docs(adr): ADR-018 D6.1/D6.2 — a broadcast NO_REPLY must release the claim - #952
Open
lilyshen0722 wants to merge 1 commit into
Open
docs(adr): ADR-018 D6.1/D6.2 — a broadcast NO_REPLY must release the claim#952lilyshen0722 wants to merge 1 commit into
lilyshen0722 wants to merge 1 commit into
Conversation
…claim
D6 ("a claim is the right to decide, not a duty to reply") is right for a
TARGETED wake and wrong for a broadcast, because on a broadcast the claim was
won by a race rather than by relevance.
Observed 2026-08-14 in Sharpen, not hypothetical: a review request went to
four seats, sprint-impl won the claim, pod-architect / sprint-review / ux-lead
all logged "already claimed — standing down", and sprint-impl returned
NO_REPLY. The implementer won a race for a REVIEW request, declined, and the
three seats that could have answered had already excluded themselves. The
request vanished with no signal to anyone — from outside, indistinguishable
from "still thinking."
D6.1: on `message.posted`, a NO_REPLY verdict RELEASES the claim for a bounded
second pass instead of consuming the message. `chat.mention` keeps D6
unchanged — there the claimer IS the addressee and its silence is the answer.
Records the asymmetry that already exists and is correct: a direct mention
overrides a peer's claim ("proceeding peer-aware — this seat was directly
addressed"), so targeting is respected and only broadcast gambles.
D6.2: serial event processing is an INVARIANT, not an implementation detail.
The wrapper polls up to 10 events and runs them strictly serially. A turn
builds context at spawn so it cannot see mid-turn arrivals — but the NEXT turn
sees the newer messages plus its own previous reply, which is what lets it
recognise the ground is covered and decline. Processing events concurrently
would break that silently: parallel turns would each answer an overlapping
question unaware of the others, and no prompting fixes it. It looks like an
obvious throughput win, which is why it is now a decision rather than a
property of the current code.
Review note added: the fleet reviewed D6 by hitting it. The claim mechanics
worked exactly as specified; the gap was stating D6 without distinguishing
broadcast from targeted. Correct and incomplete — only live traffic showed
which half was missing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Answers Sam's question about claim/queue behaviour, and closes a hole the fleet demonstrated on itself today.
D6.1 — a broadcast
NO_REPLYmust release the claimD6 says "a claim is the right to decide, not a duty to reply." That's right for a targeted wake — the claimer is the addressee, and its silence is the answer. It's wrong for a broadcast, because there the claim was won by a race, not by relevance.
Observed today, not hypothetical. A review request posted to four seats in Sharpen:
The implementer won a race for a review request, declined, and the three seats that could have answered had already excluded themselves. The request vanished with no signal to anyone — from outside, indistinguishable from "still thinking."
Nobody evaluates whether a message is for them until after the exclusive claim is taken. So D6's "right to decide" quietly becomes "the first mover decides on everyone's behalf."
The fix: on
message.posted, aNO_REPLYverdict releases the claim for a bounded second pass instead of consuming the message.chat.mentionkeeps D6 unchanged.The asymmetry that already exists is correct and worth recording — a direct mention overrides a peer's claim ("proceeding peer-aware — this seat was directly addressed"). Targeting is respected; only broadcast gambles. This makes the gamble recoverable.
D6.2 — serial event processing is an invariant
The wrapper polls up to 10 events and runs them strictly serially (
cli/src/lib/poller.js,for … await). Each message with amessageIdis its own claimable event, so a burst of three messages is three claims and three sequential turns.That ordering is what makes bursts survivable. A turn builds context at spawn and cannot see mid-turn arrivals — but the next turn rebuilds context and sees the newer messages plus its own previous reply, which is exactly what lets it recognise the ground is covered and decline.
Processing events concurrently would break this silently: parallel turns would each answer an overlapping question unaware of the others, and no prompting fixes it. It looks like an obvious throughput win, which is precisely why it's now a decision rather than a property of the current code.
Review note
The fleet reviewed D6 by hitting it. The claim mechanics worked exactly as specified — the gap was stating D6 without distinguishing broadcast from targeted. Correct and incomplete, and only live traffic showed which half was missing.
Same failure family as the at-cap decline returning
status: 'succeeded'(found in the ADR-022 review): a message disappears while every component reports success.🤖 Generated with Claude Code
https://claude.ai/code/session_01XeUH4HVDsDHYPsHJthXjB8