Skip to content

PRD: Canonical triage labels + backlog triage rollout #1132

Description

@busbyk

This was generated by AI during triage.

Problem Statement

As maintainers of NWACus/web, we have 83 open issues and no consistent way to tell what state any of them is in. We recently adopted an agent-assisted triage workflow (docs/agents/issue-tracker.md, docs/agents/triage-labels.md) that speaks in terms of five canonical triage states — but four of the five don't exist as labels yet, and the backlog predates the workflow entirely:

  • 35 open issues have no labels at all; only 14 of 83 carry a category (bug/enhancement).
  • Legacy labels overlap the canonical vocabulary: NEWneeds-triage, needs user feedbackneeds-info, needs-investigationneeds-triage, questionneeds-info.
  • The three issues marked needs user feedback (Include events from another AC #673, A3 courses can display alongside avalanche center events #808, Change Forecast Navigation? #919) have no comment telling the reporter what feedback is needed — the label is a dead end.
  • Issue templates auto-apply labels that fight the new vocabulary: bug_report.md and blank.md apply NEW; claude-task.md applies claude, a label that does not exist, so GitHub silently drops it and those issues arrive unlabeled.
  • Several labels answer no question anyone asks: area:* (only 6 of 83 open issues carry one; nobody routes work by area), quick fix, urgent, question (zero open uses each).

The result: nobody — maintainer, teammate, contributor, or agent — can query "what needs my attention," "what's ready to pick up," or "what are we waiting on."

Solution

Adopt a single, minimal label vocabulary where every label answers a real query, migrate the backlog onto it, and wire the issue templates so new issues arrive pre-labeled. Then triage the existing 83 issues in phases so every open issue carries exactly one category (bug/enhancement) and one state (needs-triage/needs-info/ready-for-agent/ready-for-human/wontfix).

Final vocabulary — 14 labels:

Group Labels
State (5) needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix
Category (2) bug, enhancement
Tenant (1, grows on demand) tenant:nwac (renamed from NWAC Specific; tenant:dvac etc. created when first needed)
Modifiers (4) good first issue, tech debt, blocked, payload-workaround
Dependabot / PRs (2) dependencies, javascript (untouched, not part of issue triage)

User Stories

  1. As a maintainer, I want every open issue to carry exactly one category and one state label, so that I can see the shape of the backlog at a glance.
  2. As a maintainer, I want a needs-triage queue, so that I know exactly which issues are waiting on my evaluation and can process them oldest-first.
  3. As a maintainer, I want a needs-info state with a triage-notes comment on each issue, so that reporters know precisely what to answer and stalled issues don't look like active ones.
  4. As a maintainer, I want exactly one label for each concept (no NEW vs needs-triage, no question vs needs-info), so that queries don't silently miss issues filed under a synonym.
  5. As a maintainer, I want new issues to arrive already stamped needs-triage via the issue templates, so that the untriaged bucket never silently regrows.
  6. As a maintainer, I want stale legacy labels (quick fix, urgent, question, area:*) removed, so that the label picker offers only choices we actually use.
  7. As a maintainer, I want tenant-specific issues labeled tenant:<slug>, so that center-specific work (currently 5 NWAC issues) is queryable per tenant and the scheme extends to DVAC/SAC/SNFAC and future centers without inventing new conventions.
  8. As a teammate reviewing this plan, I want the full label inventory with create/migrate/delete/keep decisions in one document, so that I can object to a specific decision rather than reverse-engineering intent from label churn.
  9. As a teammate, I want ready-for-human distinct from ready-for-agent, so that I can pick up work requiring judgment, design decisions, or external access without wading through agent-suitable tasks.
  10. As an open-source contributor, I want good first issue kept and paired with a written brief on the issue, so that I can start contributing without insider context.
  11. As an AFK agent (Claude via @claude mention or triage sessions), I want ready-for-agent to mean "fully specified, with an agent brief," so that I can implement without guessing requirements.
  12. As an AFK agent, I want the claude-task.md template to apply ready-for-agent instead of the nonexistent claude label, so that maintainer-authored agent tasks enter the state machine correctly instead of arriving unlabeled.
  13. As a bug reporter, I want the bug template to stamp bug + needs-triage, so that my report enters the triage queue without anyone having to notice it manually.
  14. As a reporter whose issue is marked needs-info, I want a comment listing the specific questions blocking triage, so that I can respond once with everything needed.
  15. As a maintainer, I want tech-debt issues to carry enhancement + tech debt (modifier, not a third category), so that the category invariant stays simple while tech debt remains queryable.
  16. As a maintainer, I want blocked kept as an orthogonal modifier, so that an issue can be both ready-for-human and blocked without corrupting the state machine.
  17. As a maintainer, I want payload-workaround kept (template-wired, tracks workarounds to revisit when upstream Payload fixes land), so that dormant-but-purposeful tracking survives the cleanup.
  18. As a maintainer, I want rejected enhancements written to .out-of-scope/ when closed wontfix, so that future duplicate requests can be answered by pointing at the prior decision.
  19. As a future maintainer, I want docs/agents/triage-labels.md updated to match the actual label set, so that agent-assisted triage sessions and reality never diverge.

Implementation Decisions

Label creation. Create four state labels with traffic-light colors so state reads at a glance in the issue list: needs-triage (#D93F0B orange, "Maintainer needs to evaluate this issue"), needs-info (#FBCA04 yellow, "Waiting on reporter for more information"), ready-for-agent (#0E8A16 green, "Fully specified; an AFK agent can pick this up"), ready-for-human (#1D76DB blue, "Needs human implementation"). wontfix already exists and completes the state set.

Migrations (9 open issues), then delete the source labels.

Deletions (no migration needed — zero open uses each): question, quick fix, urgent, area:admin, area:frontend, area:backend, area:infra. Deleting a label strips it from closed issues too (13 / 12 / 9 / ~27 historical uses respectively); we accept the history loss. Area labels are dropped because nothing routes by area — only 6 of 83 open issues carry one, and in the new workflow "where in the codebase" lives in the agent brief with actual file pointers.

Rename: NWAC Specifictenant:nwac via label edit (rename preserves the 5 existing issue associations). Other tenant:<slug> labels are created on demand when an issue actually needs one, not pre-created.

Issue template updates (three files under the GitHub issue-template directory):

  • Bug report template: labels: bug, NEWlabels: bug, needs-triage.
  • Blank issue template: labels: NEWlabels: needs-triage.
  • Claude task template: labels: claudelabels: ready-for-agent (replacing a label that doesn't exist; a maintainer-authored Claude task is fully specified by construction).

Documentation: Update docs/agents/triage-labels.md — the mapping table is already canonical-to-canonical, but the paragraph claiming only wontfix exists becomes stale once labels are created. Because docs are drift-bound (drift.lock), run the drift check wrapper after edits and update drift links if needed.

Backlog triage, phased:

Conventions: every AI-posted triage comment or issue starts with the disclaimer line > *This was generated by AI during triage.* Every triaged issue carries exactly one category and one state; conflicting states get flagged to the maintainer rather than silently resolved.

Testing Decisions

This is a process/configuration change — nothing under the application source tree changes, so no Jest tests. Verification is against observable issue-tracker state via gh queries, which are the natural seams:

  • Label inventory seam: the repo label list matches the 14-label table exactly — no more, no fewer.
  • Migration seam: searching open issues for each legacy label (NEW, needs user feedback, needs-investigation, question, quick fix, urgent, area:*, NWAC Specific) returns zero results; the 9 migrated issues carry their target labels; the 5 former NWAC Specific issues carry tenant:nwac.
  • Template seam: creating a test issue from each of the three templates yields the intended labels (bug + needs-triage / needs-triage / ready-for-agent); the test issues are then closed.
  • Phase 1 exit criterion: a query for open issues lacking a category label returns zero, and a query for open issues lacking a state label returns zero.
  • Docs seam: the drift check wrapper (pnpm drift:check) passes after documentation and template edits.

Prior art: none needed — these are the same gh issue list/gh label list queries the triage workflow itself uses day-to-day.

Out of Scope

  • A priority:* label scheme (the ready-for-* queues plus oldest-first ordering cover current needs; revisit only if a real prioritization query emerges).
  • Pre-creating tenant:dvac / tenant:sac / tenant:snfac before an issue needs them.
  • Retroactively relabeling closed issues.
  • GitHub Actions automation to enforce label invariants (templates + periodic triage sessions are enough for now).
  • Project boards or milestone restructuring.
  • The individual triage outcomes of Phase 2 — each themed batch is its own working session with its own maintainer decisions; this PRD only establishes the vocabulary, the wiring, and the plan.
  • Renaming good first issue or changing how contributors are directed to it.

Further Notes

  • Label deletion is irreversible for closed-issue history; the deletions above were checked for open-issue usage (all zero) before being proposed.
  • Bulk label edits should be batched gently — the GitHub search API rate-limited during the investigation for this PRD, so the sweep should prefer gh issue list pagination over per-issue search queries.
  • .out-of-scope/ does not exist yet; it is created the first time an enhancement is closed wontfix.
  • Current backlog snapshot for reviewers: 83 open issues; 35 unlabeled; 14 with a category; 12 good first issue; 11 tech debt; 5 NEW; 5 NWAC Specific; 3 needs user feedback; oldest open issue dates to March 2025.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified; an AFK agent can pick this up

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions