Found while implementing #14161 (ADR-0130 D4). Out of that card's scope, filed rather than fixed, and unassigned.
Measured, on origin/main682d03ba7, against the built packages/spec/dist
const{ ObjectStackDefinitionSchema }=require('./packages/spec/dist/index.js');constr=ObjectStackDefinitionSchema.safeParse({manifest: {id:'com.example.p',name:'p',version:'1.0.0',type:'app',namesapce:'p',zzzBogusManifestKey: 1},});parse success : true
bogus key survived : false
typo key survived : false
namespace value : undefined
Both the typo (namesapce) and an arbitrary unknown key parse green and are dropped — not preserved, not reported. manifest.namespace is then undefined, and the author is told nothing.
Why this is not a nit
This is the #8687 failure class exactly one level below the door #8687 closed. The top-level stack surface is now strictObject, so namesapce:at the top level is a named refusal carrying a rename suggestion. One level down, inside manifest: — one of the most-authored objects in the product, present in every objectstack.config.ts — the same typo is silent.
And the dropped key is load-bearing rather than decorative:
${namespace}_${shortName} is the kernel-validated object-name rule, and under ADR-0129 D1–D2 the object nameis the table name, the REST path, the formula token and the saved-view key;- the install-time namespace gate (ADR-0048 §3.2, and the co-ownership correction in ADR-0130 D1/D3) reads
manifest.namespace; MAP_SUPPORTED_FIELDS / datasource routing and several datasourceMapping rules key on the namespace.
So the observable symptom of a single transposed letter is not "a warning is missing" — it is objects landing under a different name than the author wrote, decided at parse time with exit 0.
Where the map says otherwise
docs/audits/2026-07-unknown-key-strictness-ledger.md:1321 classifies the whole directory in one cell:
| `kernel/` | wire | plugin/kernel contracts, code-to-code |
kernel/manifest.zod.ts is covered by that verdict, and for most of the directory it is right. But manifest: is not code-to-code — it is a hand-authored block in every project's stack source, in defineStack, in the Studio surfaces and in the artifact os build writes.
⚠️ That makes this the same shape as the finding the ledger's own api/ row records at length: "the flat wire verdict this row used to carry was correct when written and then silently expired, which is the finding." A directory cell is read as licence for every file under it, which is precisely what that row warns about. check:strictness-ledger is green throughout — the gate protects the arithmetic and the coverage, deliberately not the Class cell's correctness, which the ledger states is a human judgement.
Not proposing the fix here
The api/ row also records the order that made closing that shape possible: a naked strictObject was measured and refused first, because the same schema was parsing stored envelopes, and the debt was paid at the layer that owned it (peelStoredEnvelope) before strictness went in. ManifestSchema may well have its own version of that — it is parsed from stack source, from published package records and from artifact bundles — so the first work here is the measurement, not the tightening.
Suggested first step: run the door-reachability / consumer measurement for ManifestSchema, then decide between (a) strictObject with curated guidance for any wrong-layer keys, (b) a narrower split if some callers really do feed stored rows through it, or (c) recording a deliberate open verdict for this file with its reason — which would at least replace an expired directory cell with a measured file-level one.
Whichever way it goes, the kernel/ ledger row should stop covering manifest.zod.ts with a verdict that reads as "nobody authors this".
Generated by Claude Code
Found while implementing #14161 (ADR-0130 D4). Out of that card's scope, filed rather than fixed, and unassigned.
Measured, on
origin/main682d03ba7, against the builtpackages/spec/distBoth the typo (
namesapce) and an arbitrary unknown key parse green and are dropped — not preserved, not reported.manifest.namespaceis thenundefined, and the author is told nothing.Why this is not a nit
This is the #8687 failure class exactly one level below the door #8687 closed. The top-level stack surface is now
strictObject, sonamesapce:at the top level is a named refusal carrying a rename suggestion. One level down, insidemanifest:— one of the most-authored objects in the product, present in everyobjectstack.config.ts— the same typo is silent.And the dropped key is load-bearing rather than decorative:
${namespace}_${shortName}is the kernel-validated object-name rule, and under ADR-0129 D1–D2 the objectnameis the table name, the REST path, the formula token and the saved-view key;manifest.namespace;MAP_SUPPORTED_FIELDS/ datasource routing and severaldatasourceMappingrules key on the namespace.So the observable symptom of a single transposed letter is not "a warning is missing" — it is objects landing under a different name than the author wrote, decided at parse time with exit 0.
Where the map says otherwise
docs/audits/2026-07-unknown-key-strictness-ledger.md:1321classifies the whole directory in one cell:kernel/manifest.zod.tsis covered by that verdict, and for most of the directory it is right. Butmanifest:is not code-to-code — it is a hand-authored block in every project's stack source, indefineStack, in the Studio surfaces and in the artifactos buildwrites.api/row records at length: "the flatwireverdict this row used to carry was correct when written and then silently expired, which is the finding." A directory cell is read as licence for every file under it, which is precisely what that row warns about.check:strictness-ledgeris green throughout — the gate protects the arithmetic and the coverage, deliberately not theClasscell's correctness, which the ledger states is a human judgement.Not proposing the fix here
The
api/row also records the order that made closing that shape possible: a nakedstrictObjectwas measured and refused first, because the same schema was parsing stored envelopes, and the debt was paid at the layer that owned it (peelStoredEnvelope) before strictness went in.ManifestSchemamay well have its own version of that — it is parsed from stack source, from published package records and from artifact bundles — so the first work here is the measurement, not the tightening.Suggested first step: run the door-reachability / consumer measurement for
ManifestSchema, then decide between (a)strictObjectwith curatedguidancefor any wrong-layer keys, (b) a narrower split if some callers really do feed stored rows through it, or (c) recording a deliberateopenverdict for this file with its reason — which would at least replace an expired directory cell with a measured file-level one.Whichever way it goes, the
kernel/ledger row should stop coveringmanifest.zod.tswith a verdict that reads as "nobody authors this".Generated by Claude Code