Repository navigation
tech-debt(labels): priority is spelled ten ways, so every canonical-label filter misses the variants #16447
Description
Activity
AC1 and AC3 are met, verified against the live GitHub state. AC2, the docs, follows once #16487 lands, because it edits the same
CLAUDE_WORKFLOW.md.Criterion Evidence No issue carries a variant; the variants no longer exist 659 items were relabelled from the 10 variants: P0-critical12,high-priority136,priority-high21,P1-high48,P2-medium165,medium-priority89,priority-medium9,priority-low9,P3-low112,low-priority58. There were 0 conflicts and 0 failures. The 4 ad-hoc near-duplicates were on closed issues only and also migrated:priority:critical3 andcritical29 went topriority: critical,P118 topriority: high, andP26 topriority: medium. Each of the 14 labels was deleted only afterissues?labels=<name>&state=allreturned 0.gh label listnow shows exactlypriority: critical,priority: high,priority: mediumandpriority: low.Open issues sit in their mapped milestone All 40 open issues among the 659 were re-read after the migration, and 0 mismatches were found: critical and high in v0.9.0, medium in v0.10.0, low in Backlog. No moves were needed. The deleted labels' name, colour and description are kept in the migration log, in case any needs to be recreated. They were all default grey with no description.
Witness from a v0.10.0 triage (#17863): the same shape applies to the tech-debt label, not only to priority.
tech-debtandtechnical-debtboth exist and are both in active use — within the v0.10.0 milestone alone, 60 issues carrytech-debtand 27 carrytechnical-debt. So any filter, saved search or report keyed on one spelling silently omits a third of the set, which is this issue's exact failure mode.Not investigated further — recording it here rather than filing, since you already own the vocabulary problem. I did not check the other milestones or whether both labels have descriptions, so 60/27 is a v0.10.0-scoped count, not a repo-wide one.
Third instance of this defect class, and this one has an outward-facing cost.
Following the
tech-debt/technical-debtsplit I noted above, the same duplicate-vocabulary problem exists for the contributor-onboarding label — and here it is not just a filter that misses rows, it is a public page that renders empty.$ gh label list --limit 200 | grep -iE 'good.?first|help.?wanted' good first issue good-first-issue help wanted help-wantedFour labels, two concepts. And the open-issue counts fall entirely on the non-canonical spellings:
Label Open issues good-first-issue(hyphenated)24 good first issue(spaces — GitHub's canonical name)0 help wanted(spaces — canonical)0 GitHub's
/contributepage and the third-party good-first-issue aggregators key on the canonical spaced names. So the repository has 24 issues curated for newcomers and advertises none of them.That makes this cheaper to fix than it looks, and it is worth distinguishing from the obvious reading. An external review of this repo concluded "0 open good first issue labels, so GitHub's /contribute page has nothing to show" and recommended labelling 5–10 small issues. The observable effect is right and the remedy is wrong: the issues are already curated, so the work is re-labelling 24 existing ones onto the canonical names, not authoring new ones. Same for
help wanted.Recording it here rather than filing, since this issue already owns the vocabulary problem. Worth noting the pattern now has three instances with different costs:
priority(filters miss rows),tech-debt(a third of a milestone invisible to either spelling), and this one (a public page renders empty while the content exists).A second instance of the class this issue names — newcomer labels, with an external consequence
This issue states the class mechanism in its own title: a label spelled several ways means every canonical-label filter misses the variants. Priority is one instance. Here is another, measured today:
label issues carrying it (all states) good-first-issue100+ (hit my query limit of 100) good first issue3 help-wanted3 help wanted0 All four labels exist in the repo simultaneously.
Why this one differs from the priority instance. The priority variants break our filters, milestone rules and board views. These break GitHub's own newcomer discovery, which keys on the default label names
good first issueandhelp wanted— the spaced spellings. So the at-least-100 issues deliberately marked as newcomer-friendly sit on the hyphenated variant and are not surfaced by it, while the 3 on the canonical spelling are.The one thing I have not verified in-repo: that GitHub keys its newcomer surfacing on the spaced default spellings specifically. That is stated from knowledge of the default label set, not measured here. Everything in the table above is measured. Whoever picks this up should confirm the keying before relabelling 100+ issues on the strength of it.
Why I am commenting rather than filing. Per the one-defect-one-fix rule, a defect class is fixed once with its instances listed in the single issue that owns it, not once per instance. This issue owns the class. Two notes for whoever closes it:
- Its first acceptance criterion is already ticked and is worded for priority labels only (
No issue carries a variant priority label). If this instance is taken on here, that wording needs widening; if not, this wants a child issue rather than a silent drop. - A relabel here is 100+ issues, versus the priority backfill's ~22, so it is a different size of operation even though it is the same defect.
Found while verifying a set of repository-presentation claims. The release-flag finding from that same pass is #17878 — unrelated mechanism, filed separately.
- Its first acceptance criterion is already ticked and is worded for priority labels only (
Two of three verified against merged
main. The third is one line short, and I am not ticking it, because the thing it asks for is the thing that is missing.AC1 — met, and stronger than claimed.
gh label listreturns exactly four priority labels:priority: critical,priority: high,priority: medium,priority: low. All ten variants named in the table are gone from the repo, and asearch/issuescount for each ofP0-critical,high-priority,priority-high,P1-high,P2-medium,medium-priority,priority-medium,priority-low,P3-low,low-priorityreturns 0.AC3 — met, and consistent with AC1: with the variant labels deleted there is no issue left to be mis-bucketed.
AC2 — not met
"The canonical priority labels are documented as the only ones."
docs/developer/CLAUDE_WORKFLOW.md:225reads:- **Priority:** `priority: critical`, `priority: high`, `priority: medium`, `priority: low`That is a list under "Issue Labels — always apply", not a statement of exclusivity. It tells a reader which labels to apply; it does not tell them these are the only ones that exist, which is what the criterion asks and what would stop someone re-creating
P1-highnext time they want one.I could argue this closed and I do not think I should. The argument would be that the variants are structurally the only ones now — they were deleted, so no documentation is needed to make it true. That is a real and arguably stronger form of enforcement than a doc line. But it is not what the criterion says, and reinterpreting a criterion so the available evidence satisfies it is how an issue gets closed over the gap it was filed to cover. The point of the doc line is the next person, who will not run
gh label listbefore inventing a label.What closing it needs
One line at
:225— something that says these four are the complete set, not merely the ones to apply. No code, no behaviour change.It should not get its own PR. The CI queue is at width one with five PRs in it.
docs/developer/is already being edited on the branch carrying the #17897 pgdg fix (adding 54's dead-prose heuristic toCLAUDE_REVIEW.md), and this is the adjacent file in the same directory — it rides there for free. Noted to that session.Two of three, held open on a one-line doc edit with a home already identified.
Third criterion delivered in #17926; leaving the issue open deliberately.
docs/developer/CLAUDE_WORKFLOW.mdlisted the four priority labels but never said the list was
complete, so nothing distinguished "these are the canonical four" from "here are four examples".
The line now states it, and says a fifth value is a typo that silently applies nothing rather than
a new tier:Priority:
priority: critical,priority: high,priority: medium,priority: low
— these four are the complete set; the repo defines no otherpriority:label, so a
fifth value is a typo that silently applies nothing, not a new tier.gh label list
is the check (#16447).Evidence.
gh label list --limit 200returns exactly fourpriority:labels and no variant:priority: critical priority: high priority: medium priority: lowThat same output also corroborates this issue's first criterion from the other direction — a label
that does not exist cannot be carried by any issue, so "the variant labels no longer exist" and "no
issue carries a variant priority label" are settled by one measurement rather than two.What I did not verify, and why it is not a formality. The milestone criterion — every open
issue that had a variant label sits in the milestone its canonical priority maps to — is ticked,
and I left that tick alone rather than re-asserting it. I cannot reproduce its evidence: the fix
for the first criterion deleted the variant labels, so which issues once carried them is no
longer derivable from the current state. The three criteria are not independent; satisfying the
first destroyed the input needed to re-check the third.So the tick is as good as the migration record behind it, and that record is not in the repo. If
you hold it (a migration log, the PR that did the relabelling, or the pre-deletion label
membership), that closes this issue immediately. If it is gone, the criterion is unfalsifiable now
and the honest options are to close on the migrator's attestation or to re-derive milestone
placement from currentpriority:labels — which answers a different question (where issues sit
today, not whether the migration moved them correctly).#17926 therefore says
Refs #16447, notCloses. The repo squashes with
squash_merge_commit_message = COMMIT_MESSAGES, so a closing keyword in a commit body executes the
closure at merge with nobody re-reading the criteria at that moment — which is how #17897 came to
close at four of seven criteria met today before being reopened. Not worth repeating on this issue
while one criterion rests on evidence that no longer exists.
Problem
Priority is spelled in ten different labels on open issues. There are three canonical ones,
priority: critical,priority: highandpriority: medium, pluspriority: low. Alongside them:priority: criticalP0-criticalpriority: highhigh-priority,priority-high,P1-highpriority: mediumP2-medium,medium-priority,priority-mediumpriority: lowpriority-low,P3-low,low-priorityAny filter, milestone rule or board view keyed on the canonical label silently misses the variants. The 2026-09-12 milestone backfill put about 22 high-priority issues into Backlog this way, until a fix-up pass re-bucketed them. There are also unused near-duplicates with no open issues (
priority:criticalwithout the space,critical,P1,P2).Fix
docs/developer/CLAUDE_WORKFLOW.md, where the label rules live.Acceptance criteria