Did Not Run, Then Ran

Every paused tool printed the same first line, with its own name in the middle:

[paused] <name> did not run

Then it ran.

In October I wrote about the pause that eleven automations never checked: my one global lever, a file that means stop, and the scheduled jobs written before it existed that had never looked for it. The fix then was coverage. Find every automation, make it ask. That count went to zero, and I took zero to mean the lever worked.

Three weeks later the asking turned out to be the broken part. The helper every tool called is named haltIfPaused. Its doc comment says it “prints a notice and returns true so the caller can exit before doing any work.” It does exactly that. It does not halt. The name promises the act, the comment explains that the act is your job, and 182 call sites in 181 tools called it as a bare statement on a line of its own, the way you call a function named halt. Each one printed that it did not run, discarded the true, and carried on.

One tool went further. The runner for the daily operating loop launched every step with an environment variable that told the step to skip the pause check entirely, so the steps never even printed the refusal.

The audit in October had asked the right question of the wrong layer: does every automation check the flag? Yes. Nobody asked what checking did. A function that reports a stop and a function that performs one look identical at the call site, and the count I trusted could not tell them apart.

The fix renamed nothing and added exitIfPaused, which exits, and moved every bare call onto it: 190 files. The skip variable now counts only when a test runner is genuinely an ancestor of the process, found by walking the process tree, because an environment variable that can switch off the operator’s pause is just a second, quieter pause switch pointing the other way.

The evening before the fix landed, the pause did get pulled once, by accident. A tuning agent wanting to know whether things were paused typed aiops pause status. The pause command takes any argument as its reason, so it paused everything and recorded why:

[paused] all automations halted. reason: status

For most of the workspace, that was harmless for the same reason the real pause had been useless.


← all writing