You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spec): hold the #4001 strictness ledger to the code it describes (#4232)
The ledger is the campaign's map — which z.object sites are authorable (the
.strict() ratchet target), which are wire, which are deliberately open. Every
step reads it to pick the next move, and nothing kept it honest. It went stale
twice in one week: a classification verification disproved (hook.zod.ts carried
a blanket `authorable (p)` covering a runtime shape, #4207), and a "next step"
that had shipped months earlier (the unknown-key warning layer, #4218), which
sent the next reader off to rebuild something already in production.
A map that drifts is worse than no map, because it gets followed.
CHECKS. Site counts (the ledger states its own method — "z.object( occurrences
per file" — so every number is verifiable); coverage (every *.zod.ts with sites
in a triaged directory needs a row); section totals; and that a row claiming
"strict as of" names a file that really contains .strict().
The Class column is deliberately NOT checked. Authorable vs wire vs open is a
judgement about who writes the input, and this campaign's rule is
verify-before-tightening — encoding it would automate exactly the call that must
stay human. The gate protects the arithmetic and coverage so that judgement is
always made against current code.
Zero-site files are skipped: five of the six the first run flagged hold no
z.object at all (enum/token modules). Not a hole — the day one grows its first
z.object( it becomes undeclared and the gate says so.
FIRST RUN: 11 DRIFTS, in a file being actively edited by the campaign that owns
it. Six counts had moved (ui/app.zod.ts 11 → 18, ui/touch.zod.ts 4 → 7,
ui/action.zod.ts 8 → 9, ui/view.zod.ts 51 → 50, ui/responsive.zod.ts 6 → 4,
automation/flow.zod.ts 12 → 11), two section totals no longer summed, and
automation/io-node-config.zod.ts had no row. The app.zod.ts gap was
self-inflicted: the app step (#4165) added seven schemas and updated the row's
prose without touching its count.
Then it worked for real before merging: main landed
automation/builtin-node-config.zod.ts (#4045/#4228, eight sites), and merging
main turned the gate red on a branch whose own diff touches no schema. Now
classified. Every pre-existing count survived that merge unchanged, so the
failure was exactly as narrow as it should have been.
Verified the gate bites rather than just passes: a moved count fails (plus its
section total), a deleted row resurfaces as an undeclared file, and stripping
.strict() from approval.zod.ts fails its "strict as of" claim.
Refs #4001
|`app.zod.ts`|11| authorable |**strict as of #4001 PR B** — `AppSchema` + branding / area / context-selector / contribution, and the nav-item union converted to `z.discriminatedUnion('type', …)` (the union-error question, settled empirically: matched-branch-only errors, exact recursive paths, `toJSONSchema` clean). Per-target `params` stay open. PR A (#4142) tombstoned the seven audit-dead keys first |
140
+
|`app.zod.ts`|18| authorable |**strict as of #4001 PR B** — `AppSchema` + branding / area / context-selector / contribution, and the nav-item union converted to `z.discriminatedUnion('type', …)` (the union-error question, settled empirically: matched-branch-only errors, exact recursive paths, `toJSONSchema` clean). Per-target `params` stay open. PR A (#4142) tombstoned the seven audit-dead keys first |
|`approval.zod.ts`| 4 | authorable |**strict as of #4001 step 3** — all four authoring schemas (node config / approver / escalation / decision-output). The published JSON schema carries `additionalProperties: false` into the Studio form AND `registerFlow()` config validation (#4027/#4040), so an unknown key in an approval node's `config` is rejected at registration too — verified: `z.toJSONSchema` on the strict lazySchema does not throw (#3746 hazard checked) |
|`io-node-config.zod.ts`| 2 | authorable |`NotifyConfigSchema` / `HttpConfigSchema` (#4045) — the sibling contracts that validate the **open**`config` slot on flow `notify` / `http` nodes. Authored per-node, so the open-slot exemption above does not extend to them; candidate once the executors' own drift is verified |
182
+
|`builtin-node-config.zod.ts`| 8 | authorable | Same family (#4045): the CRUD quartet, `screen`, `map`. Written from what the executors read rather than from the descriptors' `configSchema` literals, and reconciled bidirectionally by `builtin-node-form-zod-ledger.test.ts` — so unlike most rows here, this one already has a drift check of its own. Same candidacy note as `io-node-config`|
0 commit comments