diff --git a/BUILDER.md b/BUILDER.md index f80fe70..95c3d0d 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -32,6 +32,26 @@ triage bug, and the move is to say so on the issue, not to guess. you to stop, the direction names what the hold waits on, and that thing is not yours to move. This is not "waiting for a good moment": somebody else has decided the work must not proceed, and only they end it. + And it ends the same way it started: **on the labels.** When the queue + labels and any prose — an issue body header, a triage comment, an + operator's comment — disagree about whether a hold stands, the most + recent queue-label event by the hold's owner governs, and the prose is + stale until someone corrects it. So before standing down *or* standing + up on a hold, read the issue's **label events** + (`gh api /repos/{owner}/{repo}/issues/{n}/timeline`), not only its + comments: an operator may lift by label alone, and on 2026-07-24 did, + twice, on [#149](https://github.com/heavy-duty/ceremony/issues/149) + and [#151](https://github.com/heavy-duty/ceremony/issues/151). Acting + on the labels against stale prose, say so in the claim — name the + events you read, their timestamps and their actor, and invite the + correction if the read is wrong; + [the 14:11:45Z claim on #149](https://github.com/heavy-duty/ceremony/issues/149#issuecomment-5070781295) + is the exemplar. Refusing is not a resting place either: + [*"I am not claiming through that contradiction"*](https://github.com/heavy-duty/ceremony/issues/149#issuecomment-5070776624) + was a correct instinct and an incomplete move — the next step is to + read the events, state what they say, and then claim or stand down on + that, or, if the events genuinely do not resolve it, say so on the + issue and pick the next `ready` issue rather than idling on this one. Not parked — these are what the rule defends against: waiting on yourself, waiting on CI, or waiting for a good moment. An issue you have simply stopped working on is not parked either — that is abandonment, diff --git a/TRIAGE.md b/TRIAGE.md index 8638b3e..971641b 100644 --- a/TRIAGE.md +++ b/TRIAGE.md @@ -48,6 +48,17 @@ is the failure this whole flow exists to prevent. name what it waits on, and set `attention` so the assignee's ack is visible on the board — the directive and the builder's doctrine ([BUILDER.md](BUILDER.md#claiming)) must use one word. + Immediately before asserting label-borne state in prose — a hold, a + claim, a queue state, whether in a comment, a body header, or a + `needs-ruling` ask — re-read that issue's **label events** + (`gh api /repos/{owner}/{repo}/issues/{n}/timeline`), not just its + comments: the answer often arrives as a label with no comment, and a + write that re-read only the thread races it. Both 2026-07-24 failures — + [a header correction on #149](https://github.com/heavy-duty/ceremony/issues/149#issuecomment-5070758613) + asserting a hold 58 seconds after its lift, and + [a `needs-ruling` ask on #151](https://github.com/heavy-duty/ceremony/issues/151#issuecomment-5070768876) + the operator's label events had answered 132 seconds earlier — are this + sentence's absence. Past 24 hours from the current episode's `labeled` event, if the ruling still stands and doubt remains, it is triage's duty to pick the option the builder proceeds on, record that pick as a decision, and stay accountable @@ -120,6 +131,14 @@ itself. Keep the checklist current — a stale epic misleads every scan. - **Close obsolete issues** with the reason and a link to what obsoleted them. Every label on every open issue stays true; the board is only worth scanning if it does not lie. +- **A lifted hold makes its body prose stale in the same instant, and the + body is yours.** The "stays true" bar above extends past the labels to + the prose that describes them: when a hold lifts, correcting the body + header that described it is your move in the same tick — not the + builder's, and not left for the next reader to diff. On + [#149](https://github.com/heavy-duty/ceremony/issues/149) the lift + arrived by label alone and the body said held for the next five and a + half minutes; two builders read that window to opposite conclusions. ## What you never do diff --git a/changelog.d/154.md b/changelog.d/154.md new file mode 100644 index 0000000..db3bede --- /dev/null +++ b/changelog.d/154.md @@ -0,0 +1 @@ +- A directive hold now has a written ending, not just a beginning: BUILDER.md's shape 5 says the hold ends where it began — on the labels — with the hold owner's most recent queue-label event governing over any stale prose, the timeline read (`gh api .../issues/{n}/timeline`) named as the move before standing down or up on a hold, a claim against stale prose required to cite the events it read, and a refused claim given its two exits. TRIAGE.md now requires re-reading label events before asserting label-borne state in prose, and makes correcting a lifted hold's stale body header triage's move in the same tick. On 2026-07-24 the unranked signals split two builders reading one board (#149, #151); both acted defensibly — the doctrine, not the builders, lacked the rule (#154).