# Label Taxonomy Ownership

Configulator synthesizes a canonical GitHub label set for every consuming
project via the sync-labels workflow. This document defines **who owns
which label families** so the taxonomy stays coherent as more agent
bundles are ported.

## Three ownership tiers

Labels fall into one of three tiers based on who is responsible for
defining them, maintaining their colors and descriptions, and keeping
them in sync with the agent rules that depend on them.

### Tier 1 — Configulator core labels

Defined statically in `src/workflows/sync-labels.ts` and applied to
every project that uses `addSyncLabelsWorkflow`. These are the labels
that the orchestrator, issue-worker, and PR automation depend on
regardless of which specific agent bundles a project enables.

Families in this tier:

- **`status:*`** — workflow state (`ready`, `in-progress`,
  `ready-for-review`, `blocked`, `done`, `deferred`,
  `needs-attention`). Required by every agent that transitions issues
  through the workflow.
- **`priority:*`** — scheduling priority (`critical`, `high`, `medium`,
  `low`, `trivial`). Required by the orchestrator to sequence work.
- **`type:*`** — conventional-commit work type (`feat`, `fix`, `docs`,
  `chore`, `refactor`, `style`, `perf`, `test`, `build`, `ci`,
  `revert`, `release`, `hotfix`). Matches the PR title convention so
  automation can derive one from the other.

These are exported as `DEFAULT_STATUS_LABELS`, `DEFAULT_PRIORITY_LABELS`,
and `DEFAULT_TYPE_LABELS` and are always merged in.

### Tier 2 — Agent-bundle labels

Owned by the individual agent bundle that depends on them. A bundle
should contribute only the labels its rules reference — typically a
small family of phase labels used by a multi-phase workflow.

Examples seen in a reference taxonomy from a downstream project:

- `meeting:extract`, `meeting:notes`, `meeting:draft`, `meeting:link`
  — owned by the meeting-analysis bundle
- `research:scope`, `research:search`, `research:synthesize`,
  `research:verify` — owned by a research-pipeline bundle
- `bcm:outline`, `bcm:scaffold`, `bcm:context`, `bcm:connect` —
  owned by a bcm-writer bundle

Bundle-contributed labels are scoped: a project that does not enable
the meeting-analysis bundle does not get `meeting:*` labels. This
keeps the label list per-project aligned with the workflows that
project actually runs.

A bundle declares its labels via the optional `labels` field on the
`AgentRuleBundle` interface. When `AgentConfig` is enabled on a
project, `addSyncLabelsWorkflow` merges labels from every active
bundle into `.github/labels.yml` automatically.

```ts
export const meetingAnalysisBundle: AgentRuleBundle = {
  name: "meeting-analysis",
  // ...
  labels: [
    { name: "meeting:extract", color: "C5DEF5", description: "..." },
    { name: "meeting:notes",   color: "BFDADC", description: "..." },
    { name: "meeting:draft",   color: "D4C5F9", description: "..." },
    { name: "meeting:link",    color: "FEF2C0", description: "..." },
  ],
};
```

Consumers can still override a bundle-contributed label's color or
description by supplying the same label name via
`SyncLabelsOptions.labels` — the consumer entry wins.

### Tier 3 — Consumer-project labels

Owned by the end project. These are domain-specific categories
configulator cannot reasonably predict. Examples from a reference
downstream project:

- `area:requirements`, `area:business-strategy`, `area:references`,
  `area:product`, `area:architecture` — area labels tied to a
  directory layout unique to that project

Consumers add these through the `labels` option on
`addSyncLabelsWorkflow` / `SyncLabelsOptions.labels`.

## How the tiers compose

At synth time, the final label set written to `.github/labels.yml` is:

```
DEFAULT_STATUS_LABELS
  ∪ DEFAULT_PRIORITY_LABELS
  ∪ DEFAULT_TYPE_LABELS
  ∪ (labels contributed by enabled agent bundles)
  ∪ (labels provided by the consumer via options)
```

The sync-labels workflow then reconciles this set against the live
repo — creating missing labels, updating colors/descriptions, and
(if `deleteOtherLabels` is true, the default) removing any label that
is not in the file.

## Naming conventions

- Use lowercase, kebab-case label names.
- Use a family prefix followed by a colon: `family:name` (e.g.
  `status:ready`, `meeting:extract`).
- Keep descriptions short and action-oriented — they appear in the
  GitHub UI dropdown when applying labels.
- Pick distinct hex colors within a family so labels are scannable in
  the issue list. Related families (e.g. all `research:*`) should
  share a color gradient.

## When to add a new label family

Before adding a new family, check whether an existing one covers the
intent:

- Workflow state → `status:*`
- Scheduling order → `priority:*`
- Kind of change → `type:*`

A new family is warranted when it cross-cuts the existing ones and
is required by a specific agent's rules — for example, phase labels
that track which micro-session of a multi-phase agent an issue
belongs to.

## See also

- `docs/src/content/docs/audits/label-audit-308.md` — initial audit of configulator
  labels against a reference taxonomy from a downstream project
- `src/workflows/sync-labels.ts` — source of truth for the Tier 1
  default labels
