ADR-0007: JSON schemas use the 2020-12 dialect
Status
Accepted
Context
Every schema under specification/schema/ originally declared JSON Schema draft-07 (2017). Issue #794 asked for a dialect decision among three directions:
- Stay on draft-07. Tolerable, but the ecosystem has moved: json-schema.org recommends 2020-12 as the default unless a validator pins you to an older draft, MCP defaults to 2020-12, and upcoming JSON Schema tooling (GSoC 2026 compatibility checker, semantic diff assistant) targets 2020-12 only.
- Migrate to 2020-12. The blocking dependency was the Go validator:
xeipuuv/gojsonschemawas draft-07-only, but #268 already replaced it withsanthosh-tekuri/jsonschema/v6, which fully supports 2020-12. The remaining cost is mechanical keyword renames plus dialect awareness in the Node tooling. - Adopt TypeSpec as the upstream source of truth, emitting JSON Schema 2020-12 and Go types from one definition. This would remove most drift classes by construction — the entire
check-*-driftfamily polices exactly the parallel-maintenance burden TypeSpec eliminates — but requires re-architectingspecification/, introduces a Node-toolchain dependency into the spec authoring path, and abandons the hand-curated schema files that the spec markdown, drift checkers, and website all link to today.
A further force: the drift-check skills never declared which dialect they expect, so any 2020-12-only syntax added to a schema would silently drift from the prompts' draft-07 mental model.
Decision
GLX JSON schemas use JSON Schema 2020-12. Every *.schema.json in the repository declares "$schema": "https://json-schema.org/draft/2020-12/schema", uses $defs rather than draft-07 definitions, and dependentRequired rather than array-form dependencies. The meta-schema (specification/schema/meta/schema.schema.json) enforces the dialect declaration, and the drift-check skills state it explicitly.
TypeSpec is deferred, not rejected. Hand-maintained 2020-12 schemas remain the machine-readable source derived from the spec markdown. Adopting TypeSpec would be a separate, larger re-architecture; if the drift-tooling burden grows enough to justify it, that proposal should arrive as its own ADR superseding the relevant parts of this one.
Consequences
Positive
- The schemas can adopt 2020-12 features as needed:
unevaluatedPropertiesfor tightening the vocabulary-definedpropertiesmaps, assertedformat,prefixItems, and$dynamicReffor shared vocabulary-entry bases. - The dialect matches what modern validators (ajv
2020class,santhosh-tekuri/jsonschema/v6), MCP, TypeSpec emitters, and upcoming JSON Schema tooling expect. - The drift-check skills now pin the dialect, so LLM-assisted checks stop suggesting draft-07 idioms.
Negative / constraints
- Contributors must write 2020-12 keywords: subschemas go in
$defs, property co-requirements independentRequired. The meta-schema check (make check-schemas) fails draft-07 declarations. - Node tooling must use dialect-aware imports (
ajv/dist/2020.js, not the draft-07 default export). json-schema-diff-validator(the schema↔schema compatibility gate, #311) predates 2020-12;specification/schema-compat.mjscanonicalizes both sides back to draft-07 keywords before diffing. If a future schema uses a 2020-12 keyword with no draft-07 equivalent (e.g.unevaluatedProperties), the gate ignores it — replacing that tool with a 2020-12-native differ is future work.- Consumers validating archives against the published schemas need a 2020-12-capable validator. Most maintained validators read both drafts; consumers pinned to draft-07-only libraries must update.