| name | labels-and-taxonomy |
|---|---|
| description | Use when adding, renaming, or retiring labels — taxonomy governance. |
| category | governance |
Labels are cheap to create and expensive to keep meaningful — every unused or duplicated label is a small tax on every triage session forever. This skill keeps .github/labels.yml as the one source of truth and the label set small enough to actually scan.
-
.github/labels.ymlis the source of truth. The GitHub UI is a projection of it, not an editable copy. Never create, rename, or recolor a label directly in the GitHub UI — edit the file, then sync:scripts/bootstrap.sh
A label that exists on GitHub but not in the file is drift; the file wins on the next sync (see
.github/PROJECT_FIELDS.md, "this file wins"). -
Single-home check before adding any label (ADR-0003): ask "does this fact already have a home?" — native issue type, a Project field, a milestone, or an existing label. If yes, do not add a label that duplicates it. Consult the authority map in
.github/PROJECT_FIELDS.mdfirst. -
Label budget: this template ships 14 labels. A healthy small repo stays under roughly 25. Label-count creep is the single most common taxonomy failure — it happens one "just this once" label at a time, never as one bad decision.
-
Add a label only if you will filter or automate on it. If you can't name the
gh issue list --labelquery or the workflow condition that would use it, it's documentation dressed up as taxonomy — write a sentence in the issue instead. -
Retiring a label is three steps, not one: remove it from
.github/labels.yml, delete it on GitHub (via the nextscripts/bootstrap.shsync orgh label delete), and note the removal in the PR description so the history is discoverable later. -
area:*labels are the intended adopter customization point. The starter set (area:docs,area:skills,area:ci,area:governance) exists to be renamed to the adopter's real domains — keep thearea:prefix so tooling and queries keep working, but the values are meant to change. -
Never encode workflow status in a label.
Backlog/Ready/In Progress/In Review/Blocked/Donebelongs to the ProjectStatusfield — that's a single field with defined transitions; N status labels would be N independently-driftable booleans on the same fact.
Add a label — edit the file, don't touch the UI:
# .github/labels.yml
- name: area:billing
color: 1d76db
description: Billing and payments domainscripts/bootstrap.sh # syncs GitHub labels to match the fileAudit for drift between the file and GitHub before assuming they match:
gh label list --json name,color,description --limit 200 > /tmp/github-labels.json
# diff against .github/labels.yml by eye or with a small scriptRetire a label cleanly:
# 1. remove the entry from .github/labels.yml
# 2. delete on GitHub
gh label delete "area:legacy-name" --yes
# 3. mention it in the PR body: "Retires area:legacy-name — superseded by area:billing"Check whether a candidate label already has a home before adding it:
grep -i "<the attribute you're about to label>" .github/PROJECT_FIELDS.md- Creating a label in the GitHub UI "just to unblock triage right now" — it silently diverges from
.github/labels.ymland gets wiped or conflicts on the next sync. - Adding a
status:*label set because a board view feels slow — that's a Project view problem, not a taxonomy problem; fix the view, not the labels. - A second
priorityortypefield appearing on the Project board that mirrors the labels — this is the exact ADR-0003 violation the contract file exists to catch in review. - Letting
area:*sprawl past a handful of values — if every PR needs a newarea:*label, the domains are sliced too fine; consolidate. - Deleting a label from GitHub without removing it from
.github/labels.ymlfirst — the next bootstrap run silently recreates it.
`.github/labels.yml`— the declarative label source of truth`.github/PROJECT_FIELDS.md`— the metadata single-home authority map`docs/adr/ADR-0003-metadata-single-home.md`— the rationale and rejected alternatives`scripts/bootstrap.sh`— syncs labels, Project fields, and repo settings from the declared source`skills/adr-writing/SKILL.md`— when a repeated labeling debate should become an ADR instead of a one-off decision