You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AGENTS.md describes how issues get created, labeled, boarded, and closed — but the rules had gaps and one outright contradiction, and none of them were checkable. This issue covers making them coherent, complete, and verifiable.
1. A milestone is what records approval
Two existing rules contradicted each other: every new issue gets a milestone at create time, and new items start in Incoming, where Incoming means "nobody has reviewed this" and Todo means "a maintainer approved it."
If every issue is milestoned at birth, "has a milestone" carries no approval information, Incoming stops distinguishing reviewed from unreviewed work, and the priority rubric's "linked to a milestone" +1 becomes a constant every issue earns — a bonus that discriminates nothing.
Assigning a milestone becomes the approval act, giving one invariant:
Incoming ⇔ no milestone. Everything past it ⇔ milestoned.
2. Triage is defined by state, not authorship
The natural framing is "externally-filed issues," but that's the wrong line. An outside reporter has no board access — and neither does a maintainer who opens an issue by hand in the GitHub UI instead of through the documented create flow. Write access makes the board reachable, not automatic.
An issue needs triage when it arrives with no board card and no milestone — regardless of who filed it.
What puts an issue in Todo is somebody performing the approval, not who owns the account.
3. Triage has to be runnable
"Triage new issues" should produce the same result every time. That needs more than prose:
A correct discovery query. The obvious one diffs open issues against board Add tab and approval flow for server -> client sampling #28 only — which reports a v1 issue correctly carded on get tools working #11 as unboarded, and double-boards it. It must diff against both boards, filtered by repository, since an org project can hold other repos' issues.
Two passes, explicitly separated. Pass 1 sweeps issues onto the board (label, card, Incoming, Priority, no milestone) and implies no approval. Pass 2 — deciding what ships in which release — is a human judgment call, never done as part of a routine sweep.
The milestoned exception. An unboarded issue that already has a milestone was approved; only its card is missing. It goes straight to Todo, or triage would silently un-approve scheduled work.
4. The board drifts in ways no single-issue rule catches
Only one defect class ("no card at all") was written down. A board audit added covering the rest — double-boarded issues, PRs sitting as board items, statusless cards, both directions of the Incoming ⇔ milestone invariant, wrong board for the version label, missing labels, missing Priority — as a table of invariant + fix plus one runnable check that should print 0 on every row.
5. Done means the work shipped
Nothing said what Done asserts, so an issue closed as a duplicate or won't-fix was being moved there like any other close. That makes the record wrong in a way no later reader can detect: counting Done cards can no longer distinguish a shipped fix from a report closed as a duplicate of one.
Exactly two things earn a card a place in Done — its PR merged, or it is a parent whose last sub-issue closed. Every other close means the card is deleted. Deleting a card touches only the board; the issue keeps its labels and comments and stays searchable.
6. Every issue carries a type label
The version label says which line work belongs to; nothing said what kind of work it is. In practice that meant reaching for bug or enhancement and pressing everything else into one of them — a migration guide and a tsup → tsdown swap both landing as "enhancement," which degrades the label to "not a bug."
Every issue created or triaged now carries exactly one of bug / enhancement / documentation / chore / question, independent of its version label. (chore did not exist as a repo label and was created; the existing dependencies label is Dependabot's and scoped to PRs.)
Scope
Documentation only — AGENTS.md. No code, no board-schema changes. Not mirrored into .github/copilot-instructions.md: board, milestone, and triage mechanics are on that file's deliberately-absent list, since no reviewer cites them against a diff.
Found by
A board audit on 2026-08-05 that swept every open issue against both project boards. It surfaced 17 issues with no label, no milestone and no card; 34 boarded issues with no milestone; a v2 issue on the v1 board; two double-boarded issues; and 5 PRs sitting as items on board #11. Fixing those is what exposed the rule gap: 47 issues got milestones mechanically, by rubric band, and then sat in Incoming — and nothing in AGENTS.md said that was wrong or what should have happened instead.
Each rule added since has been validated by running its check against the live boards, which caught further real defects — including a v1 issue carded on board #28 while holding a v2 release milestone (#1040).
AGENTS.mddescribes how issues get created, labeled, boarded, and closed — but the rules had gaps and one outright contradiction, and none of them were checkable. This issue covers making them coherent, complete, and verifiable.1. A milestone is what records approval
Two existing rules contradicted each other: every new issue gets a milestone at create time, and new items start in
Incoming, whereIncomingmeans "nobody has reviewed this" andTodomeans "a maintainer approved it."If every issue is milestoned at birth, "has a milestone" carries no approval information,
Incomingstops distinguishing reviewed from unreviewed work, and the priority rubric's "linked to a milestone" +1 becomes a constant every issue earns — a bonus that discriminates nothing.Assigning a milestone becomes the approval act, giving one invariant:
2. Triage is defined by state, not authorship
The natural framing is "externally-filed issues," but that's the wrong line. An outside reporter has no board access — and neither does a maintainer who opens an issue by hand in the GitHub UI instead of through the documented create flow. Write access makes the board reachable, not automatic.
What puts an issue in
Todois somebody performing the approval, not who owns the account.3. Triage has to be runnable
"Triage new issues" should produce the same result every time. That needs more than prose:
v1issue correctly carded on get tools working #11 as unboarded, and double-boards it. It must diff against both boards, filtered by repository, since an org project can hold other repos' issues.Incoming, Priority, no milestone) and implies no approval. Pass 2 — deciding what ships in which release — is a human judgment call, never done as part of a routine sweep.Todo, or triage would silently un-approve scheduled work.4. The board drifts in ways no single-issue rule catches
Only one defect class ("no card at all") was written down. A board audit added covering the rest — double-boarded issues, PRs sitting as board items, statusless cards, both directions of the
Incoming⇔ milestone invariant, wrong board for the version label, missing labels, missing Priority — as a table of invariant + fix plus one runnable check that should print0on every row.5.
Donemeans the work shippedNothing said what
Doneasserts, so an issue closed as a duplicate or won't-fix was being moved there like any other close. That makes the record wrong in a way no later reader can detect: countingDonecards can no longer distinguish a shipped fix from a report closed as a duplicate of one.Exactly two things earn a card a place in
Done— its PR merged, or it is a parent whose last sub-issue closed. Every other close means the card is deleted. Deleting a card touches only the board; the issue keeps its labels and comments and stays searchable.6. Every issue carries a type label
The version label says which line work belongs to; nothing said what kind of work it is. In practice that meant reaching for
bugorenhancementand pressing everything else into one of them — a migration guide and atsup→tsdownswap both landing as "enhancement," which degrades the label to "not a bug."Every issue created or triaged now carries exactly one of
bug/enhancement/documentation/chore/question, independent of its version label. (choredid not exist as a repo label and was created; the existingdependencieslabel is Dependabot's and scoped to PRs.)Scope
Documentation only —
AGENTS.md. No code, no board-schema changes. Not mirrored into.github/copilot-instructions.md: board, milestone, and triage mechanics are on that file's deliberately-absent list, since no reviewer cites them against a diff.Found by
A board audit on 2026-08-05 that swept every open issue against both project boards. It surfaced 17 issues with no label, no milestone and no card; 34 boarded issues with no milestone; a v2 issue on the v1 board; two double-boarded issues; and 5 PRs sitting as items on board #11. Fixing those is what exposed the rule gap: 47 issues got milestones mechanically, by rubric band, and then sat in
Incoming— and nothing inAGENTS.mdsaid that was wrong or what should have happened instead.Each rule added since has been validated by running its check against the live boards, which caught further real defects — including a
v1issue carded on board #28 while holding a v2 release milestone (#1040).