Skip to content

docs(os-dev): a turn ends only at a report — add the missing narrow-and-declare exit - #9858

Merged
os-warren merged 1 commit into
mainfrom
claude/issue-9687-never-end-turn-waiting
Aug 19, 2026
Merged

docs(os-dev): a turn ends only at a report — add the missing narrow-and-declare exit#9858
os-warren merged 1 commit into
mainfrom
claude/issue-9687-never-end-turn-waiting

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#9687

What this changes

One dev-side clause in .claude/agents/os-dev.md: a turn never ends in a waiting or
monitoring posture. Rewrites clean-close item 4 into the canonical turn-end contract —
a turn ends only when a report is delivered, and a report is either the terminal report
(draft PR + report comment + final JSON, with in_progress written honestly when gates
have not converged) or a blocked report naming the one thing only the PM can resolve.
A queued lock, a running test, an unconverged CI is not a third terminal state.

The finding that shaped the implementation

The card's premise as filed — "Nothing in os-dev.md tells an agent not to background a
long check and yield"
— does not survive verification against origin/main. Three
prohibitions already say exactly that, and git blame dates all three to 2026-08-16,
which is before all four measured stalls:

sitetext
resource rule 6never hang verification on a background watcher and then end the turn
resource rule 7never end a turn to "wait for the lock"
clean-close item 4the only wait that may end a turn is one your report judges blocked and names

So four agents stalled with the prohibition already in the file three times over. A
fourth restatement would not have prevented any of them, and the card's own body records
what the two stalled agents failed to reach — a third dev "abandoning its full-package
suite for the same reason and narrowing scope instead", called there "the correct
response".

A scan for that exit (narrow / declare) returns zero hits in the file. Rule 7's
ladder ran timed-acquire, lock-free work, re-acquire, blocked. For a merely queued lint
job blocked reads wrong (nothing there needs the PM), and waiting has no end, so the
agents invented the unavailable fourth option: background it and yield.

The missing rung, not the missing prohibition, is what this PR adds: when a check is
queued or over budget, narrow its scope and declare the narrowing in the report — an
accepted deviation, because CI runs the full farm regardless and the PM reviews against
CI convergence rather than local coverage. An undeclared narrowing stays what it always
was: a skipped check.

One home, no duplication

The posture rule is consolidated into clean-close item 4 and deduped out of the places
that restated it:

  • resource rule 6 keeps foreground execution and now points at clean-close for the
    prohibition and the two legal terminal states (net minus 1 line).
  • resource rule 7's ladder routes through the narrowing exit before blocked, by name
    rather than by rule number, so the sibling lock-mechanization card can rewrite that
    region without stranding the pointer.
  • The clause states the posture rule and points at the lock discipline for etiquette
    rather than hard-coding today's flock details, per the dispatch note.

Evidence is carried as a self-contained one-line lesson (four same-shape stalls, two
seats, one day) with no issue numbers, per the id-lint standard.

Gates — union re-run after the final commit, at 660e0b84b

node scripts/pm/dispatch-gates.mjs (no paths; derived from the merge base itself)
placed 8 families for this surface. All 8 run green:

  • check-skill-line-ratchet: .claude/agents/os-dev.md is 358 lines (ceiling 399; headroom 41) — 352 to 358, +6 within budget, no ceiling change
  • check-skill-id-lint: 9 file(s) clean (pattern /#[0-9]{3,}/g)
  • check-agent-model-declared: 1 agent definition(s) ... all declare a model, os-dev.md → opus
  • check-nul-bytes: OK (scanned 6281 text file(s) ... no raw ASCII control bytes), plus a direct control-byte self-scan of the edited file (no hits)
  • check-doc-authoring: 377 files clean — no bare metadata literals
  • check-pm-governed-merges: 77 assertions
  • check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
  • check:doc-formula-expressions: 22 record-scoped formula example(s) across 396 files / 1413 TS blocks judged clean

Governed surface (.claude/**) — opens draft and stays draft for a human merge.
No changeset: .claude/-only, publishes nothing (skip-changeset).

Generated by Claude Code


Generated by Claude Code

…re exit
Four same-shape stalls in one day across two seats: a contended or long check,
the agent backgrounds the wait and yields believing a monitor will wake it. In
this harness a stopped subagent with no live children is DONE.
The prohibition already existed three times (resource rules 6/7, clean-close#4) and predated all four stalls, so a fourth copy would not have prevented
them. What was missing is the third rung: when a check is queued or over
budget, narrow its scope and DECLARE the narrowing in the report — an accepted
deviation, since CI runs the full farm regardless. Without it the ladder ran
wait-forever or `blocked`, and agents invented background-and-yield instead.
Consolidates the posture rule into one home (clean-close#4) as the two-report
turn-end contract, dedups the mechanism out of resource rule 6, and routes
rule 7's queue ladder through the narrowing exit before `blocked`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] os-dev stalls by backgrounding a contended verify job and yielding — measured twice in one session, and concurrency makes it likelier

2 participants

@os-warren@claude