@vantageos/charter-dtcg-contract
v1.0.0
Published
Versioned DTCG contract for the charter seam between Rho (producer) and Hephaistos (consumer).
Downloads
139
Readme
Charter DTCG contract — v1
The seam between the charter generator (Rho, producer) and the document engine (Hephaistos, consumer).
A charter that does not satisfy charter-dtcg.v1.schema.json is not a charter. This is the whole point of the file: "frozen per cycle" as a sentence in a plan drifts on the second cycle, silently, and the consumer discovers the break downstream. A schema validated in CI cannot drift without something going red.
What a consumer does
Pin the version. CONTRACT_VERSION is derived from package.json and cross-checked against the major in the schema's $id, so the two cannot disagree without throwing at import.
import { validateCharter, CONTRACT_VERSION } from "./src/validate.mjs";
const { valid, errors } = validateCharter(charter);Breaking changes ship as charter-dtcg.v2.schema.json. v1 is never edited once consumed — a consumer that pinned v1 must keep getting v1's meaning.
Shape
Root requires $version, name, color, font. Everything else (typography, space, radius, shadow, duration, easing) is optional — a charter without colors and fonts is not a brand, a charter without a shadow scale is just a charter that does not need one.
Every leaf is a DTCG token carrying $type, $value, and $extensions.vantage:
{
"$type": "color",
"$value": "#f59e0b",
"$extensions": {
"vantage": {
"provenance": "ooxml-theme",
"confidence": 1,
"source": "deck.pptx#/theme1.xml/a:clrScheme/a:accent1",
"cssVar": "--accent"
}
}
}provenance — a closed set
ooxml-theme · firecrawl-branding · pdf-frequency · image-measured · user-confirmed
An extractor that cannot name its route does not get to write a token. The set is closed on purpose: a free-text field would fill with prose and stop being queryable.
confirmed — the gate applies to inferred values only
Tokens whose provenance is firecrawl-branding, pdf-frequency, or image-measured were guessed, and the schema requires confirmed: true before they can ship. Tokens read verbatim from an OOXML theme are not subject to the gate.
That asymmetry is deliberate. A gate that also asks the user to confirm a value read straight out of theme1.xml teaches them to click through everything, and then it guards nothing.
cssVar — why the mapping lives on the token
Two naming conventions exist in this codebase and both are legitimate:
design-systems/_schema/tokens.schema.ts—--bg,--fg,--accent,--text-xl,--space-4@vantageos/mosaic-tokens—--mosaic-<category>-<key>
The DTCG path (color.primary) is the token's identity; the emitted CSS custom property name is an output concern. Carrying the mapping on the token lets one charter serve both conventions without a second source of truth — and without the exporter having to guess.
Running the check
cd contracts/charter-dtcg
npm install
npm testCI runs the same command on every push touching this directory.
Fixtures
fixtures/valid-*.json must pass; fixtures/invalid-*.json must fail, each for a named reason asserted in test/. The suite also asserts the count of rejection fixtures on disk — a fixture added without a matching test moves the count and the suite says so, instead of sitting unexercised.
Orchestrator: Rho — VantageOS Team | 2026-07-24
