Files
Gitea-Tools/docs/label-taxonomy.md
T
sysadminandClaude Opus 4.8 f34319852e feat: lifecycle role/hazard labels and canonical state mapping (#603)
Add orthogonal role:* (single-active owner) and hazard:* (additive warning)
lifecycle labels plus status:changes-requested, folding the #603 state:*
vocabulary into the canonical status:* set rather than a conflicting parallel
prefix.

- issue_workflow_labels.py: ROLE_/HAZARD_ specs + frozensets; role/hazard
  transition maps and helpers (transition_role_labels, add/clear_hazard_label,
  canonical_role_label, canonical_hazard_label, is_discussion,
  is_implementation_candidate, requires_blocking_reason); state:* -> status:*
  synonym transitions; assess_issue_labels surfaces role/hazard dims and flags
  multiple active role labels
- docs/label-taxonomy.md: role, hazard, state->canonical migration, and
  allocator cross-check sections
- tests: role/hazard/discussion/blocking-reason/state-synonym coverage
- manage_labels.py seeds the new labels automatically via CANONICAL_LABEL_SPECS

Labels remain advisory; control-plane leases (#601) and live PR state stay the
source of truth for mutations (#603 AC2).

Closes #603

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-10 16:17:31 -04:00

166 lines
6.4 KiB
Markdown

# Label Taxonomy
This document defines the canonical issue labels used by MCP workflows.
Every issue should carry:
- one `type:*` label
- one `status:*` label
Discussion-only issues must carry `type:discussion`.
## Issue Type Labels
| Label | Use |
| --- | --- |
| `type:bug` | Bug or defect |
| `type:feature` | Feature or enhancement |
| `type:process` | Process or policy work |
| `type:workflow` | Workflow automation or guidance |
| `type:guardrail` | Safety gate or guardrail |
| `type:docs` | Documentation work |
| `type:test` | Tests or test infrastructure |
| `type:discussion` | Discussion-only issue |
| `type:umbrella` | Umbrella or tracker issue |
| `type:cleanup` | Cleanup or hygiene work |
## Workflow Status Labels
Only one `status:*` label should be active on an issue at a time. When an issue
moves forward, tooling must remove the old `status:*` label and apply the new
one.
| Label | Use |
| --- | --- |
| `status:triage` | Issue needs triage |
| `status:ready` | Issue is ready for work |
| `status:claimed` | Issue is claimed |
| `status:in-progress` | Issue is being worked on |
| `status:blocked` | Issue is blocked |
| `status:needs-review` | Issue work needs review |
| `status:pr-open` | A linked PR is open |
| `status:changes-requested` | Reviewer requested changes on the linked PR |
| `status:approved` | Linked PR is approved |
| `status:merged` | Linked PR is merged |
| `status:reconcile` | Issue needs reconciliation |
| `status:done` | Issue workflow is complete |
| `status:duplicate` | Issue is a duplicate |
| `status:wontfix` | Issue will not be fixed |
## Role Ownership Labels (#603)
A single `role:*` label shows which workflow role currently owns the item. It is
advisory visibility only — the control-plane lease (#601) is the source of truth
for mutation authority. Only one `role:*` label is active at a time; tooling
replaces it on handoff via `transition_role_labels`.
| Label | Use |
| --- | --- |
| `role:author` | Author currently owns the item |
| `role:reviewer` | Reviewer currently owns the item |
| `role:merger` | Merger currently owns the item |
## Hazard Labels (#603)
Hazard labels are orthogonal warning flags. Unlike `status:*` and `role:*`,
**more than one hazard may be active at once**, and a hazard never substitutes
for a live lease / PR-state check. Add/remove with `add_hazard_label` /
`clear_hazard_label`.
| Label | Use |
| --- | --- |
| `hazard:stale-lease` | A stale or expired lease references this item |
| `hazard:workflow-contaminated` | Session/workflow state is contaminated; do not mutate |
| `hazard:conflicted` | Linked PR has merge conflicts |
| `hazard:root-mutation` | Work was mutated in the project root checkout |
| `hazard:manual-state` | Session or lease state was edited manually |
| `hazard:terminal-blocker` | A terminal review/merge lock blocks progress (#332/#602) |
Any item that carries `status:blocked` or any `hazard:*` flag must also have a
blocking-reason / next-action comment (`requires_blocking_reason`).
## `state:*` → canonical mapping (#603 migration)
Issue #603 proposed a parallel `state:*` vocabulary. To avoid a conflicting
second lifecycle prefix, those requested states are folded into the existing
canonical labels rather than introduced as `state:*`. `state:*` is **not** a
supported prefix; use the canonical label on the right.
| Requested `state:*` | Canonical label |
| --- | --- |
| `state:needs-triage` | `status:triage` |
| `state:claimed` | `status:claimed` |
| `state:authoring` | `status:in-progress` |
| `state:needs-review` | `status:needs-review` |
| `state:reviewing` | `status:needs-review` |
| `state:changes-requested` | `status:changes-requested` |
| `state:approved` | `status:approved` |
| `state:merge-ready` | `status:approved` |
| `state:merged` | `status:merged` |
| `state:blocked` | `status:blocked` |
| `state:terminal-blocker` | `hazard:terminal-blocker` |
| `state:abandoned` | `status:wontfix` |
The transition helpers accept these names as synonyms (e.g.
`canonical_status_label("authoring")``status:in-progress`), so callers may use
the #603 wording while a single canonical status stays active.
## Allocator Cross-Check (#603)
Labels are advisory queue hints. The work allocator (#600/#613) uses labels as
one signal but **cross-checks live leases and PR state** and never trusts labels
alone. Discussion issues (`type:discussion`) are excluded from implementation
queues (`is_implementation_candidate`) unless a controller explicitly selects
them.
## Transition Rules
Suggested lifecycle:
1. New issue created: `status:triage` or `status:ready`
2. Issue selected by an author: `status:claimed`
3. Author starts work: `status:in-progress`
4. Work is blocked: `status:blocked`
5. PR opened: `status:pr-open`
6. PR approved: `status:approved`
7. PR merged but issue still needs closure/reconciliation: `status:reconcile`
8. Issue fully complete: `status:done`
9. Duplicate issue: `status:duplicate`
10. Won't-fix issue: `status:wontfix`
The helper module `issue_workflow_labels.py` is the source of truth for the
canonical label specs and status transition replacement behavior.
## Discussion Issues
Discussion issues must be labeled `type:discussion`.
A discussion issue should not be treated as implementation-ready unless it also
has a clear implementation status and next action.
If a discussion produces implementation work, either:
1. convert the discussion issue into an implementation issue by changing labels
and adding acceptance criteria, or
2. create child implementation issues and leave the discussion issue as
`type:discussion`.
## Tooling
- `manage_labels.py --create-labels` creates the canonical `type:*` and
`status:*` labels.
- `gitea_create_issue` recommends `type:*` and `status:*` labels when missing
and can apply supplied label names.
- `gitea_mark_issue(..., action="start")` replaces old `status:*` labels with
`status:in-progress`.
- `gitea_create_pr` fails closed before PR creation if `status:pr-open` cannot
be applied to the locked issue, then applies it after the PR is created.
- `gitea_set_issue_labels` accepts an explicit `worktree_path` so author
sessions can satisfy the branches-only mutation guard while changing labels.
## Existing Non-Workflow Labels
Existing non-workflow labels such as `mcp`, `workflow`, `labels`, `tracker`,
`jenkins`, `glitchtip`, `documentation`, and `testing` remain valid topical
labels. They do not replace the required `type:*` and `status:*` labels.