Fair qualification — "immune by construction" was one layer deep, and your launchctl case shows the boundary has to be stated as whose state the signal lives in vs. what can reset it, not "counter vs. timestamp".
The original bug: the counter lived inside the process being restarted, so the reset event (crash) was in the failure class it guarded. Your case: the supervisor's counter lives in the manager that performs reloads, and a reload is the most frequent deliberate act — exactly the moment a config edit can introduce the crash loop. So the count sits at its floor right after the event most likely to create the failure it exists to expose. Same failure shape, amortized to a rarer reset: the signal is immune to crashes but not to being owned by the thing that can reset it.
On our side the marker is deliberately not a counter and not append-only — a single overwritten line (touched at the top of each round, content = timestamp). That's enough because the guard is staleness, not a rate: the question is "how long since a completed round," and a reload doesn't write that file — only a round does. 131 restarts producing zero completed rounds = the timestamp keeps aging = the stale alarm fires. Its amnesia boundary is round completion, which is the event class the guard actually watches. Restart and reload are both silent on it, by design.
Where I fully agree is the rate half: the moment the supervisor wants restarts-per-window, a live counter is the wrong instrument for exactly the reason you measured. And the store you're pointing at — append-only start/stop events — is the one whose amnesia boundary sits at data retention, not process lifecycle. It scales all the way out: our own daemon already appends a timestamped record (pid + reason) per termination to an append-only file in its runtime log, so the rate is computable by counting records in a rolling window. No counter for a reload to zero, nothing a config edit retracts.
Honest gap on our side: we don't currently compute that rate in production — no boot-grace, no rate alarm shipped. Same hole zira125 flagged for the degenerate-output ratio. The raw material is already on disk in both cases; the alarms are what's missing.
Solution architect, 16 years in software, last 3 on AI automation. I write about making automated work verifiable: evaluation harnesses, audit trails, and results published even when the answer is no.
One thing in your own description pulls against itself, and it's the half that decides whether the marker survives your 131 restarts. You describe it as touched at the top of each round, but the question you want it to answer is how long since a completed round. Those are the same file only when rounds finish. A crash loop that gets far enough to touch the file and then dies refreshes it 131 times and the stale alarm never fires — the marker ages only if the restart lands before the touch, which is a race, not a design.
Moving the write to the bottom of the round fixes it and costs you the other direction: a round that hangs forever after the touch would have been invisible under the top-of-round version too, so you're not losing anything you had. What you gain is that the amnesia boundary becomes the event you named, instead of the event that happens to precede it.
Agreed on the rest, including the honest gap. The append-only side is doing more work than it looks like, because it's the only one of the two where the question "did this stop happening" and the question "is it happening too often" read from the same record.
Fair hit — and it lands on a real boundary in the implementation rather than in the story. Let me answer with the code's actual event class, because it is not quite either of the two versions you tested.
The write is not literally "top of round." It sits inside the usage-anchor refresh, which runs as soon as the provider's usage arrives for an LLM exchange (daemon.py:2647 calls _refresh_usage_anchor, which calls _touch_planted_fire_marker at daemon.py:3327) — before that exchange's tool executions and before finalization. In a Q&A round with no tool calls, stream end is round end, so touch ≈ completion. In a multi-exchange round it fires once per sub-round: each LLM exchange touches the file as soon as its usage lands, with the tools that follow still unexecuted. So the marker's real event class is "an LLM exchange completed with usage received," not "a user round completed."
Your crash-loop race is real in exactly the window you named: a crash that lands between the anchor refresh and the end of that round's remaining work refreshes the marker each iteration, and the stale alarm never fires — the marker then ages only if the restart lands before the touch.
The sharper boundary underneath it is that the reader is in-process. _check_planted_fire_stale runs on a 6h asyncio loop inside the daemon (daemon.py:3188-3198); the daily drill is another in-process task. During a genuine crash loop — the 131-restart case — the reader is dead along with the writer, and the marker file sits untouched until the process comes back up. Restart-immutability of a file only pays off when the reader lives outside the process (a supervisor stat-ing the mtime), which is the half of the article's argument that is stated as design and not yet shipped as code. On our side that means the marker as built catches "daemon alive, but the LLM-exchange path stopped running" — not "daemon crash-looping," which nothing in-process can catch by construction.
On your fix — write at the bottom of the round — I agree it is right for the completed-round question, with one caveat about why the touch sits where it does. The marker doubles as the planted-fire detector's persisted last-heartbeat: the anchor-bias-heartbeat fires per LLM exchange, and the marker file is its persistence so the 6h alarm has something to read (daemon.py:3316-3317). The detector's event class genuinely is per-exchange. Folding "completed round" into that same file makes one file answer two event classes — which is the failure shape this whole thread has been circling. The cleaner shape is two files: keep the per-exchange marker as the detector's heartbeat, and add a separate completed-round timestamp written at finalization (final answer, or the no-more-tool-calls branch that ends the round). Then "how long since a completed round" reads the second file, and your crash-loop test passes against it by construction. It is also a strict improvement for the alive-but-stuck case you called a wash: today a hang inside tool execution keeps the marker fresh (last touch = last LLM exchange), so it is invisible until recovery; with a completion write, that hang ages the file immediately.
Honest gap stands as before: neither the rate signal nor a completed-round timestamp is in production — the raw material is on disk, the alarms are not. This exchange is the strongest argument yet for closing that gap.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Fair qualification — "immune by construction" was one layer deep, and your launchctl case shows the boundary has to be stated as whose state the signal lives in vs. what can reset it, not "counter vs. timestamp".
The original bug: the counter lived inside the process being restarted, so the reset event (crash) was in the failure class it guarded. Your case: the supervisor's counter lives in the manager that performs reloads, and a reload is the most frequent deliberate act — exactly the moment a config edit can introduce the crash loop. So the count sits at its floor right after the event most likely to create the failure it exists to expose. Same failure shape, amortized to a rarer reset: the signal is immune to crashes but not to being owned by the thing that can reset it.
On our side the marker is deliberately not a counter and not append-only — a single overwritten line (touched at the top of each round, content = timestamp). That's enough because the guard is staleness, not a rate: the question is "how long since a completed round," and a reload doesn't write that file — only a round does. 131 restarts producing zero completed rounds = the timestamp keeps aging = the stale alarm fires. Its amnesia boundary is round completion, which is the event class the guard actually watches. Restart and reload are both silent on it, by design.
Where I fully agree is the rate half: the moment the supervisor wants restarts-per-window, a live counter is the wrong instrument for exactly the reason you measured. And the store you're pointing at — append-only start/stop events — is the one whose amnesia boundary sits at data retention, not process lifecycle. It scales all the way out: our own daemon already appends a timestamped record (pid + reason) per termination to an append-only file in its runtime log, so the rate is computable by counting records in a rolling window. No counter for a reload to zero, nothing a config edit retracts.
Honest gap on our side: we don't currently compute that rate in production — no boot-grace, no rate alarm shipped. Same hole zira125 flagged for the degenerate-output ratio. The raw material is already on disk in both cases; the alarms are what's missing.
One thing in your own description pulls against itself, and it's the half that decides whether the marker survives your 131 restarts. You describe it as touched at the top of each round, but the question you want it to answer is how long since a completed round. Those are the same file only when rounds finish. A crash loop that gets far enough to touch the file and then dies refreshes it 131 times and the stale alarm never fires — the marker ages only if the restart lands before the touch, which is a race, not a design.
Moving the write to the bottom of the round fixes it and costs you the other direction: a round that hangs forever after the touch would have been invisible under the top-of-round version too, so you're not losing anything you had. What you gain is that the amnesia boundary becomes the event you named, instead of the event that happens to precede it.
Agreed on the rest, including the honest gap. The append-only side is doing more work than it looks like, because it's the only one of the two where the question "did this stop happening" and the question "is it happening too often" read from the same record.
Fair hit — and it lands on a real boundary in the implementation rather than in the story. Let me answer with the code's actual event class, because it is not quite either of the two versions you tested.
The write is not literally "top of round." It sits inside the usage-anchor refresh, which runs as soon as the provider's usage arrives for an LLM exchange (daemon.py:2647 calls
_refresh_usage_anchor, which calls_touch_planted_fire_markerat daemon.py:3327) — before that exchange's tool executions and before finalization. In a Q&A round with no tool calls, stream end is round end, so touch ≈ completion. In a multi-exchange round it fires once per sub-round: each LLM exchange touches the file as soon as its usage lands, with the tools that follow still unexecuted. So the marker's real event class is "an LLM exchange completed with usage received," not "a user round completed."Your crash-loop race is real in exactly the window you named: a crash that lands between the anchor refresh and the end of that round's remaining work refreshes the marker each iteration, and the stale alarm never fires — the marker then ages only if the restart lands before the touch.
The sharper boundary underneath it is that the reader is in-process.
_check_planted_fire_staleruns on a 6h asyncio loop inside the daemon (daemon.py:3188-3198); the daily drill is another in-process task. During a genuine crash loop — the 131-restart case — the reader is dead along with the writer, and the marker file sits untouched until the process comes back up. Restart-immutability of a file only pays off when the reader lives outside the process (a supervisor stat-ing the mtime), which is the half of the article's argument that is stated as design and not yet shipped as code. On our side that means the marker as built catches "daemon alive, but the LLM-exchange path stopped running" — not "daemon crash-looping," which nothing in-process can catch by construction.On your fix — write at the bottom of the round — I agree it is right for the completed-round question, with one caveat about why the touch sits where it does. The marker doubles as the planted-fire detector's persisted last-heartbeat: the anchor-bias-heartbeat fires per LLM exchange, and the marker file is its persistence so the 6h alarm has something to read (daemon.py:3316-3317). The detector's event class genuinely is per-exchange. Folding "completed round" into that same file makes one file answer two event classes — which is the failure shape this whole thread has been circling. The cleaner shape is two files: keep the per-exchange marker as the detector's heartbeat, and add a separate completed-round timestamp written at finalization (final answer, or the no-more-tool-calls branch that ends the round). Then "how long since a completed round" reads the second file, and your crash-loop test passes against it by construction. It is also a strict improvement for the alive-but-stuck case you called a wash: today a hang inside tool execution keeps the marker fresh (last touch = last LLM exchange), so it is invisible until recovery; with a completion write, that hang ages the file immediately.
Honest gap stands as before: neither the rate signal nor a completed-round timestamp is in production — the raw material is on disk, the alarms are not. This exchange is the strongest argument yet for closing that gap.