open-standards/wai/schema/wai-build-1.schema.json
Transaction Science 2df4f582a2 wai lock, wai check and wai build: a project pinned, validated and built
wai lock (project.lock) writes wai.lock beside wai.json: wai's version and
the SHA-256 of its catalogue, the registry's, the template's files as this
binary holds them, each parameter set's pin (SPEC 3.1), the packaging
policy's canonical digest by wai-pack policy, and each conformance corpus's
digest (conformance-results 2.1). The file is RFC 8785 on one line with no
line ending, no time and no path, so the same inputs give the same bytes on
any host and a checkout with core.autocrlf=true has nothing to convert. A
member with nothing to pin is absent. wai lock --check holds the file to what
it pins. The reader refuses a later version as that version, a member it does
not know, a member named twice, and bytes that are not the canonical form.

wai check (project.check) validates a project without building it and
reports every finding: wai.json, each file it states, required capabilities
against the registry, the app by wai app check, what a build would make of
the site, and the lock member by member. What it could not run here says not
checked and is never counted as holding: exit 1 when a check failed, 5 when
none failed and one or more could not run.

wai build (project.build) runs the same checks, refuses with nothing written
when one fails, then writes dist/: the site, the app, and the package by
wai-pack pack and verify, made beside dist/ and renamed into place. It ends
with dist/wai-build.json, naming wai.json's canonical digest and wai.lock's.
Two builds in two directories at two times give the same tree.

wai.json gains the members these read (requires.capabilities, priors,
package, conform.suites), and its reader names every problem. The three are
in the catalogue and in wai mcp's core toolset, with their schemas under
wai/schema/. wai/project-conformance/ pins the lock's bytes and holds a
second reader in Python, standard library only, that recomputes every digest.
The examples, wai/LICENSE and the corpora a suite reads are never converted
on a checkout, and a test holds each to that. Studio's actions are
regenerated from the catalogue.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-06 17:28:16 -05:00

113 lines
3 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://wai.transaction.science/schema/wai-build.json/1",
"title": "wai-build.json, the record of a WAI project's build, version 1",
"description": "What `wai build` writes last into dist/: what the tree came from and what it holds. The file is RFC 8785 over this object, on one line, with no line ending, and holds no time and no path outside dist/, so two builds of one project and lock give one record, and its SHA-256 is the tree's digest.",
"type": "object",
"additionalProperties": false,
"required": [
"$schema",
"wai",
"project",
"lock",
"toolchain",
"files"
],
"properties": {
"$schema": {
"description": "This schema.",
"const": "https://wai.transaction.science/schema/wai-build.json/1"
},
"wai": {
"description": "The record's version.",
"const": 1
},
"project": {
"description": "The project: its name where wai.json gives one, and the SHA-256 of wai.json's canonical form (RFC 8785 over what it says, a whole number however it is written).",
"type": "object",
"additionalProperties": false,
"required": [
"sha256"
],
"properties": {
"name": {
"type": "string"
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
},
"lock": {
"description": "The lock: the SHA-256 of wai.lock, byte for byte.",
"type": "object",
"additionalProperties": false,
"required": [
"sha256"
],
"properties": {
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
},
"toolchain": {
"description": "The wai that built it, as the lock pins it.",
"type": "object",
"additionalProperties": false,
"required": [
"version",
"catalogue"
],
"properties": {
"version": {
"type": "string",
"minLength": 1
},
"catalogue": {
"type": "object",
"additionalProperties": false,
"required": [
"sha256"
],
"properties": {
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
}
}
},
"files": {
"description": "Every file of the tree but this one, sorted by path as bytes.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"path",
"sha256",
"bytes"
],
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"bytes": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
}
}
}
}
}