docs(korus): make a stale dispatched brief something the receiver checks for (BACKLOG #1448) - #880
docs(korus): make a stale dispatched brief something the receiver checks for (BACKLOG #1448)#880wshallwshall wants to merge 2 commits into
Conversation
…cks for (BACKLOG #1448) A chip is a snapshot of the tree at spawn. Once the receiver has started it there is no path to correct it: dismiss_task withdraws only a chip nobody has acted on yet. Measured 2026-09-04. A chip cut under #1443 named three drift sites; minutes later the spawner took item 3 itself and pushed c2f549f on PR 837. PR 859 avoided rewriting the same two comment blocks only because it read that diff at hunk granularity before touching anything. Two of the brief's other items also failed a read of their sources, and the three faults have three different causes. Section 5 already says the brief is disposable. That covers a brief being thrown away, not one that is wrong by the time it is read. Two bullets: the receiver verifies against the tree, and whichever seat dispatched mails what it took back. #1391 is cited rather than extended. Its brief is wrong at generation; this one goes wrong after dispatch, and neither candidate fix touches the other row. Checks: pre-commit all hooks pass, five doc lint scripts clean, 134 doc tests pass. No code changed, so ruff, mypy and simplify have nothing to read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…scoped to (BACKLOG #1448) The rule shipped saying a brief goes stale "between spawn and read". Two Manager seats answered within the hour that the dominant window is filed-to-dispatch: the brief is written stale because the ITEM it was cut from is stale, over weeks rather than minutes. One reports six of eleven briefed items already answered at spawn on 2026-09-04, each by a different mechanism. That scoping was the defect this row exists to describe. A reader told the window is spawn-to-read checks how fresh the brief is and skips -- the SDS-3.4 shape the incident's own c2f549f was fixing, a warning whose stated reason licenses the failure it prevents. Also added: line numbers are navigation aids and never evidence (four anchors adrift by 50, 86, 581 and 593 lines in one day), and finding an item already answered is a good outcome to record and stop on, not a failed turn. The row records what the title cannot: a subagent CAN be corrected mid-flight (MANAGER.md:30), a chip and a claude -p session cannot, so the fix differs by seat. Peer measurements are attributed, not verified here. BUILDER.md and MANAGER.md checked for conflict before amending sec. 5; none found, reported as a null result. Checks: pre-commit green, doc lints clean, no new dangling citations (same 16 distinct numbers). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Amended in b67edbf after two Manager seats sent measurements. The rule as first written had the defect it describes. It said a brief goes stale "between spawn and read". One Manager, who dispatched fourteen Builders that day, reports the dominant window is filed-to-dispatch instead -- six of eleven briefed items already answered at spawn, each by a different mechanism, over weeks rather than minutes. A reader told the window is spawn-to-read checks how fresh the brief is and skips. That is the SDS-3.4 shape the incident's own Widened, and three things added:
The row now records what its title cannot. "Cannot be corrected" is true of a chip and of a Peer measurements are attributed, not verified here, and marked as such in both files. Checked for conflict before amending, reported as a null result: Checks: pre-commit green, doc lints clean, no new dangling citations (same 16 distinct numbers before and after). |
What this changes
Two bullets in
CLAUDE.mdsection 5, and the BACKLOG row they cite.The rule. A dispatched brief can go stale between spawn and read, and nothing tells you. The receiver verifies the brief against the tree before acting: read the diff of every PR it names, at hunk granularity, and re-locate every line number by symbol. Where the brief and the tree disagree, the tree wins. Whichever seat dispatched mails the receiver when it takes an item back, because it cannot update the chip.
Section 5 already says "The brief is disposable. The BACKLOG item is the record." That covers a brief being thrown away. It does not cover a brief being wrong by the time it is read, and those need opposite responses: a disposable brief you may ignore, a stale one you must first detect. I checked section 5 for an equivalent before adding, per SDS-3.5 — the nearest bullets are about spawn flags, grant forms and worktrees, and none of them covers this.
The measured incident, 2026-09-04
A chip cut under #1443 named three drift sites. Item 3 was a docstring in
scripts/webconsole_seam_snapshot.py. Minutes later the author of that line handed the fix to the spawning session directly; it took it and pushedc2f549f42on PR 837. That was the right call. The chip was already dispatched anddismiss_taskwithdraws only a chip nobody has acted on, so it stayed live and wrong.PR 859 avoided the duplicate only because it read PR 837's diff at hunk granularity first. Trusting the brief would have put two PRs on the same two comment blocks, to meet at merge with the Lander resolving prose by hand.
The sharpest detail is that #1443's own body records the handover in the same change. The spawner did exactly what section 5 prescribes — it corrected the record — and the receiver was reading the other artifact, the one with no update path.
One thing I measured differently from the brief I was given
The brief reported three stale items. Two hold; the third does not, and the row says so against its own interest.
I was told the brief filed
docs/adr/0143under "adjacent, probably leave alone" while #1443's carve-out listed it as a deferred site to fix. Reading the carve-out on PR 837's branch: it does list 0143, among "Three more, all in the #1220 class and all deliberately out of this diff" — and the same sentence argues against fixing it, that "an accepted ADR records what was true when written and is better left dated than edited." Both readings have support in one sentence. The brief's compression is defensible, not stale.Recording it as a plain staleness would have made this row a stale citation of exactly the kind it exists to describe. The row still supports the rule: the receiver's recovery is identical in all three cases — read the source, not the brief's one-line summary of it.
The other two hold. Item 3 is confirmed stale (
c2f549f42, two hunks). Item 1 is confirmed wrong when written, not stale:messagefoundry_webconsole/__init__.py:29is a fragment ending on the word "the", and deleting it alone puts the pre-#279 range framing on:27-28against its contradiction on:30-31. Three different faults, three different causes.Why not an amendment to #1391
I checked this before allocating, as asked. #1391 is the same family and is cited rather than extended. Its brief is wrong at generation —
respawn.ps1emits a relative command rooted at the predecessor's checkout. This one was correct at spawn and the tree moved underneath it. Neither candidate fix touches the other row, and #1391's own body warns that "a fix aimed at the wrong half will look like it worked on the seats that were never affected."Citations not yet on main
#1443 and #1445 are allocated and open in PRs 837 and 859; neither is on
mainyet.dangling_citation_check.pyreports both unresolved until they land — advisory, exit 0. Cited anyway and said so in the row, per section 5's rule for an allocated-but-unlanded number. #1439 is on main.Severity
Fleet-process defect. No engine, PHI or deployment axis (section 0) — nothing here reaches a running instance, because there are none. Written in the conditional throughout. What it would cost is duplicated Builder turns and a prose merge conflict resolved by hand.
Checks
pre-commit(all hooks)backlog_status_check.pylink_check.pybacklog_citation_check.pyclaude_section_check.pydangling_citation_check.py🔢banner; the grep proves the instrument sees non-ASCIINot run, and why:
ruff,ruff format,mypyand/simplifyhave no input — this change touches no.py. The fullpytestsuite was not run; nothing here is importable.Legs only a hosted runner reads:
windows-service-smokeand the required-context set. Please read those after merge.Note on the ranking table
New items get no row in section-top ranking table — that table holds the 2026-09-03 scoring pass, and #1435/#1439 carry no row either. #1448 is filed unscored and says so.
🤖 Generated with Claude Code