Skip to content

T-8JJE-the-sdlc-chain-decision-doc-chain-config-binding-stages-to

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

A decision doc plus chain: config for the SDLC chain. Stages: capture -> triage -> define -> ready -> implement -> check -> judge -> review -> respond -> merge -> close-out, each bound to a workflow (or explicitly bound to none, for a checkpoint stage). See D-0019-sdlc-chain-stages-and-labels for the full design (stage table, workflow bindings, rationale) — this task lands the config side of that decision.

  1. Add solutions/ontological/lib/config/chain.ts, mirroring lib/config/workflows.ts’s shape:
    • CHAIN_STAGE_NAMES — the fixed, ordered 11-name tuple (capture, triage, define, ready, implement, check, judge, review, respond, merge, close-out).
    • ChainStageNameSchema = z.enum(CHAIN_STAGE_NAMES).
    • DEFAULT_CHAIN_BINDINGS: Record<ChainStageName, string | null> — the built-in workflow name per stage from D-0019’s table (define, implement, check, judge, review -> 'pr-review', respond -> 'pr-respond', close-out; capture/triage/ ready/merge -> null).
    • resolveChain(config) — returns the ordered 11-entry { name, workflow }[], applying any per-stage workflow override from sdlc.yaml’s chain.stages over the default binding. A project can only override the workflow value of an existing stage name — it cannot add, remove, or reorder stages (schema rejects an unknown key under chain.stages).
  2. Replace the strict-empty chain stub in solutions/ontological/lib/config/load.ts (currently ~line 1098, z.object({}).strict().optional() with the “no field is defined yet” description) with a real shape: chain: z.object({ stages: z.partialRecord(ChainStageNameSchema, z.object({ workflow: z.string().trim().min(1).nullable() }).strict()) .optional() }).strict().optional(), updating the .describe() text (drop “no field is defined yet”) and keeping the existing .meta(keyMeta({...})) block’s category/layers/applies_via/ runs_in, updating consumers to point at lib/config/chain.ts#resolveChain and the (Phase-7, this milestone’s other tasks) issues-loop/labels-applier consumers.
  3. Update solutions/ontological/conventions/sdlc-yaml.md’s reserved- sections table/entry for chain to reflect the real shape (remove the “no field defined yet” language, add a short example mirroring the workflows: override example already in that doc).
  4. Write the decision doc (done — D-0019-sdlc-chain-stages-and-labels — this task’s remaining work is the config landing to match it) and link it from this task’s related frontmatter once merged.
  5. Add lib/config/chain.test.ts covering: default resolution (no chain: key -> the 11 built-in bindings, in order), a valid per-stage override (chain.stages.review.workflow: 'custom-review' resolves), an explicit-null override on a bound stage (turns a real workflow into a checkpoint), and a rejected unknown stage name under chain.stages (schema validation error, not a silent no-op).
  6. Ship the review stage’s default binding, pr-review, as a real skill at solutions/ontological/plugin/plugins/sdlc/skills/pr-review/pr-review.md (this is the one built-in workflow name with no backing skill on disk today — lib/config/workflows.ts’s pr-review entry and the atlas both flag it). Follow the pr-check/pr-respond vault-note convention (frontmatter: description, allowed-tools, ap-kind: skill, ap-plugin: sdlc; numbered steps; a Failure modes and a Notes section). Contract: given a PR number, read its diff, dispatch an adversarial review under the engine named by orchestrator.review.engine (lib/config/load.ts, default 'claude' — already read by the prs/merges ticks, previously inert for lack of this skill) applying the S-0017 rubric (S-0017-code-review-rubric) as its lens, and post the findings as review comments on the PR (reuse pr-respond’s existing comment- posting mechanism rather than inventing a second one). Emit a deterministic terminal marker, matching pr-check/pr-respond convention.
  7. After authoring the skill note, rebuild the plugin: cargo run -q -p agent-pants -- build --yes --config solutions/ontological/agent-pants.yaml, and commit the regenerated .claude-plugin/manifest output alongside the vault note.
AreaNote
docs/planning/decisions/D-0019-sdlc-chain-stages-and-labels.mdThe chain decision doc (already written)
solutions/ontological/lib/config/chain.tsNew: stage list, default bindings, resolveChain
solutions/ontological/lib/config/load.tsReplace the strict-empty chain stub (~line 1098) with the real schema
solutions/ontological/conventions/sdlc-yaml.mdDocument the real chain: shape (reserved-sections table + an example)
solutions/ontological/plugin/plugins/sdlc/skills/pr-review/pr-review.mdNew skill: closes the review stage’s workflow gap
solutions/ontological/agent-pants.yaml / .claude-pluginPlugin rebuild after the new skill note lands
  • AC-1: The decision doc (D-0019-sdlc-chain-stages-and-labels) lists all 11 stages in order with their workflow binding (or explicit none).
  • AC-2: chain: config validates and resolveChain() returns all 11 stages, each naming a workflow (a string) or explicitly null for a checkpoint stage.
  • AC-3: An unknown stage name under chain.stages in sdlc.yaml fails config validation rather than being silently ignored.
  • AC-4: bun test solutions/ontological/lib/config/chain.test.ts passes, covering default resolution, a per-stage override, an explicit-null override, and the unknown-stage-name rejection.
  • AC-5: solutions/ontological/plugin/plugins/sdlc/skills/pr-review/pr-review.md exists, follows the pr-check/pr-respond vault-note conventions, and cargo run -q -p agent-pants -- check --config solutions/ontological/agent-pants.yaml (the check verb’s drift gate) reports no drift after the rebuild.
  • The labels applier and the issues loop that will consume resolveChain() (T-WPBJ, T-0AKS).
  • Any auto-merge workflow for the merge checkpoint (D-0019’s Open questions).
  • sync --fix / auto-resolving label-task conflicts (T-3YQO, deferred per D-0019 Option B).
  • none

← Back to Tasks