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]>
143 lines
4.4 KiB
JSON
143 lines
4.4 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://wai.transaction.science/schema/wai.lock/1",
|
|
"title": "wai.lock, a WAI project's lock file, version 1",
|
|
"description": "Everything whose bytes change a project's results, pinned by digest. `wai lock` writes it and `wai lock --check`, `wai check` and `wai build` read it. The file is RFC 8785 over this object, on one line, with no line ending: a reader refuses any other bytes as edited by hand, which this schema, reading values, does not see. A member with nothing to pin is absent, never null. A member not listed here is refused.",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"$schema",
|
|
"wai",
|
|
"toolchain",
|
|
"registry"
|
|
],
|
|
"properties": {
|
|
"$schema": {
|
|
"description": "This schema.",
|
|
"const": "https://wai.transaction.science/schema/wai.lock/1"
|
|
},
|
|
"wai": {
|
|
"description": "The lock's version. A reader of version 1 refuses a later one.",
|
|
"const": 1
|
|
},
|
|
"toolchain": {
|
|
"description": "The wai that wrote it: its version, and the SHA-256 of its catalogue (`wai ops export`, wai/catalogue/ops.json).",
|
|
"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}$"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"template": {
|
|
"description": "The template the project came from: its name as wai.json states it, and the SHA-256 of its listing as that wai holds it (one line a file, sorted by path as bytes: the file's SHA-256, two spaces, its path, a line feed). A template that wai does not hold has no digest.",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"name"
|
|
],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"sha256": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{64}$"
|
|
}
|
|
}
|
|
},
|
|
"registry": {
|
|
"description": "The SHA-256 of the capability registry (`wai registry export`, wai/registry/capabilities.json).",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"sha256"
|
|
],
|
|
"properties": {
|
|
"sha256": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{64}$"
|
|
}
|
|
}
|
|
},
|
|
"priors": {
|
|
"description": "Each parameter set the project names, by the name wai.json gives it: its pin as SPEC 3.1 states it. A directory is a wai.prior.set, its digest that of its listing; one file has no form, its digest that of the file.",
|
|
"type": "object",
|
|
"minProperties": 1,
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"sha256"
|
|
],
|
|
"properties": {
|
|
"form": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"sha256": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{64}$"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"policy": {
|
|
"description": "The packaging policy: its version, and its canonical digest as `wai-pack policy` prints it (packaging 3).",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"schema",
|
|
"blake3"
|
|
],
|
|
"properties": {
|
|
"schema": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"blake3": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{64}$"
|
|
}
|
|
}
|
|
},
|
|
"conformance": {
|
|
"description": "Each corpus the project conforms against, by the suite wai.json names (<kind>/<suite>): its digest as conformance-results 2.1 states it, the one a conformance result names.",
|
|
"type": "object",
|
|
"minProperties": 1,
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"digest"
|
|
],
|
|
"properties": {
|
|
"digest": {
|
|
"type": "string",
|
|
"pattern": "^sha256:[0-9a-f]{64}$"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|