Skip to content

T-MU9Z-meta-definition-zod-4-meta-on-every-sdlc-yaml-key-enforced

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

Every top-level key of SdlcConfigSchema carries a typed Zod 4 .meta() block (category, consumers, layers, applies_via, runs_in) next to its .describe(), enforced by a completeness test, so later Phase 5 work (sdlc config list|explain|get|set, the generated sdlc.yaml reference, sdlc apply appliers, doctor drift) can read it as data. The sections the sdlc 1.0 plan names (chain, hooks, harness, sessions, notify, mcp, knowledge, issues, usage) exist as optional keys. Trust stays machine-local.

  1. New lib/config/meta.ts: closed enums CONFIG_CATEGORIES (lifecycle/automation/integration/planning/infrastructure), CONFIG_LAYERS (project/local/machine/subtree), APPLIER_NAMES (hooks/harness/mcp), RUN_CONTEXTS (cli/hook/loop/session/ci); AppliesViaSchema = read | apply:<applier> (template literal); consumers are <path>.ts#<symbol> (relative to the sdlc source root) or planned:<note> for reserved sections. ConfigKeyMetaSchema (strict) and RegisteredKeyMetaSchema (plus the merged description); keyMeta() types a call site; checkConfigMeta(shape) returns one issue per bad key; readConfigMeta(shape) returns all metas or throws; isReserved, applierOf helpers.
  2. load.ts: .meta(keyMeta({...})) as the last call on every top-level key, with consumers taken from a grep of the real readers. Layers follow the loaders: lease_authority is project only (read raw from sdlc.yaml), paths/repos/checkout add machine, verify adds subtree. Add the nine new optional sections: strict empty objects for the reserved ones (chain, sessions, notify, knowledge, issues, usage), hooks as a record(string, unknown) placeholder (apply:hooks), harness: { targets?: string[] } (apply:harness), mcp: { allow: string[] = [], deny: string[] = [] } (apply:mcp). Nested orchestrator fields that lacked a .describe() get one; meta stays top-level only (nested fields inherit their section’s).
  3. notify: the working notifier stays under orchestrator.notify (consumed by lib/services/notify/dispatch.ts); top-level notify is a reserved stub Phase 8 fills and absorbs it into. sessions is a stub: session launch reads only host.default today.
  4. scaffold.ts: an optional section with no default renders commented out, so the scaffold still round-trips to SdlcConfigSchema.parse({}).
  5. meta.test.ts: completeness, negative cases, and truthfulness checks.
  6. conventions/sdlc-yaml.md: a Key meta section, a reserved-sections table, and stale-prose fixes (orchestrator.review.command, zod-to-json-schema, additionalProperties).
AreaNote
solutions/ontological/lib/config/meta.tsNew: meta schema, types, checker
solutions/ontological/lib/config/meta.test.tsNew: completeness + truthfulness tests
solutions/ontological/lib/config/load.ts.meta() on every key; nine new sections; nested describes
solutions/ontological/lib/config/scaffold.tsOptional no-default sections render commented
solutions/ontological/lib/config/index.tsRe-export the meta surface
solutions/ontological/conventions/sdlc-yaml.mdKey meta + reserved sections docs
  • AC-1: Every top-level SdlcConfigSchema key carries a .meta() block with category/consumers/layers/applies_via/runs_in and a description (checkConfigMeta(SdlcConfigSchema.shape) returns []).
  • AC-2: A completeness test fails when a key lacks .meta(), has meta set before a wrapping call, lacks a description, or carries malformed meta (bad enum, empty or duplicate list, bad consumer, unknown applier, unknown field).
  • AC-3: Every <path>#<symbol> consumer names an existing file that contains the symbol; the machine layer is claimed by exactly the keys MachineConfigSchema declares; no trust key is in SdlcConfigSchema.
  • AC-4: chain, hooks, harness, sessions, notify, mcp, knowledge, issues, usage exist, optional; mcp is exactly { allow: string[], deny: string[] } defaulting to []; reserved stubs reject any key.
  • AC-5: Existing config tests, the scaffold round-trip, bunx tsc --noEmit and the repo’s own sdlc.yaml (preflight on config get-verbs) stay green.
  • The sdlc config list|explain|get|set CLI, sdlc apply and its appliers, the hooks step grammar (T-F8NL), and generated reference docs — later Phase 5 tasks consume this meta.
  • none

← Back to Tasks