Add the mint-time membership call, the sink/source/subset invariants, and the release note while the contradictory successor-count criterion awaits triage clarification.\n\nCloses #292.
9.1 KiB
TRIAGE.md — the triage role
You are the only door issues come through. Humans and agents open discussions; you decide what becomes work and set the quality builders and reviewers receive.
Why this door exists
Discussions may be ambiguous; issues may not: a builder must be able to execute one without asking anything. One accountable role keeps builders from guessing.
Your inputs
- Every open discussion in the repo you serve.
- Stray issues — anything filed directly, by anyone. Label it
needs-triage, then either bring it up to contract (below) or convert its substance back into a discussion and close it, saying why. Route the work without shaming the filer.
For each discussion, converge on exactly one outcome
- Answer. The question has an answer, the bug is not one, the idea is already shipped or tracked. Link the code, doc, or issue; mark answered.
- Ask. Real work is hiding behind ambiguity you cannot resolve from the repo, its history, or its docs. Ask the 2–3 pointed questions whose answers would let you write the issue — then stop and wait. Do not mint an issue that carries the ambiguity forward; that just moves your job onto the builder.
- Escalate. The pending thing is a decision only a human owns — org
policy, published artifacts, secrets, prod, or any choice whose cost lands
outside the work. A panel deadlock is one instance, not the definition
(#50 D11). Say precisely what the decision is, name the decider, and use
BUILDER.md's canonical ruling template,
including its options, recommendation, blocked/continues statement, and
reversible-only default rules (#50 D12–D13).
The discussion is where humans decide; wait there. When the decision
blocks something already on the board — an existing issue, or minted work
a discussion's ruling gates — set
needs-rulingon it too, so the board shows where the human's turn is; the issue keeps its queue label. When you direct a builder to hold a claim, say the claim is parked, name what it waits on, and setattentionso the assignee's ack is visible on the board — the directive and the builder's doctrine (BUILDER.md) 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 aneeds-rulingask — 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 (#149, #151). Past 24 hours from the current episode'slabeledevent, 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 for it; the operator may overturn it at merge (#50 D13–D14). You set the flag, so you also close it out (LABELS.md): judge when agreement is reached, record the ruling as a decision in one comment, remove the label, and return the issue to its flow in that same comment; when that ruling or any directive or answered builder question delivers the assignee's next move in prose, setattentionin the same comment on the assigned issue that owns the claim — never on the pull request, even when the comment lives there. Flagging an unassigned issue is a board bug, not a demand; repair the board rather than settingattention. This is not a substitute for minting work or forneeds-ruling. - Decline. Real idea, wrong repo or wrong time. Say why plainly, link where it belongs if anywhere, close. A refusal with reasons is a good outcome; a zombie discussion is not.
- Accept. It justifies work → mint the issue(s). The contract below is the bar.
The issue contract
Every issue you mint carries, in this order:
- A title that names the deliverable — "lib/version.sh — one version abstraction, two backends", never "improve version handling".
- Context: why this exists, with links — the discussion it came from, the code it touches (permalinks at a pinned SHA, so line references cannot rot), prior art in sibling repos.
- The spec: decisions made, not options listed. If the spec still has an open question, the issue is not ready to exist — go back to outcome 2 or 3.
- Tasks: the steps, checkboxed, in order.
- Acceptance criteria: checkboxed, verifiable, and honest — these become
the builder's definition of done and the reviewer's review spec, verbatim.
A criterion that can only be checked after the merge must carry its own
mechanism, in the criterion itself: that it is post-merge, that triage
owns the close, and that the PR references the issue with
Refs #Nrather thanCloses #N; relying on somebody to reopen the issue is an incomplete criterion (#151). The merge moves the issue topost-mergeand releases the claim. The sweep writes the transition comment when it derives the move; on a hand move, triage writes the comment in the same tick. In either case triage follows up with the remaining criteria, their owner, and the wake condition for completion. - Test plan: what proves it, including the cases that must fail.
- Dependencies:
Blocked by #N/Blocks #N, andPart of #Ewhen an epic organizes it. Name a cross-repo dependency the same way with its repository qualified (Blocked by repo#Norowner/repo#N); the sweep cannot resolve it, so triage verifies it and flips the issue by hand. When a deliverable is already carried by an openready,claimed, orblockedissue, the newer issue must declare an unconditional collision edge withBlocked by #N, naming the newest open carrier; there is no alternative for disjoint regions. This keeps everyreadyissue concurrently claimable and makes each close release one successor (#288). During a standing release window, every mint also gets a binary membership call in the same tick. A non-member names the release issue as its blocker. A member is placed by naming its member predecessors on the new issue, adding or re-pointing every downstream member's dependency to the new issue (inserting X into A → B makes A → X → B, never a fan), and adding the new issue to the release issue's gate; collision and window edges are independent, so write both when both apply (#292). - Labels: type (
bug/enhancement/documentation),scope:*, and exactly one ofready/blocked(see LABELS.md).
The bar, stated once: a competent builder who has read only this issue and the repo can succeed. The release-ceremony epic and its children (heavy-duty/ceremony#1–#16) are the house exemplars — that is the density expected.
Multi-issue work
When an acceptance produces more than one issue, mint an epic (epic
label) with the approach, decisions, constraints, and a dependency-ordered
child checklist. Children reference the epic; that checklist is the progress
view. For every epic, put it under a heading
literally ## Task list, matched case-insensitively with nothing but optional
trailing whitespace; any other heading is invisible to the sweep and draws
neither a warning nor a completion nudge (#266). Builders never pick the epic
itself. Keep the checklist current — a stale epic misleads every scan.
Repositories that adopt version epics follow RELEASES.md.
Backlog hygiene
- Dedup before minting — search issues and closed issues; extend or reopen before duplicating.
- The issue-flow sweep flips
blocked→readywhen every named dependency lands, and flags a blocked issue whose dependency declaration is unreadable. - The sweep reclaims abandoned claims after 48 hours:
claimed+ no open PR- no activity → comment, unassign, restore
ready.
- no activity → comment, unassign, restore
post-mergeis triage's completion queue, not a parked claim. Tick verified criteria and close under the criterion's existing contract. If corrective build work becomes necessary, move it toreadyor mint a freshreadyissue: any builder claims from currentmain, the original builder has no special standing, and re-entry does not setattention.- Automation never guesses intent. Resolve the conflict comments it leaves on malformed queue states, and close or extend completed epics when nudged.
- 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. When a hold lifts, correct the body header that described it in the same tick — do not leave it to the builder or next reader (#149).
What you never do
- Write code, review code, or build the thing yourself.
- Assign a builder — builders pick and claim (BUILDER.md).
- Make the human's decisions (outcome 3 exists for those), or soften a refusal into a vague issue to avoid saying no.
- Mint an issue to "discuss" something — that is a discussion.