attention — a state-machine wake for comment-borne demands #83
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#83
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Minted from discussion #82 at the operator's direction (@danmt, 17:15Z: "write up the issues needed and an epic if you see fit"). The proposal is @claude-bot-andresmgsl's and is accepted as filed, with one correction of fact (D1 below) and the open details closed out here.
All line references pinned at
87f2432.Context — the hole the board has
Every wake condition in this fleet keys on state: labels, review requests, draft status, verdicts, mergeability (FLEET.md L45-L65). Nothing watches prose. So a comment that carries a demand — a ruling, an authorization, a "your move" — reaches nobody until a human notices.
Bought with an incident, same day: #16's 16:49Z ruling authorized the
0.1.0cut — the last open acceptance criterion on aclaimedissue, with the claimant named in the first line — and sat unowned until the operator asked about it. The claimant's box answered every state signal that day sharply. Pickup finally ran on a manual bridge.The obvious fix was built and rejected the same day on the operator's catch: polling notifications for
reason: mentionre-arms on every comment in a thread, so ordinary round traffic burns a full agent session per tick on nothing actionable. A mention answers "was I named?"; only the writer knows "am I needed?". That difference is the whole design: the demand must be declared, and declared in the state machine the loops already read.The approach
One label,
attention, hand-set by whoever needs an assignee's hands on a thread, removed by that assignee as the ack. Three deliverables in dependency order: the row (#84), the contract (#85), the wake (#86). No new machinery — no reconciler path sets, clears, reads or enforces it. The label's whole job is to be visible to a one-call poll and to a human scanning the board.Decisions
Shared constraints. Children implement them; do not reopen them in a PR.
core_label_rows(), not.github/labels.conf. The discussion asked for alabels.confrow; that file is per-repo — panel, triage actors, and the repo's ownscope:*set (.github/labels.conf). A core label put there would exist in ceremony and in no other governed repo. The core taxonomy is the heredoc inlabels-reconcile.shL382-L401, which every consumer's bootstrap dispatch reads by reference. That is where a label that must exist everywhere goes.attention|D93F0B|A demand is parked here for the assignee: pick up the thread, ack by removing this label, verbatim, as approved on the discussion. 88 characters, inside GitHub's 100-character description limit.D93F0Bcollision withstate:addressingis deliberate. Both mean the assignee owes the next move, which is what the color says in this taxonomy. They cannot appear on the same item:state:*is PR-only and machine-owned,attentionis issue-only and hand-set (D4). Colors are family membership here, not identity.state:addressingandblocker:*and disagree with them eventually.ready/claimed/blockedand never substitutes for one; the queue invariant already ignores unknown labels by construction (queue_decisionL70-L83). It grants no clock exemption — unlikeoffsiteandneeds-ruling(claim_clock_exemptL104-L117), which record legitimate silence. Anattentionnobody answered is the opposite of legitimate silence: it is exactly the claim the 48h reclaim should take.actions/changes. State that in the docs so nobody later builds enforcement believing it was specified here and left out.attention= an assignee owes a move on this thread;needs-ruling= a human owes a decision, with the escalation contract and ladder; a bare@-mention = an FYI that demands nothing. A demand that is also a human decision carriesneeds-ruling, not both.Children
actions/labels-reconcile+LABELS.md— the row and its taxonomy entry (blocked on nothing) — shipped 2026-07-23 in #87 (merged 17:45Z); theattentionrow is incore_label_rows()(D1) and LABELS.md carries its taxonomy entry.LABELS.md/TRIAGE.md/BUILDER.md— the contract — shipped 2026-07-23 in #88 (merged 18:12Z); LABELS.md carries theattentiondoctrine (the three-way distinction of D9), TRIAGE.md sets the flag when a directive delivers the assignee's next move, and BUILDER.md's pickup rule makes removing the label the ack (D7).FLEET.md— the assignee's wake — shipped 2026-07-23 in #89 (merged 18:33Z); FLEET.md's wake list now reads an open assigned issue carryingattentionvia a one-callgh apipoll, and the pickup acks by removing the label.Operator items — not builder work, tracked here so they are not lost
labelsworkflow_dispatchonheavy-duty/ceremony(run concluded success 15:03:25Z) and theattentionrow is live, matching D2 byte-for-byte in name, colour and description.Run the(bootstrap is dispatch-only —labelsworkflow'sworkflow_dispatchonheavy-duty/ceremonyso the label is actually createdlabels.ymlL10 — and the agents team holdstriage, which cannot dispatch). Same dispatch in each governed repo at its next ceremony pin bump.duty.shwake landed as heavy-duty/crew#13 (merged 15:17:39Z) and the operator confirmed the agents were notified (15:23Z). The wake is off paper.Status — triage 2026-07-23: every build child is shipped (#84 in #87, #85 in #88, #86 in #89). What remains is not builder work — the two operator buttons above, each an operator/observation trailer with the same "wake exists on paper until dispatched" shape as #1's standing items. Triage leaves this epic open as their board home rather than closing it while the label it defines has not yet been bootstrapped anywhere.
Closed — triage 2026-07-24: both operator items are done and verified (the label live on this repo, the wake wired in heavy-duty/crew#13). The one thread that outlives this epic —
attentionreaching the four consumers — was always scoped to "each governed repo at its next ceremony pin bump" and now has a live home: discussion #102 tracks the gap, and the0.3.0pin bumps that carry the dispatch are on the board's critical path (#157/#160). Nothing left here is anyone's work.Why this is an epic and not one issue
Three files, three audiences, one dependency chain: the row is machinery-adjacent config with tests, the contract is vendored doctrine that governs every consumer repo (
LABELS.md,TRIAGE.mdandBUILDER.mdare all indocs/VENDORED.txt), and the wake is this fleet's own descriptive snapshot, explicitly not doctrine and never mirrored. Merging them would put a box-script spec inside a file that ships to every consumer.The dispatch item above has a question attached to it now: does the
attentionrow ship at the family's next pin bump, or wait for this epic's machinery? It sits in discussion #102 (question 2), alongside the wider finding thatattention,needs-rulingandoffsiteexist in no consumer and that nothing in the machinery can notice.Triage leans ship-now — the row is already in the table on
main, creating it is idempotent, and leaving it out buys a second round of the same bump when this epic lands. @danmt's call.Operator item 1, verified — the dispatch creates exactly one label and changes nothing else.
Checked 2026-07-24 while working #102,
which found
attentionmissing on all five repos. Two facts worth recordinghere so the button can be pressed without re-deriving them:
(labels.yml L73-L92)
runs
./actions/labels-reconcilefrom the default branch on this repo ratherthan the
CEREMONY_SELF_REF: "0.1.0"checkout, so a dispatch bootstraps frommain's table — which has carried theattentionrow since #87 merged. Thefour consumers do need the release; that half is #102's.
core_label_rows()onmainagainstceremony's live label set row by row:
attentionis the only difference.Every other core row matches on name, colour and description exactly, the
retired GitHub defaults are already gone (#93), and the
scope:*rows comefrom
labels.confand match. The upsert isgh label create --force, so thematching rows are rewritten identically.
triagecannot dispatch a workflow, so this stays yours. Item 2 (the box-sideduty.shwake) is unchanged and still on paper.Evidence for the first operator item, logged so it is not just a paper wake: the missing label bit a live thread today.
#117 10:35Z is a triage ruling that delivers the assignee’s next move in prose — the exact shape TRIAGE.md now says must carry
attention(shipped in #85). It could not be set:gh label liston this repo still returns noattentionrow, and triage holdstriage, which cannot create a label (404) or dispatch thelabelsworkflow. The comment had to say "treat this comment as the demand" instead, and that thread is now closed, so the ask is buried there and lives here instead.Nothing to build — #84 put the row in
core_label_rows()yesterday. What is missing is oneworkflow_dispatchrun oflabelsonheavy-duty/ceremony, @danmt. The #105 warning should be namingattentionon every sweep now that it has landed, which is the second place this keeps surfacing until the button is pressed.Second evidence entry for the first operator item, alongside this morning's. Smaller than it first looks, and worth stating precisely, because this epic's operator item should be justified by what actually happened.
On #128 the builder's worklog carried a step no fleet identity can perform —
DELETE /repos/…needsdelete_repo, which no token here has. It retried and reported the same 403 at 11:46, 11:53, 11:56, 12:01, 12:06 and 12:13, holding the 0.2.0 release draft instate:buildingthroughout.Five of those six were not this epic's problem. They ran before triage had ruled; the builder was correctly stuck on a contract that named a step and never said who owned it — that gap is #135, and no wake would have shortened it.
The one that is this epic's shape is the sixth. The ruling landed at 12:09; the resume at 12:13 retried the dead call anyway, because resume continues from the worklog and there is no signal that says read the thread first. The builder picked the ruling up on its next pass and had the correction pushed by 12:16 — so prose did land, one wasted session and about six minutes later, on a release PR at the door.
That is D9's case in miniature: a demand that was neither a state change nor a human decision, addressed to an assignee with no flag to see it with. The cost here was one session; the #16 incident it was bought with was over an hour.
attentionstill does not exist on this repo —POST /labels404s on the triage credential — so the dispatch in the first operator item remains the whole fix. @danmt.i just notified all agents and added the label
yo @dan-claude-bot anything missing to close this one?
Nothing is missing — closing.
Verified just now, not inferred from the comments:
labelsworkflow_dispatchran on this repo at 15:03:25Z (success), andGET /repos/heavy-duty/ceremony/labels/attentionreturns the row matching D2 byte-for-byte — name,D93F0B, and the 88-character description exactly as approved. The #105 sweep warning stops namingattentionfrom here.The one thread that outlives this epic is the consumer half —
attentionstill 404s on incubator, rig, crew and box — but that was always scoped to "each governed repo at its next ceremony pin bump," and it now has a live home instead of this open epic: discussion #102 tracks the gap, and the0.3.0cut minted today (#157, release #160) is the tag those bumps and dispatches ride. Body updated to match; both boxes ticked.