ADR-0005: Schema conventions
- Status: Accepted (2026-09-29)
- Date: 2026-09-29
Context
Specs are written by an LLM (via strict tool inputs or structured outputs), by samplers,
by people in a text editor, and by UI panels. They are read by two languages. Claude's
structured outputs accept a subset of JSON Schema: objects must be closed
(additionalProperties: false); recursive schemas are not supported; numeric, length and
complex array constraints are removed by the SDK and checked client-side.
Decision
- JSON Schema 2020-12 in
schemas/v<major>/. These files are the source of truth; generated TypeScript types and GDScript classes are committed and CI checks they are current. - Structured-output compatible, enforced by a CI lint:
- every object is closed;
- no
oneOf,patternProperties,if/then/else,notorunevaluatedProperties; - no recursion;
- unions are
anyOfof objects with aconstdiscriminator ("type": "line").
- No map-shaped objects. Collections are arrays of objects with an
id; the semantic validator checks uniqueness. - Flat hierarchies. Parent/child relations use
parentids, never nesting (set elements, rig parts, kit recipe nodes). This also keeps diffs and patches local. - Envelope.
kind,schemaVersion,id, name or title, thenmeta(status, locks, provenance, derivation). An optional$schemalets editors validate hand edits. - Kind-prefixed ids (
char.*,set.*,ep.*,pattern.<type>.*) checked by regex; short local slugs inside documents. - Units in names (
Cm,M,Deg,Sec,Px1080). Colors are sRGB hex or@slotpalette references. - JSON Pointer addressing everywhere a spec refers to a part of another document: pattern rules, locks, variations, revisions.
- Descriptions are prompts. Every non-obvious field has a description written for both a person and the model; tool definitions reuse them verbatim.
- Versioning.
schemaVersionisMAJOR.MINOR. A minor version only adds optional fields; a major version ships a migration and tests. - Canonical files, JCS hashes. Only the core writes specs: schema key order, 2-space indent, shortest round-trip numbers, trailing newline. Content hashes are SHA-256 over RFC 8785 canonical JSON.
Consequences
- One schema serves validation, editor autocompletion, LLM tool definitions and codegen.
- Some shapes are more verbose than idiomatic JSON (arrays of
{slot, color}instead of a map). That is the cost of being LLM-writable with guarantees. - Semantic validation (references, uniqueness, pointer targets, word indexes) is a separate layer in the core, and it produces the same pointer-addressed diagnostics as schema validation.