Ruled: 5869334748 · letter B · 2026-09-28T11:56Z
Filing gate: ① a defect with a named landing site, finding class (b): a declared door that does not hold. The error-code ledger says these codes are 「Raised by os validate / os build」, and os validate raises them only when the author happened to call defineStack(). reach: was measured at the public door os validate.
Found by the os-dev round on #20332 (PR #20365; the report on #20332, out_of_scope_findings[0]). Filed by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
What happens (measured by the dev at 94e32023, relayed)
| config shape |
requires: ['triggers'] + a record_change flow |
os validate |
export default defineStack({ … }) |
refused at load |
exit 1, STACK_TRIGGER_CAPABILITY_REQUIRED |
export default { … } (a plain object) |
not refused |
exit 0, 「Validation passed」 |
packages/cli/src/commands/validate.ts step 2 runs only ObjectStackDefinitionSchema.safeParse.
- Every cross-field refusal that
defineStack runs is therefore reached only when the author called defineStack: the capability, namespace prefix, single app, hierarchy scope and trigger capability refusals.
os build (compile.ts) is not measured.
Why it matters
The error-code ledger (packages/spec/src/api/error-code-ledger.zod.ts) documents these codes as raised by os validate / os build. An AI-written or hand-written config that skips the helper passes the author-time door and then fails, or silently misbehaves, at deploy. That is the declared ≠ enforced shape, on the whole refusal family rather than on one arm.
Seam: spec:defineStack refusal family → runtime:packages/cli/src/commands/validate.ts step 2 (and, unmeasured, compile.ts).
What the fix is (for the dispatch to confirm)
- One judge, both doors.
os validate (and os build) run the same cross-field refusals defineStack runs, on whatever the config exports: call the exported refusal pass on the parsed definition, not only the schema parse.
- Pin it: the same stack as
defineStack({…}) and as a plain object gives the same code and exit at os validate, for each refusal in the family.
- Census the example and template configs for a plain-object export. Expected:
defineStack everywhere, but measure it.
Dedupe
A local scan of every open and recently closed objectstack issue and PR for plain object.*(validate|defineStack)|without defineStack|defineStack.*(not called|skipped|only when)|os validate.*(plain|export default)|ObjectStackDefinitionSchema\.safeParse finds 4 hits: PR #20365 (this card's source), PR #20266, PR #20229 and PR #20125. None carries the door gap.
Dedupe words: os validate plain object config skips defineStack refusal · defineStack cross-field refusals only when defineStack called · validate without defineStack capability refusal
Ruled: 5869334748 · letter B · 2026-09-28T11:56Z
Filing gate: ① a defect with a named landing site, finding class (b): a declared door that does not hold. The error-code ledger says these codes are 「Raised by
os validate/os build」, andos validateraises them only when the author happened to calldefineStack().reach:was measured at the public dooros validate.Found by the
os-devround on #20332 (PR #20365; the report on #20332,out_of_scope_findings[0]). Filed by thedomain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.What happens (measured by the dev at
94e32023, relayed)requires: ['triggers']+ arecord_changeflowos validateexport default defineStack({ … })STACK_TRIGGER_CAPABILITY_REQUIREDexport default { … }(a plain object)packages/cli/src/commands/validate.tsstep 2 runs onlyObjectStackDefinitionSchema.safeParse.defineStackruns is therefore reached only when the author calleddefineStack: the capability, namespace prefix, single app, hierarchy scope and trigger capability refusals.os build(compile.ts) is not measured.Why it matters
The error-code ledger (
packages/spec/src/api/error-code-ledger.zod.ts) documents these codes as raised byos validate/os build. An AI-written or hand-written config that skips the helper passes the author-time door and then fails, or silently misbehaves, at deploy. That is the declared ≠ enforced shape, on the whole refusal family rather than on one arm.Seam:
spec:defineStackrefusal family →runtime:packages/cli/src/commands/validate.tsstep 2 (and, unmeasured,compile.ts).What the fix is (for the dispatch to confirm)
os validate(andos build) run the same cross-field refusalsdefineStackruns, on whatever the config exports: call the exported refusal pass on the parsed definition, not only the schema parse.defineStack({…})and as a plain object gives the same code and exit atos validate, for each refusal in the family.defineStackeverywhere, but measure it.Dedupe
A local scan of every open and recently closed objectstack issue and PR for
plain object.*(validate|defineStack)|without defineStack|defineStack.*(not called|skipped|only when)|os validate.*(plain|export default)|ObjectStackDefinitionSchema\.safeParsefinds 4 hits: PR #20365 (this card's source), PR #20266, PR #20229 and PR #20125. None carries the door gap.Dedupe words:
os validate plain object config skips defineStack refusal·defineStack cross-field refusals only when defineStack called·validate without defineStack capability refusal