T-Y1L0-entities-validate-absorb
Status: closed/done · Impact: high · Complexity: medium
Fourteen skills gate every frontmatter edit on
validators/validate_frontmatter.ts. The op behind it exits 0 on
validation failure and lacks the shim’s 3-tier schema resolution, so a
naive codemod would silently green every gate. Absorb the shim’s full
contract into entities validate so the codemod becomes a one-line diff
per caller and validators/ can be deleted with no carve-out.
| Location | Role today |
|---|---|
plugin/validators/validate_frontmatter.ts | 3-tier resolution (--schema → type: → parent-dir basename + singularize); OK/FAIL <path> (schema: <name>) text; exit 0/1/2; --quiet, --list-types; entitiesDir defaults to the plugin’s entities dir |
plugin/lib/model/ops/validate.ts#handler | explicit-schema or entitiesDir+type: only; returns {failed} so the generated CLI exits 0 on failure; hidden: true; JSON only |
Proposed
Section titled “Proposed”The op gains the dir-basename + singularize tier, the entitiesDir
default, a cli.render hook reproducing the exact OK/FAIL + indented
at <loc>: + stderr-summary text, exit 1 when failed > 0, and
--quiet. The op is un-hidden. --list-types is dropped (zero SKILL.md
callers). The shim’s output is locked as golden BEFORE the absorb; the
shim file itself stays until T-YBKU-shim-deletion-guard deletes it.
Approach
Section titled “Approach”- Golden-snapshot the shim: pass, fail, mixed-type multi-file (task + backlog in one call), parse-error, and no-schema cases.
- Port the resolution tiers + entitiesDir default into the op handler.
- Add the
cli.renderhook (lands with T-NV49-op-path-substrate) reproducing text + exit shaping; keep--jsoncanonical. - Un-hide; add
--quietto the input schema. - Parity test:
bun run plugin/cli/sdlc.ts entities validate …vs the goldens, byte-identical.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/lib/model/ops/validate.ts | modify | resolution tiers, default, render hook, exit shaping, —quiet, un-hide |
plugin/lib/tests/ops_generic.test.ts | modify | absorb coverage |
plugin/lib/tests/ | modify | new CLI-spawned parity goldens |
plugin/validators/validate_frontmatter.ts | modify | none beyond comments — stays until T-YBKU-shim-deletion-guard |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: CLI parity goldens byte-match the shim, including the mixed-type multi-file call.
- AC-2:
sdlc entities validate <bad-file>exits 1;--jsonstill emits the validated JSON shape. - AC-3: a draft file with no
type:field indocs/planning/tasks/resolves to the task schema via the dir-basename tier. - AC-4: the op appears in
sdlc entities --help(un-hidden); fullbun testgreen.
Out of scope
Section titled “Out of scope”- Codemodding the 14 callers (T-QL5F-skill-prose-codemod).
- Deleting the shim (T-YBKU-shim-deletion-guard).
- The
baseflavor (validate_base) — unchanged.
Dependencies
Section titled “Dependencies”- T-NV49-op-path-substrate — the
cli.renderhook and exit shaping land there.
Discovery context
Section titled “Discovery context”- Resolved design question (e) in docs/plans/op-substrate-full-sweep.md: absorb-into-op chosen over retain-as-adapter; the op’s exit-0-on-failure was the disqualifier for a naive codemod.