Commit cdc3cc4
fix: enforce the §2 unknown-property rule below the envelope (#10)
* fix(component): reject unknown properties below the envelope
spec.md §2 requires unknown properties to be rejected at every level, but
additionalProperties: false was present on only SeedComponentMetadata. The 21
Component*Request defs were open, so a misspelled optional key anywhere below
the envelope validated clean and fell back to its default.
The gap is an artifact of the bootstrap import (ADR 0001): platform Seed*
models set Pydantic extra="forbid"; reused *Request wire models inherit the
default extra="ignore".
Map-shaped schemas (contract inputs/outputs, workload endpoints/volumes, build
arguments) are untouched — their keys are chosen by the document author.
Refs #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
* fix(blueprint): reject unknown properties below the envelope
The six Blueprint*Request defs carried no additionalProperties, so a misspelled
optional key inside a parameter or a connection ref validated clean. The Seed*
defs were already closed, which is why the first level below the envelope
appeared strict while everything under it was not.
Refs #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
* test(conformance): pin nested unknown-field rejection
structural/003-unknown-field only injects a key at the root, which is why the
gap below the envelope survived the bootstrap import. structural-005 injects
the typo deeper: a probe field on component, a parameter's ui block on
blueprint, and an array element on listing.
Against the pre-change schemas the component case validated cleanly and the
blueprint case produced no ERR_UNKNOWN_FIELD. The listing case passes either
way — listing was already fully strict, so it is a regression pin rather than
proof of a fix.
Refs #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
* feat(tools): require object schemas to close additionalProperties
Nothing checked this before, which is how 27 open defs survived the import.
Any subschema declaring type: object and properties must now also declare
additionalProperties: false.
Map-shaped schemas declare no properties and are unaffected, so the rule needs
no exemption list. walkObjects now carries a JSON Pointer so the diagnostic can
name the offending subschema.
Refs #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
* docs(component): name ERR_UNKNOWN_FIELD in the envelope clause
All four unknown-field fixtures cite #envelope, but §2 never named the code
they assert — the binding came only from the §8 registry. State it inline, as
the specVersion sentence two lines down already does, and say explicitly that
the rule covers optional fields, where ignoring a typo substitutes the default.
Refs #6
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
---------
Signed-off-by: Justin Merrell <merrelljustin@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 262a006 commit cdc3cc4
20 files changed
Lines changed: 212 additions & 9 deletions
File tree
- conformance
- blueprint/v1
- structural/005-nested-unknown-field
- component/v1
- structural/005-nested-unknown-field
- listing/v1
- structural/005-nested-unknown-field
- specifications
- blueprint/v1/schemas
- dist
- src
- component/v1
- schemas
- dist
- src
- tools/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
Lines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
Lines changed: 17 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
Lines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
Lines changed: 17 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
0 commit comments