Skip to content

T-WPBJ-labels-sdlc-stage-stage-sdlc-auto-stage-apply-manages-the

State: closed/done · Impact: medium · Complexity: medium

sdlc:stage/<stage> labels position, sdlc:auto/<stage> sets the autonomy ceiling; apply manages the label vocabulary on the repo. Design: D-0019-sdlc-chain-stages-and-labels.

  1. Add gh label support to @sksizer/easy-gh (packages/ts/easy-gh/): verbs.ts gains argv builders + JSON parsers for label list (gh label list --json name,color,description), label create (gh label create <name> --color <hex> --description <text>) and label edit (gh label edit <name> --color <hex> --description <text>); sync.ts’s Gh class gains labelList() (query, returns Label[] | null), createLabel() and editLabel() (mutations, throw CommandFailed on non-zero exit, same tri-modal pattern as createPr/editPr); types.ts’s existing (currently unused) Label type becomes the real return shape.
  2. Add solutions/ontological/lib/services/apply/labels.ts implementing the Applier interface (lib/services/apply/types.ts): name: 'labels'. The canonical 22-label vocabulary is derived, not hand-listed — import CHAIN_STAGE_NAMES from lib/config/chain.ts (landed by T-8JJE; coordinate merge order, or take a short-lived local copy if T-8JJE hasn’t landed yet and switch to the import once it has) and build sdlc:stage/<name> + sdlc:auto/<name> for each. plan(ctx) calls new Gh(ctx.projectRoot, { runner: ctx.gh }).labelList(), diffs the live label set against the vocabulary (by name; a name-color-or-description mismatch is an update Change, a missing name is a create Change), and returns Change[] — never a remove (the applier does not delete labels it doesn’t own, including a repo’s pre-existing, non-sdlc:-prefixed labels). apply(ctx, changes) realizes exactly the changes plan returned, via createLabel/editLabel.
  3. Register the applier: add 'labels' to ApplierName and APPLIER_NAMES (lib/config/meta.ts), add it to the APPLIERS map in lib/services/apply/registry.ts. No new sdlc.yaml config key is needed — the vocabulary has one source of truth (CHAIN_STAGE_NAMES), not a project-editable list.
  4. Pick a small, fixed, deterministic color scheme (documented as a comment in labels.ts, not user-configurable): one hex per family (e.g. a blue for every sdlc:stage/*, an orange for every sdlc:auto/*) — the exact stage/ceiling within a family is carried by the label name, not the color, so one color per family is sufficient and keeps the diff logic simple.
  5. Add solutions/ontological/lib/services/apply/labels.test.ts following hooks.test.ts’s direct-applier-call pattern: construct a ctx with a fake gh CommandRunner (a stub .run(argv, opts) returning canned gh label list --json ... output, recording calls made) — no real gh/network. Cover: empty repo (all 22 as create), a repo with some labels already correct (only the missing/mismatched ones as changes), and apply() issuing exactly the argv plan() promised for each Change kind.
  6. sdlc apply --only labels --check / --dry-run exercise the new applier through the existing generic apply CLI surface (no new flags needed — --only already takes an applier name).
AreaNote
packages/ts/easy-gh/verbs.tsNew label list/label create/label edit argv builders + parsers
packages/ts/easy-gh/sync.tsNew Gh.labelList/createLabel/editLabel methods
packages/ts/easy-gh/types.tsWire the existing Label type to real use
solutions/ontological/lib/services/apply/labels.tsNew applier: plan/apply for the 22-label vocabulary
solutions/ontological/lib/services/apply/registry.tsRegister the labels applier
solutions/ontological/lib/config/meta.tsAdd 'labels' to APPLIER_NAMES
  • AC-1: sdlc apply --only labels --check against a fixture with no sdlc:* labels reports all 22 as pending (create), and exits 1 (the check convention already established by the other appliers).
  • AC-2: Re-running plan() against a fixture where all 22 already exist with the correct color/description returns zero changes (idempotent).
  • AC-3: apply() never emits a remove Change and never calls a delete/remove gh label verb, even when the fixture’s live label set has extra, non-sdlc:-prefixed labels.
  • AC-4: bun test solutions/ontological/lib/services/apply/labels.test.ts passes using a fake ctx.gh runner only — no real gh invocation.
  • Wiring label reads/writes into actual stage transitions — that is the issues loop’s job (T-0AKS), which relabels an issue after a successful stage dispatch. This task only makes the vocabulary exist and be manageable via apply.
  • A user-configurable label color scheme or a project-level opt-out of specific labels.
  • solutions/ontological/lib/config/chain.ts (T-8JJE) for CHAIN_STAGE_NAMES, the single source of truth for the 22 label names. If T-8JJE has not landed yet when this task starts, take a short-lived local copy of the 11 stage names and switch to the import once it lands — never hand-maintain two separate stage-name lists past that point.

← Back to Tasks