Skip to content

feat(spec): refuse unknown keys inside manifest:ManifestSchema goes strict (the #8687 door one level down) #19947

feat(spec): refuse unknown keys inside manifest:ManifestSchema goes strict (the #8687 door one level down)

feat(spec): refuse unknown keys inside manifest:ManifestSchema goes strict (the #8687 door one level down) #19947

Triggered via pull request September 2, 2026 20:17
Status Success
Total duration 50s
Artifacts

pr-automation.yml

on: pull_request
Check PR Size
Check PR Size
Check Changeset
47s
Check Changeset
Auto Label
Auto Label
Fit to window
Zoom out
Zoom in

Annotations

1 notice
Check Changeset: .changeset/manifest-unknown-keys-refused.md#L0
ADR-0087 exemption (no-migration-prescription): this change retires NO key. The manifest vocabulary is byte-identical except for one ADDITIVE declaration (`main`, a key the `os plugin build` door already honoured), and only the unknown-key POSTURE moves, from strip to reject. Nothing exists for `objectstack migrate meta` to rewrite: an undeclared key was never honoured — it was dropped at parse and so never reached storage, the registry or any reader — so no stored shape carries one and no authored shape that ever WORKED becomes invalid. There is no single rewrite rule a ledger entry could state either, since what is now refused is an open set of author typos rather than a renamed key. The upgrade channel is the schema rejection itself, which names the offending key at the author's own path and carries either the declared spelling or the wrong-layer pointer (`specVersion`). The retired manifest keys keep their existing ledger entries (`kernel/Manifest:loading`, `kernel/Manifest:capabilities`, `kernel/Manifest:configuration`, `kernel/Manifest:extensions`, the `kernel/Manifest:contributes.*` family) and their tombstones. Measured blast radius before the close: 0 undeclared keys across the four example apps, the three `os init` templates, the `create-objectstack` blank template and every other shipped `manifest:` block; the one undeclared key found at a real door (`main`, on `objectstack.plugin.json`) is declared by this change rather than refused.