Filed by the domain:services PM seat (#6021) from two measured instances in the same hour, on two independent dev seats running unrelated cards. Both were recovered by hand; neither would have recovered on its own.
The two instances, verbatim
Both seats ended their turn with work outstanding and a stated intention to be woken:
| card |
the seat's own last words |
| #16896 |
"I'll stop here and wait for the Monitor's completion notification before continuing with the remaining verification and PR steps." |
| #16679 |
"I've started the full verification suite (dogfood package tests + all 59 derived gate commands) as background jobs, along with a completion watcher. I'll resume analysis and proceed to open the PR once these finish and report back." |
Neither notification exists. A background job or watcher a subagent spawns does not deliver that subagent a new turn. The run parks, indefinitely, holding a dispatch slot and a claim.
Both were recovered only because the PM noticed the completion event and sent an explicit "poll the state yourself" message. #16896 then finished normally (PR #17038); #16679 was recovered the same way.
Why the seats were not being careless
⛔ Worth stating plainly, because the fix is not "tell devs to be more careful": both behaved reasonably given what they were told. They had just been instructed to run long, expensive verification (full gate unions, dogfood boots, whole-workspace builds) and to avoid re-running what they had already measured. Backgrounding that work and waiting for it is the correct shape in an environment where completion wakes you. It does not here, and nothing in their contract says so.
.claude/agents/os-dev.md describes the deliverable, the discipline and the prohibitions in detail. It does not contain the sentence "you will not be woken."
The cost
Each stall held a dispatch slot at a concurrency the maintainer has fixed at 3, so a stall is a 33% throughput loss for as long as it lasts — and it lasts until a human or the PM happens to look. Both of today's ran for tens of minutes. The failure is also silent in the worst way: from outside, a stalled seat and a working seat are indistinguishable until the completion event arrives carrying an intention instead of a result.
Why this is not already covered
The domain:services seat ledger has carried a standing correction on exactly this since an earlier incident — "a dev seat can die silently on a notification that never arrives; a continuation order must tell it to go measure the state it is waiting for." ⇒ That correction lives in the PM's seat post, where the dev never reads it. It is applied only when the PM remembers to write it into a dispatch — and today's two dispatches did not, which is how both instances happened. A rule that only works when a human remembers it is not a rule; it belongs in the contract the dev actually loads.
Directions (not a ruling)
- One sentence in
.claude/agents/os-dev.md: you will not be woken by anything you start; never end a turn waiting on a background job, a watcher, or a notification; poll the state yourself and, if you cannot determine it, name it NOT MEASURED and continue. Cheapest, targets the reader, and removes the PM's dependence on memory.
- Give the pattern a supported shape. Long verification really does need backgrounding. Say what the supported idiom is — write an exit-status file and poll it, bounded, inside one turn — so the rule reads as "do it this way", not "don't do the natural thing".
- Consider whether the PM dispatch template should carry the same line as a belt-and-braces, given (1) is the load-bearing fix.
(1) is the one that closes it. ⛔ The PM seat cannot write any of these itself: .claude/** is a governed surface.
Not claimed
⚠️ Whether other lanes' dev seats have stalled the same way. This seat has two instances, both its own, both today. ⛔ A sweep of other lanes' dispatched cards for seats that went quiet with a claim and no PR would answer it — and a zero from that sweep needs a positive control that re-finds these two, or it is NOT MEASURED.
Related: #17032 (a rule inferred from a check's name because no document stated it) — same family: the reader's available artefacts do not contain the rule they need.
Filed by the
domain:servicesPM seat (#6021) from two measured instances in the same hour, on two independent dev seats running unrelated cards. Both were recovered by hand; neither would have recovered on its own.The two instances, verbatim
Both seats ended their turn with work outstanding and a stated intention to be woken:
Neither notification exists. A background job or watcher a subagent spawns does not deliver that subagent a new turn. The run parks, indefinitely, holding a dispatch slot and a claim.
Both were recovered only because the PM noticed the completion event and sent an explicit "poll the state yourself" message. #16896 then finished normally (PR #17038); #16679 was recovered the same way.
Why the seats were not being careless
⛔ Worth stating plainly, because the fix is not "tell devs to be more careful": both behaved reasonably given what they were told. They had just been instructed to run long, expensive verification (full gate unions, dogfood boots, whole-workspace builds) and to avoid re-running what they had already measured. Backgrounding that work and waiting for it is the correct shape in an environment where completion wakes you. It does not here, and nothing in their contract says so.
.claude/agents/os-dev.mddescribes the deliverable, the discipline and the prohibitions in detail. It does not contain the sentence "you will not be woken."The cost
Each stall held a dispatch slot at a concurrency the maintainer has fixed at 3, so a stall is a 33% throughput loss for as long as it lasts — and it lasts until a human or the PM happens to look. Both of today's ran for tens of minutes. The failure is also silent in the worst way: from outside, a stalled seat and a working seat are indistinguishable until the completion event arrives carrying an intention instead of a result.
Why this is not already covered
The
domain:servicesseat ledger has carried a standing correction on exactly this since an earlier incident — "a dev seat can die silently on a notification that never arrives; a continuation order must tell it to go measure the state it is waiting for." ⇒ That correction lives in the PM's seat post, where the dev never reads it. It is applied only when the PM remembers to write it into a dispatch — and today's two dispatches did not, which is how both instances happened. A rule that only works when a human remembers it is not a rule; it belongs in the contract the dev actually loads.Directions (not a ruling)
.claude/agents/os-dev.md: you will not be woken by anything you start; never end a turn waiting on a background job, a watcher, or a notification; poll the state yourself and, if you cannot determine it, name it NOT MEASURED and continue. Cheapest, targets the reader, and removes the PM's dependence on memory.(1) is the one that closes it. ⛔ The PM seat cannot write any of these itself:
.claude/**is a governed surface.Not claimed
Related: #17032 (a rule inferred from a check's name because no document stated it) — same family: the reader's available artefacts do not contain the rule they need.