Design System Contracts

How it works · foundations 4

Determinism & receipts

"Generate from your design system" can be an architecture property or a model behavior you hope for. This spec chooses the property — and backs every honesty claim with a named mechanism.

Receipts flow: the contract feeds four emitters behind one interface; emitted surfaces are pinned by a golden manifest of SHA-256 hashes; illegal contracts are refused by name before anything emits; every token reference must resolve through the integrity gate; imports name every loss as a degradation code. Each gate writes a committed receipt.Receipts flow: the contract feeds four emitters behind one interface; emitted surfaces are pinned by a golden manifest of SHA-256 hashes; illegal contracts are refused by name before anything emits; every token reference must resolve through the integrity gate; imports name every loss as a degradation code. Each gate writes a committed receipt.

Golden manifests

Same contract in, byte-identical surfaces out — no generation lottery. Determinism is proven against recorded output, not just against itself: a golden-output manifest (evals/golden.json) pins SHA-256 hashes over every generated file, so a surviving-mutant change to any emitter fails loudly. The full token build plus component generation runs twice under the eval and must hash identically; regenerating from an unchanged contract is always a no-op diff.

npm run eval    # golden-output manifest, refusals, drift detection, convergence
npm run build   # regenerate everything — a clean tree stays byte-identical

Refusal, by name

An illegal contract fails at build time with the exact violation named — on every surface, including the canvas emitter. There is no "best effort" mode. The reference pages list the refusal rules per feature: defaults outside enums, duplicate design-property bindings, malformed token references, composition cycles, slot content outside accepts, a shape part that isn't a leaf, a state override on a part the child contract owns. Each class is exercised by the C2 eval family — a refused contract fails fast instead of crashing dependents.

The integrity gate

Every token reference in every contract — after placeholder expansion — must resolve to a real token in tokens/. Point a binding at a token that doesn't exist and the build itself fails, naming the contract path and the missing token. The contract and the token set cannot silently disagree.

Degradation codes — nothing is lost silently

Import is where honesty is usually lost: a pipeline reads a rich source and quietly carries what it can. Here, every channel the capture reads but cannot carry is a receipt. The import pipeline names its losses with degradation codes — paint stacks it had to truncate, non-uniform stroke weights, unsupported stroke styles, blend modes, rotations, vector geometry, min/max size constraints, text channels — and the proposer names bound variables on fields outside the contract vocabulary rather than dropping them. Unbound or raw values are always reported with nearest-token candidates, never invented. The standing measure: across an entire enterprise kit import, every fact carried, every note, and every degradation is counted per component set — see the instruments.

Declared fidelity limits

Not everything is expressible on both surfaces, and nothing here pretends otherwise. The canvas runs a named slice of behavior and no more: the generator wires Figma prototype reactions for hover and press on the State axis, so a generated set responds in presentation mode — but Figma's trigger vocabulary has no focus and no disabled trigger, so those previews stay drawn cells and are asserted as destinations of nothing. Everything past that is code-side: events are callbacks, and the canvas cannot fire a callback, so they surface there as description text. CSS animation and conditional literal styles are code-side by declaration. Structured arrayOf props have no canvas manifestation and say so in their binding. Each limit is written into the spec page for its feature — a limit you can read is a limit you can trust.

The claims rule

The reference implementation's contribution norm, and this site's too: no capability claim without an eval behind it (CONTRIBUTING.md). Fixture first, eval second, claim last. This page's claims each name their mechanism; the dated log of what has been proven, in order, is MILESTONES.md.