Review fixes: @type alias round-trip, enforce the $id MUST, document examples/default - #122
Open
simontaurus wants to merge 3 commits into
Open
Review fixes: @type alias round-trip, enforce the $id MUST, document examples/default#122simontaurus wants to merge 3 commits into
simontaurus wants to merge 3 commits into
Conversation
…examples/default Addresses #117, #118 and #120 from the rc.1 review. - #117: the inline-type example declared `type` as a strict array but aliased it plainly ("type": "@type"), which cannot carry @container, so a single @type compacted back as a scalar and failed the spec's own re-validation MUST. Verified with jsonld.js: the plain alias returns "schema:Person", { "@id": "@type", "@container": "@set" } returns ["schema:Person"]. - #118: the $id MUST is now enforced by the meta-schema instead of going unchecked. Split it into a two-tier dialect: oold-meta-schema.json (what $schema points at) carries required: ["$id"] and $refs the new oold-meta-schema-base.json, which holds the keyword syntax and $dynamicAnchor "meta". Nested subschemas recurse into the base via $dynamicRef, so fragments in properties/$defs are exempt, as they must be. Verified in ajv 8 and Python jsonschema 4.26; the standard 2020-12 meta-schema uses the same idiom, so no new support is required. Compliance fixtures that are document roots gained a $id. - #120: document that instance generation uses useExamplesValue / useDefaultValue, so `examples` and `default` must satisfy their own subschema even though JSON Schema treats them as annotations.
…y table The keyword name was OO-LD's own pick, not something SSSOM mandates (SSSOM defines slots and a TSV/JSON serialization, not a JSON Schema keyword), so an unprefixed x-sssom claimed a global extension name we do not own and broke the "every OO-LD keyword is x-oold-namespaced" rule. Renamed at both levels: the schema-level block and the per-entry block inside x-oold-context. @context remains the single exception, since JSON-LD fixes that name. Also fixes a gap the rename surfaced: the vocabulary() macro and the validator's coverage check both filtered on the x-oold- prefix, so @context and the former x-sssom were defined in the meta-schema but absent from the rendered keyword table and unasserted by the coverage check. Both are now included, and the all-keywords compliance fixture exercises @context. "OO-LD-proprietary" reworded to "OO-LD-specific": x- is a vendor extension in the JSON Schema / OpenAPI sense, marking the defining project, not commercial or closed status.
- Enforce the existing MUST that a schema closing its objects (additionalProperties/unevaluatedProperties false) must PERMIT the @context and $schema members an exported instance carries. It is a conditional obligation about permitting, not declaring: an open schema permits them implicitly, an instance held inside an application may omit both, and an embedded object never carries them - so the meta-schema does not require every schema to declare them. Probing the compiled schema with each member added is also what distinguishes additionalProperties from unevaluatedProperties correctly under composition, which a static check cannot. - Fix a boundSchema bug this surfaced: $id/$schema were stripped at every node, including inside property maps, where those are instance member names rather than schema keywords - so a schema legitimately declaring a $schema or $id member lost it from the validation view (and was then falsely reported as not permitting it). - Constrain the shape of a schema's own @context to the four forms JSON-LD allows (map, IRI reference, array of either, null). W3C publishes no JSON Schema for a context, and the community one on SchemaStore checks only this same union; the term definitions inside are verified by the JSON-LD processor tier instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #117, #118 and #120 from the v1.0.0-rc.1 review (thanks @LukasOro - all three came out of porting the EU Battery Passport model from SAMM).
#117 - the
type->@typealias is not round-trip safe (bug)Confirmed and fixed. The normative "Carrying the type inline" example declared
typeas a stricttype: arraybut aliased it plainly ("type": "@type"), and a plain-string term cannot carry@container- so a single@typecompacted back from RDF as a scalar and failed the spec's own re-validation MUST.Verified with jsonld.js:
@contextterm"type": "@type""schema:Person"- scalar, failstype: array"type": { "@id": "@type", "@container": "@set" }["schema:Person"]- array, re-validatesThe example now uses the
@container: "@set"form, and the prose says explicitly that a strict-arraytypeproperty needs it like any other strict-array property. Scope is that one example: theexamples/schemas aliastypetoo but declare no strict-arraytypeproperty, which is why the self-suite did not catch it.#118 - nothing enforced the
$idMUST (now it does)The premise that JSON Schema cannot express a root-only requirement turns out not to hold - it can, via
$dynamicAnchorscoping, which is exactly what the standard 2020-12 meta-schema does. The dialect is now two-tier:meta/oold-meta-schema.json(unchanged URL, what$schemapoints at) carries the document-level obligations -required: ["$id"]- and$refs the body.meta/oold-meta-schema-base.json(new) holds the keyword syntax and$dynamicAnchor: "meta". Nested subschemas recurse into the base via the standard$dynamicRef, so a fragment inproperties/$defs/x-oold-rangeis validated against the dialect without being required to carry$id.Verified in both target ecosystems - ajv 8 and Python
jsonschema4.26 - with the real files: root with$idand$id-less nested fragments passes; a root without$idis rejected. No new tooling support is required: the official 2020-12 meta-schema is itself built on$dynamicAnchor/$dynamicRef, and our meta-schemas already declared the anchor.Fallout, all mechanical: compliance fixtures that are document roots gained a
$id(28 inoold-vocab.json, 5 feature schemas inroundtrip-patterns.json- thelintSchemasgroup is checked against the pattern lint, not the meta-schema, so it is untouched), andvalidate.mjsregisters the base and reads the keyword list from it.#120 -
examples/defaultare load-bearing (documented)The harness generates instances with
useExamplesValue/useDefaultValue, so those annotations must satisfy their own subschema even though JSON Schema does not validate them. The behaviour is worth keeping (it caught real upstream defects), it was just undocumented and surfaced as a confusingGEN-INVALID.docs/tooling.mdnow states it and notes that aGEN-INVALIDpointing at such a value indicates the annotation, not an unsatisfiable schema.Not included: #119 (generator guidance) is deferred pending the SAMM evaluation - the direction there is that SAMM's URNs do allow deriving a context, the open question is preserve-vs-mint, and
x-oold-uuidshould be a UUIDv5 seeded from the stable source identifier so regeneration does not churn. #115 (persistent$ids) is a separate concern from enforcement and is untouched here.Rendered spec regenerated;
check_spec.pypasses; self-suite 147/147.Added after review of the keyword listing
x-sssomrenamed tox-oold-sssom(both the schema-level block and the per-entry block insidex-oold-context). The name was OO-LD's own pick - SSSOM specifies slots and a TSV/JSON serialization, not a JSON Schema keyword - so an unprefixedx-sssomclaimed a global extension name we do not own and broke the "every OO-LD keyword isx-oold--namespaced" rule.@contextis now the single exception, and it is a genuinely forced one (JSON-LD fixes the name). Doing this in an RC rather than after v1.0.@contextandx-oold-sssomwere missing from the rendered keyword table and from the validator's vocabulary-coverage assertion: both thevocabulary()macro andvalidate.mjsfiltered on thex-oold-prefix, so two keywords that are defined in the meta-schema were invisible and unchecked. Both now included; the all-keywords compliance fixture exercises@context.x-is a vendor extension in the JSON Schema / OpenAPI sense - the namespace marks the defining project, not commercial or closed status.