Contents

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

  1. 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.
  2. Structured-output compatible, enforced by a CI lint:
    • every object is closed;
    • no oneOf, patternProperties, if/then/else, not or unevaluatedProperties;
    • no recursion;
    • unions are anyOf of objects with a const discriminator ("type": "line").
  3. No map-shaped objects. Collections are arrays of objects with an id; the semantic validator checks uniqueness.
  4. Flat hierarchies. Parent/child relations use parent ids, never nesting (set elements, rig parts, kit recipe nodes). This also keeps diffs and patches local.
  5. Envelope. kind, schemaVersion, id, name or title, then meta (status, locks, provenance, derivation). An optional $schema lets editors validate hand edits.
  6. Kind-prefixed ids (char.*, set.*, ep.*, pattern.<type>.*) checked by regex; short local slugs inside documents.
  7. Units in names (Cm, M, Deg, Sec, Px1080). Colors are sRGB hex or @slot palette references.
  8. JSON Pointer addressing everywhere a spec refers to a part of another document: pattern rules, locks, variations, revisions.
  9. Descriptions are prompts. Every non-obvious field has a description written for both a person and the model; tool definitions reuse them verbatim.
  10. Versioning. schemaVersion is MAJOR.MINOR. A minor version only adds optional fields; a major version ships a migration and tests.
  11. 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.