docs(fleet): reconcile the attention wake too — the stamp covers the whole file
Refs #189. Round 1 on #191 (codex blocking, kimi nit). codex caught that advancing the stamp to crew@4da17c4 made the attention section false. It did, and the error is mine in kind, not only in detail: a reconciliation stamp is a claim about the WHOLE file against that tree, and I audited only the ci-red surface across a 17-commit advance. That is the #187 failure mode, on the PR that closes #189. What was false at the pinned SHA, all from the crew#66 ruling (danmt, 2026-07-27) landing in d578150e: - "One wake is registry-independent, by design: attention" — no wake is exempt now. _attention_partition splits rows against the registry; OUT rows are reported and never acted on. - "the assignment is what carries the authorization — there is nothing here for a repo list to scope" — this is the position the ruling REJECTED. The cost was argued first: a cross-repo handoff now waits on an operator adding the repo, which is why an out-of-scope demand also pings the operator over the boot-gate channel rather than only reaching duty.log. - "a fix that bounds this wake to the registry would re-create the #16 incident" — that fix landed, with the ping as its mitigation. - The parenthetical calling crew's repos-default.txt header a contradiction "raised there as a discussion" — the discussion is crew#66, it was ruled, and crew's header now names the attention wake explicitly. This file was preserving the losing side of a settled question. Also in range and owned by this section: d849f166 ledgered the wake, so "a session that dies before acking is relaunched; that is the whole crash-recovery story" no longer is. Dying relaunches; COMPLETING without acking is a decline, and the ledger stops it re-firing until the issue moves. Meaning, not mechanism, so it belongs here. Re-audited the rest of the advance rather than spot-fixing: fleet.roster still declares itself the TARGET environment (the roster paragraph holds), and the roster/install commits touch role resolution inside crew, which this file does not describe. kimi's nit, which the earlier rewrite made mine: the paper inventory counted one row while the triage-signals bullet marks a second. Both are needs-ruling rows and both are now named — a number that has to be recounted every time a wake lands is the thing that went wrong. 18/18 test files; changelog_fragment_problem OK; shellcheck, self-ref and git diff --check clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
45934b54a2
commit
4f3fc2a20b
2 changed files with 43 additions and 21 deletions
57
FLEET.md
57
FLEET.md
|
|
@ -75,9 +75,11 @@ What belongs here is what a wake *means*:
|
|||
hygiene, but not review, the one module that submits verdicts.
|
||||
[`lib/duty-review.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/lib/duty-review.sh)
|
||||
states the rule and implements the WARN.
|
||||
- **One wake is registry-independent, by design: attention** (next section).
|
||||
The registry bounds what a box goes *looking for*, not what is handed to
|
||||
this identity *by name*.
|
||||
- **No wake is exempt, including attention** (next section). The attention
|
||||
*query* is cross-repo by construction — it is one call to the
|
||||
authenticated-user endpoint, which has no repo filter — but the *action*
|
||||
it authorizes is bounded like every other. A demand parked on this box in
|
||||
a repo nobody listed is reported, never worked.
|
||||
|
||||
### Wake conditions
|
||||
|
||||
|
|
@ -92,20 +94,26 @@ very thing that unparks the work resume would otherwise pick up. The query is
|
|||
the authenticated-user endpoint —
|
||||
`gh api "/issues?filter=assigned&state=open&labels=attention"` — one call, no
|
||||
search index (the review queue below already records that the index lags) —
|
||||
and, **alone among the wakes, it reaches repos `~/duty/repos.txt` does not
|
||||
name.**
|
||||
and it **sees** repos `~/duty/repos.txt` does not name, because that endpoint
|
||||
takes no repo filter.
|
||||
|
||||
That reach is deliberate, and it survives the registry rule above as its one
|
||||
stated exception. An `attention` assignment is work handed to this identity
|
||||
by name, and **the assignment is what carries the authorization** — there is
|
||||
nothing here for a repo list to scope, because the box is not choosing where
|
||||
to look.
|
||||
**Seeing is not acting, and that is a ruling** (crew#66, danmt, 2026-07-27).
|
||||
The wake used to work every row it saw, which for a builder meant a clone and
|
||||
the full worktree and round rule set against a repo no operator had listed —
|
||||
write authority outside the registry, and the one hole left in the
|
||||
containment story. Rows are now partitioned against the registry: inside it,
|
||||
a session as before; outside it, reported and never acted on, exactly like an
|
||||
out-of-scope review request or authored PR.
|
||||
[`lib/duty-attention.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/lib/duty-attention.sh)
|
||||
queries the cross-repo endpoint on purpose and says so in its header; a fix
|
||||
that bounds this wake to the registry would re-create the #16 incident below.
|
||||
(Crew's `conf/repos-default.txt` header currently claims *every* duty module
|
||||
is registry-bounded — that contradiction is crew's, raised there as a
|
||||
discussion; this file records the exception as it is implemented today.)
|
||||
implements the partition and states the ruling in its header.
|
||||
|
||||
The cost was argued before the ruling rather than discovered after it: an
|
||||
assignment plus a label **is** a targeted authorization, so a cross-repo
|
||||
handoff now waits on an operator adding the repo, and the box most likely to
|
||||
be handed work outside its beat is the one that goes quiet. That is why an
|
||||
out-of-scope demand does not only reach `duty.log` — it pings the operator
|
||||
over the same channel the boot gate uses. A bounded wake that failed silently
|
||||
would trade an unbounded write surface for a broken channel to the human.
|
||||
|
||||
Each demand gets **exactly one session, and the ack bounds it**: the
|
||||
session's first act, before any of the demanded work, is the pickup comment
|
||||
|
|
@ -113,9 +121,13 @@ plus removing the label — [the `attention`
|
|||
contract's](https://github.com/heavy-duty/ceremony/blob/bce09aa7648dbd74b8e91b1d4fbc2fa8d145f705/LABELS.md#L143-L149)
|
||||
ack (#85), which here becomes the session's ack-then-act ordering.
|
||||
Then it acts on the thread and exits — short by construction. Until the label
|
||||
is removed the flag is still up, so a session that dies before acking is
|
||||
simply relaunched at the next tick; that is the whole crash-recovery story,
|
||||
and it is the same crash-only shape as resume below.
|
||||
is removed the flag is still up, so a session that **dies** before acking is
|
||||
simply relaunched at the next tick — the same crash-only shape as resume
|
||||
below. A session that **completes** without acking is a different fact: that
|
||||
is a decline, and a seen-ledger stops it re-firing until the issue moves.
|
||||
Dying and declining used to look identical to the engine, which meant a
|
||||
demand a session had considered and correctly left alone woke a new one every
|
||||
tick forever.
|
||||
|
||||
The design this replaces was built and rejected: polling notifications for
|
||||
`reason: mention` re-arms a thread on every comment, so ordinary round
|
||||
|
|
@ -256,9 +268,12 @@ written in this file have a record of becoming engine: the attention wake
|
|||
and the reviewers' request sweep both started here as paper (the sweep's
|
||||
org-wide form was then retired by the 2026-07-25 scope ruling), and the
|
||||
builders' ci-red wake above is the latest: written here as paper while
|
||||
crew#64 was open, engine at the stamped SHA. One is still on paper: the
|
||||
notifier's `needs-ruling` queue — at that SHA, `notify.sh`'s only label
|
||||
filter is `state:needs-human`.
|
||||
crew#64 was open, engine at the stamped SHA. Two rows are still on paper, and
|
||||
both are `needs-ruling`: the notifier's queue — at that SHA, `notify.sh`'s
|
||||
only label filter is `state:needs-human` — and triage's **past 24h**
|
||||
detection row above, which the triage-signals bullet already marks. Earlier
|
||||
counts here said "two" while silently excluding the second; naming them is
|
||||
cheaper than a number that has to be recounted every time a wake lands.
|
||||
|
||||
### Conventions on the board
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@
|
|||
implements it: a green head, or one with no checks configured, opens a
|
||||
round; a red head and an unfinished one are held and reported
|
||||
separately (#189).
|
||||
- `FLEET.md` corrects the attention wake to the crew#66 ruling: the query
|
||||
is cross-repo, the action is registry-bounded, and an out-of-scope
|
||||
demand is reported and escalated to the operator rather than worked. It
|
||||
no longer claims attention is exempt from the registry (#189).
|
||||
- `FLEET.md` distinguishes an attention session that dies before acking,
|
||||
which relaunches, from one that completes without acking, which is a
|
||||
decline a ledger keeps from re-firing (#189).
|
||||
- `BUILDER.md` re-requests by head, not by verdict: a push while
|
||||
answering a round stales every approval, so every panelist is
|
||||
re-requested; only an unchanged head re-requests the non-approvers
|
||||
|
|
|
|||
Loading…
Reference in a new issue