whynot-design/ir/schema/manifest.schema.json

51 lines
2.6 KiB
JSON
Raw Normal View History

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://whynot.design/ir/schema/manifest.schema.json",
"title": "whynot IR — Version Manifest",
"description": "ir/manifest.json — the per-version inventory and diff anchor. Generated only by scripts/ir-extract.mjs (make ir). Each hash is a deterministic content hash (sha256 over canonicalised JSON: keys sorted, no insignificant whitespace) so it is invariant to formatting and sensitive only to meaningful contract/token change. The consumer drift-check (WHYNOT-WP-0003 T05) compares two manifests, or a manifest against a consumer's .whynot-design.lock.",
"type": "object",
"required": ["schemaVersion", "designVersion", "generatedAt", "tokensHash", "components"],
"additionalProperties": false,
"properties": {
"schemaVersion": {
"type": "string",
"description": "Shape version of THIS manifest. Bumped when the manifest layout or the hashing scheme changes, so a consumer can tell a re-canonicalisation apart from a real design change.",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
},
"designVersion": {
"type": "string",
"description": "The package.json version this manifest was extracted at (e.g. the semver tied to a git tag vX.Y.Z)."
},
"generatedAt": {
"type": "string",
"format": "date-time",
"description": "ISO-8601 timestamp of extraction. Reused from the prior manifest when nothing hashed changed, so a no-op `make ir` does not churn the committed file. Informational only — never part of any hash."
},
"tokensHash": {
"$ref": "#/$defs/hash",
"description": "Content hash of the full canonicalised ir/tokens.json. A single coarse hash by design (token-level diff granularity is a deferred refinement)."
},
"components": {
"type": "array",
"description": "One entry per component contract, sorted by name.",
"items": {
"type": "object",
"required": ["name", "group", "hash"],
"additionalProperties": false,
"properties": {
"name": { "type": "string", "pattern": "^[A-Z][A-Za-z0-9]*$" },
"group": { "type": "string", "description": "The component's group (atoms, chrome, …)." },
"hash": { "$ref": "#/$defs/hash", "description": "Content hash of the canonicalised ir/components/<name>.json contract." }
}
}
}
},
"$defs": {
"hash": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{16}$",
"description": "Algorithm-prefixed truncated digest: 'sha256:' + first 16 hex chars of sha256(canonical JSON)."
}
}
}