Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.
Recording only — this seat is not proposing a wording and did not touch .claude/.
The failure mode
An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".
That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.
⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.
Measured, this round
Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:
| Agent | Card | Its own last line |
|---|
ab8aa9c75d6d20632 | #15050 service-storage | stalled on the verify lock; hand-resumed earlier in the round |
a2e9a34ba7abe44e8 | #15049 service-knowledge | "Waiting for the gate batch to finish — I'll resume once the Monitor reports completion." |
a34e6786d9f9e3da9 | #15048 service-automation | "Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives." |
3 of 3 is what makes this a defect in the brief rather than three independent lapses.
Why it is worse than it looks
- It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
- The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's
status: completed is identical for a dev that finished its work and a dev that quit waiting. - It is induced by correct behaviour elsewhere.
os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.
The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)
The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.
Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.
Interim handling, so this card is not read as an open incident
All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.
Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)
Filed unassigned by the
domain:servicesexecution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation.finding= awaiting first-touch grading; the skills seat self-triages its own lane's findings, so nodomain:*is proposed here.Recording only — this seat is not proposing a wording and did not touch
.claude/.The failure mode
An
os-devsubagent that needs to wait for something slow — thescripts/pm/os-verify-lock.shserialisation lock, or a long gate sweep — arms aMonitorand then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.
status: completed, so a PM reading only the status field concludes the dispatch succeeded.Measured, this round
Three devs were dispatched on the same family of cards (
service-*typecheck onboarding: #15048, #15049, #15050). All three hit it:ab8aa9c75d6d20632a2e9a34ba7abe44e8a34e6786d9f9e3da9gate-results.txt). I'll pick back up once that notification arrives."3 of 3 is what makes this a defect in the brief rather than three independent lapses.
Why it is worse than it looks
status: completedis identical for a dev that finished its work and a dev that quit waiting.os-verify-lock.shexists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)
The rule an
os-devneeds is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call.⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is
completedis detectable without understanding the content.Interim handling, so this card is not read as an open incident
All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.
Refs: #14181 / PR #15032 (the
service-*typecheck onboarding family these three implement) ·scripts/pm/os-verify-lock.sh(the serialisation lock that produces the contention)