Skip to content

T-OOOE-sdlc-yaml-config-cli-list-explain-get-set-run-apply-init-and

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

sdlc config list|explain|get|set (writing through yaml-splice), sdlc run, sdlc init, and the sdlc.yaml reference docs generated from schema plus meta. Everything reads the per-key .meta() T-MU9Z added, so a new key flows into every surface without an edit to the CLI.

sdlc apply [--dry-run] and drift reporting in doctor were part of this task’s original scope. They move to the apply framework work tracked under T-F8NL (Phase 5 brief C2), which builds the appliers those two depend on.

  1. Schema introspection (lib/config/introspect.ts): resolveKeyPath walks a dotted path through object fields and record values to the field schema, its own description, and its section’s meta; shapeOf renders a short type string from z.toJSONSchema; defaultOf is the schema’s own parse of undefined; nestedFields lists an object’s children.
  2. Span-preserving edits (lib/config/edit.ts): setPath/unsetPath reduce a nested path to yaml-splice’s top-level edits by cutting the parent’s block-mapping lines (located with the yaml package’s source ranges), dedenting, editing, re-indenting, and splicing back. A flow or null parent re-renders that section alone; a mapping emptied by unset is removed.
  3. Config service core (lib/services/config/config-file.ts): reads sdlc.yaml and sdlc.local.yaml fresh (not through loadConfig’s memo), reports a key’s source (local/project/default/unset), fails loudly on an invalid config, and writes one layer only after validating the merged result against SdlcConfigSchema.
  4. Ops (lib/services/config/ops/): list (grouped by category), explain, get (YAML text, --json, --layer), set (value parsed as YAML, apply hint when the section’s meta says apply:<x>), unset, init. get-verbs/set-verbs stay: /sdlc:find-verbs calls them.
  5. Reference docs (lib/config/reference.ts): a markdown page with a key table and one section per key (description, meta table, shape, default, nested field tables, recursing into object fields), registered as the sdlc-yaml artifact in lib/services/docs/generate.ts (default set, docs/sdlc-yaml-reference.md, listed in GENERATED_DOCS_ROOTS, excluded from rumdl like its siblings).
  6. sdlc init (config init): configStarterYaml in lib/config/scaffold.ts sets only detected verbs — check from an aggregate ci/check task or fmt-check/lint/typecheck/test (@sksizer/detect-runners, root-level tasks), setup from detectSetup — and comments out every other key with its description, grouped by category. Refuses an existing file without --force; --dry-run prints. sdlc project setup keeps writing the full configScaffoldYaml form.
  7. sdlc run (workflow run): runWorkflow from the step runner with a streaming verb seam (child output to stderr) and a trust-gate wrapper that rethrows a refusal so the command exits 21; the failing step’s exit code becomes the command’s. The step runner gained StepOutcome.exitCode and a command option for the trust message. --dry-run prints the resolved plan with each run: step’s verbs.
  8. Top-level verbs (cli/sdlc.ts TOP_LEVEL_VERBS): sdlc init and sdlc run dispatch to the config init / workflow run registry entries.
AreaNote
solutions/ontological/lib/config/introspect.tsNew: dotted-path resolution, shape, defaults
solutions/ontological/lib/config/edit.tsNew: span-preserving nested edits over yaml-splice
solutions/ontological/lib/config/reference.tsNew: generated sdlc.yaml reference
solutions/ontological/lib/config/scaffold.tsconfigStarterYaml for sdlc init
solutions/ontological/lib/services/config/config-file.tsNew: layer reads, source, validated writes
solutions/ontological/lib/services/config/ops/New ops: list, explain, get, set, unset, init
solutions/ontological/lib/services/workflow/ops/run.tsNew op: workflow run / sdlc run
solutions/ontological/lib/services/orchestrator/step-runner.tsexitCode on outcomes, command option
solutions/ontological/lib/services/docs/generate.tssdlc-yaml artifact
solutions/ontological/cli/sdlc.tsTop-level init / run
docs/sdlc-yaml-reference.mdGenerated, committed
.rumdl.tomlExclude the generated reference
  • AC-1: config set on a nested key of a commented, oddly spaced fixture changes exactly that value’s line (exact-output tests in lib/config/edit.test.ts and config_ops.test.ts); config unset likewise removes only that line.
  • AC-2: config set with a value the schema rejects exits SCHEMA_ERROR (14) and leaves the file byte-identical.
  • AC-3: config get prints the merged value and its source, --layer one file’s; config list groups every top-level key by category; config explain works on top-level and nested (orchestrator.max_implementations) keys with the nested description and inherited meta.
  • AC-4: sdlc docs generate writes docs/sdlc-yaml-reference.md deterministically from the live schema, and --check reports a missing or hand-edited copy as drift.
  • AC-5: sdlc init in a bun project detects bun install as setup and the gate scripts as check, refuses an existing file without --force, and writes nothing under --dry-run.
  • AC-6: sdlc run <workflow> --dry-run prints the resolved plan; a run: step executes its verb in a trusted repo; an untrusted repo exits 21 before any verb runs; a failing step’s exit code stops the run.
  • sdlc apply [--dry-run] and doctor drift reporting: T-F8NL (brief C2).
  • An interactive or host-attached session for skill:/prompt: steps under sdlc run: they use the step runner’s headless session launch path.
  • T-MU9Z (per-key .meta()).

← Back to Tasks