FLEET.md — the assignee's attention wake #86

Closed
opened 2026-07-23 17:21:54 +00:00 by dan-claude-bot · 2 comments
dan-claude-bot commented 2026-07-23 17:21:54 +00:00 (Migrated from github.com)

Part of #83. Blocked by #85 (it cites that contract's ack rules by name). From discussion #82, approved by @danmt.

All line references pinned at 87f2432.

Context

#84 makes the label exist; #85 makes it mean something. Neither wakes anybody. FLEET.md is where this fleet's wake conditions are specified — descriptive, not doctrine, never mirrored to consumers, and the file's own header says so. It is also the established place for a box-side spec the operator later implements: the needs-ruling notifier (#74, L67-L108) landed exactly this way.

Today's wake list L45-L65 is per-role and entirely state-driven. attention is the first wake that is role-independent: anyone can be an assignee, so every loop needs it.

Spec

Decisions. Do not reopen them in the PR.

  • D1 — one wake, shared by all three roles, written once above the per-role lists rather than pasted into each: an open issue assigned to me carrying attention. Triage, builders and reviewers all get it; the pickup session is the same shape in each.
  • D2 — the query is the authenticated-user endpoint: gh api "/issues?filter=assigned&state=open&labels=attention". One call, no search index (the reviewer trigger already documents that the search index lags — L59-L65). Record the property that follows: like the review-request trigger, it reaches repos ~/duty/repos.txt does not name.
  • D3 — priority: first, ahead of resume. A demand parked by triage, the operator or a sibling agent outranks self-directed continuation, and it is frequently the thing that unparks the work resume would otherwise pick up. The session is short by construction — ack, then act on the thread.
  • D4 — exactly one session per demand, and the ack bounds it. The session's first act is the pickup comment plus removing the label (#85's contract, referenced not restated). Until it 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 matches the crash-only resume already documented.
  • D5 — record the rejected design, because it was built. Polling notifications for reason: mention re-arms a thread on every comment, so ordinary round traffic (verdicts naming the builder, the builder's own replies echoing back) burns a full agent session per tick on nothing actionable. A mention answers "was I named?", not "am I needed?". Two sentences, so nobody rebuilds it.
  • D6 — the incident is the evidence, as with the notifier section: #16's 16:49Z ruling authorized the last open acceptance criterion on a claimed issue and sat unowned for over an hour; the box answered every state signal that day and never saw the comment; the eventual pickup ran on a manual bridge.
  • D7 — the status caveat, in the file's own idiom: this is the spec for a box-side change only the operator can make (L110-L113); until duty.sh polls it, the wake exists on paper. One consumer already polls for the label and no-ops while it is absent, so the wiring can be verified live the day the row lands.
  • D8 — the notifier is not in scope. notify.sh watches what the operator owes. attention is what an assignee owes, and the assignee is an agent whose loop reads it directly. No second queue in the operator's messages.

Tasks

  • FLEET.md — the shared wake (D1–D4) in Wake conditions, above the per-role bullets.
  • FLEET.md — the rejected mention-poll and the incident (D5, D6), in the same paragraph or a short one after it; keep it to the file's evidence-then-spec shape, not a new #### section.
  • FLEET.md — the on-paper caveat (D7).
  • CHANGELOG.md — one line under ## Unreleased, inserted above the heading below it.

Acceptance criteria

  • The wake is stated once, applies to all three roles, and names the exact query of D2.
  • Its priority relative to the existing per-role triggers is unambiguous — a reader implementing duty.sh knows where it goes in the ordering without asking.
  • The one-session-per-demand rule and the ack-then-act ordering are both stated, with the die-before-ack case resolved explicitly.
  • The rejected mention-poll is recorded with the reason it was rejected.
  • The #16 incident is cited as the evidence, matching how the notifier section cites its three.
  • The on-paper caveat is present, so the file does not claim wiring that no box has yet.
  • The diff touches FLEET.md and CHANGELOG.md and nothing else. FLEET.md is not in docs/VENDORED.txt — nothing here may restate doctrine that belongs in LABELS.md, and no doctrine file is edited by this PR.

Test plan

  • test/run.sh green and the lint scripts clean — no executable behavior here.
  • docs-sync --check unaffected, and that is itself an assertion worth making in the PR body: if it goes red, the diff touched a vendored file it should not have.
  • The read-through case that must fail: an operator who, reading only this section, cannot tell whether the pickup session removes the label before or after doing the work. Before. If the prose leaves that ambiguous, it is wrong.
  • Every permalink pinned to a SHA, never main.

Dependencies

Blocked by #85. Part of #83.

Part of #83. Blocked by #85 (it cites that contract's ack rules by name). From discussion [#82](https://github.com/heavy-duty/ceremony/discussions/82), approved by @danmt. All line references pinned at [`87f2432`](https://github.com/heavy-duty/ceremony/tree/87f243299d17b1a3831c3345fa11fa638eb21b1d). ## Context #84 makes the label exist; #85 makes it mean something. Neither wakes anybody. [FLEET.md](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md) is where this fleet's wake conditions are specified — descriptive, not doctrine, never mirrored to consumers, and the file's own header says so. It is also the established place for a box-side spec the operator later implements: the `needs-ruling` notifier ([#74](https://github.com/heavy-duty/ceremony/issues/74), [L67-L108](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md#L67-L108)) landed exactly this way. Today's [wake list L45-L65](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md#L45-L65) is per-role and entirely state-driven. `attention` is the first wake that is **role-independent**: anyone can be an assignee, so every loop needs it. ## Spec Decisions. Do not reopen them in the PR. - **D1 — one wake, shared by all three roles**, written once above the per-role lists rather than pasted into each: *an open issue assigned to me carrying `attention`.* Triage, builders and reviewers all get it; the pickup session is the same shape in each. - **D2 — the query is the authenticated-user endpoint:** `gh api "/issues?filter=assigned&state=open&labels=attention"`. One call, no search index (the reviewer trigger already documents that the search index lags — [L59-L65](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md#L59-L65)). Record the property that follows: like the review-request trigger, it reaches repos `~/duty/repos.txt` does not name. - **D3 — priority: first, ahead of resume.** A demand parked by triage, the operator or a sibling agent outranks self-directed continuation, and it is frequently the thing that unparks the work resume would otherwise pick up. The session is short by construction — ack, then act on the thread. - **D4 — exactly one session per demand, and the ack bounds it.** The session's first act is the pickup comment plus removing the label ([#85](https://github.com/heavy-duty/ceremony/issues/85)'s contract, referenced not restated). Until it 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 matches the [crash-only resume](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md#L118-L124) already documented. - **D5 — record the rejected design, because it was built.** Polling notifications for `reason: mention` re-arms a thread on every comment, so ordinary round traffic (verdicts naming the builder, the builder's own replies echoing back) burns a full agent session per tick on nothing actionable. A mention answers *"was I named?"*, not *"am I needed?"*. Two sentences, so nobody rebuilds it. - **D6 — the incident is the evidence,** as with the notifier section: [#16's 16:49Z ruling](https://github.com/heavy-duty/ceremony/issues/16#issuecomment-5061051198) authorized the last open acceptance criterion on a `claimed` issue and sat unowned for over an hour; the box answered every state signal that day and never saw the comment; the eventual pickup ran on a manual bridge. - **D7 — the status caveat, in the file's own idiom:** this is the spec for a box-side change only the operator can make ([L110-L113](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/FLEET.md#L110-L113)); until `duty.sh` polls it, the wake exists on paper. One consumer already polls for the label and no-ops while it is absent, so the wiring can be verified live the day the row lands. - **D8 — the notifier is not in scope.** `notify.sh` watches what the *operator* owes. `attention` is what an *assignee* owes, and the assignee is an agent whose loop reads it directly. No second queue in the operator's messages. ## Tasks - [ ] `FLEET.md` — the shared wake (D1–D4) in **Wake conditions**, above the per-role bullets. - [ ] `FLEET.md` — the rejected mention-poll and the incident (D5, D6), in the same paragraph or a short one after it; keep it to the file's evidence-then-spec shape, not a new `####` section. - [ ] `FLEET.md` — the on-paper caveat (D7). - [ ] `CHANGELOG.md` — one line under `## Unreleased`, inserted **above** the heading below it. ## Acceptance criteria - [ ] The wake is stated once, applies to all three roles, and names the exact query of D2. - [ ] Its priority relative to the existing per-role triggers is unambiguous — a reader implementing `duty.sh` knows where it goes in the ordering without asking. - [ ] The one-session-per-demand rule and the ack-then-act ordering are both stated, with the die-before-ack case resolved explicitly. - [ ] The rejected mention-poll is recorded with the reason it was rejected. - [ ] The [#16 incident](https://github.com/heavy-duty/ceremony/issues/16#issuecomment-5061051198) is cited as the evidence, matching how the notifier section cites its three. - [ ] The on-paper caveat is present, so the file does not claim wiring that no box has yet. - [ ] The diff touches `FLEET.md` and `CHANGELOG.md` and nothing else. `FLEET.md` is **not** in [`docs/VENDORED.txt`](https://github.com/heavy-duty/ceremony/blob/87f243299d17b1a3831c3345fa11fa638eb21b1d/docs/VENDORED.txt) — nothing here may restate doctrine that belongs in `LABELS.md`, and no doctrine file is edited by this PR. ## Test plan - `test/run.sh` green and the lint scripts clean — no executable behavior here. - `docs-sync --check` unaffected, and that is itself an assertion worth making in the PR body: if it goes red, the diff touched a vendored file it should not have. - The read-through case that must fail: an operator who, reading only this section, cannot tell whether the pickup session removes the label before or after doing the work. Before. If the prose leaves that ambiguous, it is wrong. - Every permalink pinned to a SHA, never `main`. ## Dependencies Blocked by #85. Part of #83.
github-actions[bot] commented 2026-07-23 18:12:49 +00:00 (Migrated from github.com)

Every issue named by Blocked by is closed. The sweep is moving this issue to ready.

<!-- issueflow:blockers-cleared --> Every issue named by `Blocked by` is closed. The sweep is moving this issue to `ready`.
claude-bot-andresmgsl commented 2026-07-23 18:15:59 +00:00 (Migrated from github.com)

Claiming — starting now. Draft PR to follow shortly.

Claiming — starting now. Draft PR to follow shortly.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#86
No description provided.