Skip to content

AGENTS.md: 'Incoming ⇔ no milestone' is wrong — a milestoned card may legitimately stay in Incoming #2005

Description

@cliffhall

The problem

AGENTS.md states, as a hard invariant, that a card's Status and its milestone are locked together:

Incoming ⇔ no milestone, everything past it ⇔ milestoned — AGENTS.md:497

and the board audit encodes that as a defect check:

Check Invariant Fix
Incoming with a milestone Incoming ⇔ no milestone Approval was never recorded: move to Todo, or clear the milestone

That does not match how the board is actually used. Incoming is simply where an issue lands on the board. A maintainer then reviews it in place and either assigns a milestone or closes it on merit — and assigning the milestone does not by itself mean the card moves out of Incoming. So a milestoned card sitting in Incoming is a normal, correct state, not a defect.

What it cost

During the 2026-08-14 triage sweep the audit flagged #1973 (Incoming, milestone v2.3.0) as a violation, and following the documented fix moved its card to Todo — a change the maintainer did not want and had to be reverted. The rule is wrong, not the board, and an audit that reports a false positive trains people to ignore it.

Scope of the change

The Incoming/milestone biconditional is asserted in several places; all of them need to agree:

  • AGENTS.md:497 — "The milestone is the machine-checkable form of that claim — Incoming ⇔ no milestone, everything past it ⇔ milestoned."
  • AGENTS.md:469 (Project Boards) — "Assigning the milestone is the approval act, so the two always go together: a milestoned card sitting in Incoming is a card whose approval was never recorded…"
  • AGENTS.md:302 — the Incoming with a milestone row of the board-audit table.
  • AGENTS.md:333 — the corresponding "Incoming w/ milestone" key in the audit jq query. Remove the check (it has no true-positive case left).
  • AGENTS.md:291 — "Incoming is the review queue, and 'milestoned' is the line between reviewed and not".
  • AGENTS.md:174 — the callout's closing sentence pairing Todo-with-milestone against Incoming-without.
  • AGENTS.md:263 and the sweep query's destination hint at :278–:281 — the "unboarded issue that already carries a milestone → board straight into Todo" exception. If a milestone no longer implies "past Incoming", this should probably become Incoming, keeping the milestone, and the query's printed destination should drop the Todo branch.
  • .github/copilot-instructions.md — check whether the mirror repeats any of this (board mechanics are listed as not review-relevant, so it may already be absent; confirm rather than assume).

What must not change

  • Triage (pass 1) still leaves the milestone unset. The complaint is about the audit's reading of a milestoned Incoming card, not about triage assigning milestones — triage must keep not assigning them (AGENTS.md:259, :291, :578).
  • The Past Incoming without a milestone audit check stays. A card in Todo/In Progress/In Review with no milestone is still a real defect.
  • The milestone signal bonus in the priority rubric stays, along with its note that a pass-1 issue never earns it.

Acceptance

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationv2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions