wai: wai generate and wai score, and the instruction object of wai.generate.spectral (form v0) #197
Merged
dcharlot
merged 12 commits from 2026-10-10 22:59:43 -04:00
wai/generate-score-cli into main 2026-10-10
Merge origin/main into wai/generate-score-cli
All checks were successful
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 22s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 21s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 20s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 8m25s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 11s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 10s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m26s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 16m37s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m53s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m2s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 12m20s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 30s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m21s
wai-ops integer operators / macos-arm64 (pull_request) Successful in 25s
wai-pack / wai-pack · macos (pull_request) Successful in 2m14s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 37m13s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 35m47s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 4m31s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 5m7s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 4m50s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 3s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m20s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m16s
wai-pack / wai-pack · linux (pull_request) Successful in 1m9s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 1m50s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 17s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m15s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 36m23s
Brings in #200 (HTTP receipts and keys) and #206 (wai-ops) among the rest of main. One conflict, wai/CHANGELOG.md: both sides added entries at the top of v0.4.0. Kept every entry; this branch's "Generated pictures and scores" stays on top as the newest, main's entries follow unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09
wai-web wasm32 CI: the browser generator and score synth make every native pin
All checks were successful
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m7s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m5s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m13s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 10s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m41s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m0s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Successful in 1h29m35s
wai-pack / wai-pack · linux (pull_request) Successful in 1m8s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 22s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m19s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 1m49s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 36m4s
standards workspaces build + test / aac-rs (pull_request) Successful in 10m19s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 9m39s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 5m5s
standards workspaces build + test / map-rs (pull_request) Successful in 5m26s
standards workspaces build + test / mesh-rs (pull_request) Successful in 5m22s
standards workspaces build + test / openpay (pull_request) Successful in 25m11s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 10m47s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 2m42s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 5m40s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 3m48s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m54s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 6m47s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 10m43s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m16s
wai-pack / wai-pack · macos (pull_request) Successful in 2m12s
The CHANGELOG said every pin equals the shared browser binding's output, and the browser sink's form-v0 reading has no CI of its own, yet wai-web-wasm.yml ran no generate or score check. demo/verify_generate_wasm.mjs runs generateSpectral at every size the generate vectors pin (sizes.json, instr-v0.json's four listed sizes, and the first listed size of each object at a bound of form v0), checks each object names the committed model, and runs ScoreSink over every score-conformance vector for its pcm_sha256, mixdown hash and score hash. The workflow runs it on the node build and now also triggers on wai/score-conformance/. 35 checks pass locally on a wasm32 build of this tree. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai REGISTRY: the status note names wai.generate.spectral among the registrations v0.4.0 completes
The hand-written Status note listed the integer codecs whose registrations v0.4.0 completes and left out wai.generate.spectral, which SPEC §8 now says §5 completes. The note sits outside the generated region the library test compares. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai generate.spectral: the model is the parameter set, so the envelope carries no pin; inspect and unwrap report the payload
Form v0 names the model inside the payload by the SHA-256 of one file, and SPEC §5
never said how that relates to §3.1's parameter-set pin, which governs every
GenerativeDeterministic capability: whether a generate envelope carries a pin, or
which wins when a pin and `model` disagree. The library registers the set as
several files, so a form-less pin over the very file `model` names would be
refused form_required. SPEC §5 now states the relation: the model file is the
parameter set and `model` its identity; an envelope that names the generator
carries no `prior` and a sink refuses one that does, whatever it names. §3.1 says
so beside the pin rules, the non-conforming list names it, and prior-carriage §7's
row says the set is never pinned and names the file. No library source changes.
`wai inspect` and `wai unwrap` reported a generate envelope with a corrupt
payload as conforming ("component roles ✓", no payload line). They now report
the payload (form v0, with the reader's reason), the intent and any pin of every
envelope or WAI2 component that names the generator, ✓ or ✗; inspect's verdict
says the envelope does not conform. inspect_and_unwrap_report_the_generators_envelope
covers a prompt byte changed in place, the intent improve, a pin over the model
file itself, and a WAI2 component with and without a pin.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai generate.spectral: the generator's envelope carries intent create, and wrap writes no other
SPEC §5 said the envelope's intent is `create`, but `wai wrap` refused only `replicate` and wrote wai.generate.spectral envelopes with `--intent improve` or `--intent banana`, and the non-conforming list did not mention intent. The sentence is now a rule: an envelope that names the generator, as capability or fallback, carries `create`, one with another intent is non-conforming, and wrap refuses any other. wrap_writes_the_generator_only_with_intent_create covers improve, an open string, a case variant, the empty string and the fallback. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai generate.spectral form v0: accepted objects at every bound, and each refusal's reason
instr-v0.json had one accepted object and 28 refused ones, none at an inclusive bound, so a second sink stricter by one passed every vector; and the CLI test held only that each object was refused, not why, so a rule relaxed (a quotation mark let into the prompt) stayed green while the canonical-bytes check refused the object in its place. - The reader (wai_cli/instr.rs) refuses with a reason code, the first rule broken in a stated order; a member given twice is refused as such (strict_json). - The vector gains twelve accepted objects (seed 0 and 2^32 - 1, steps 1 and 64, an empty prompt, 256 bytes, 0x20 and 0x7e, JSON's structural characters, a side of 1, a side of 4096 and 2^23 pixels, 16 sizes, the w-then-h order), each with the SHA-256 of its first listed size made natively; eight more refused objects (types, a fraction in a size, a negative side, an escaped line feed, a backslash, cut-short JSON); and a reason for every refused object. - tests/cli_generate_score.rs asserts each refusal's reason through `wai generate --instr` and `wai wrap`, and makes and wraps every accepted object. - tests/generate.rs states form v0 a second time, independently of the reader, and holds the object, the accepted and the refused lists to it, making each accepted object's output with the library. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai score build: refuse a member given twice in the authoring form
The authoring form (score §2.3) is the definition, yet a note holding both "start":0 and "start":5 built with start 5 (serde_json keeps the last value) and the same hash as a note with start 5 alone; another JSON reader could keep the first. wai_cli/strict_json.rs reads JSON with every object's members distinct and refuses a repeat, and build reads its document through it. Two refused cases are added: a note field and a document member, each given twice. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai score render: refuse a contract that is not one channel of wai.det.fixed64
render printed "channels":2 beside a mono mixdown of `duration` samples when a WSCR's contract said two channels, and rendered a contract whose numeric profile was wai.det.float64; a verifier following SPEC §7 Digests would read that PCM as stereo frames. render now refuses both, as build refuses to write them. score_render_refuses_a_contract_it_does_not_render patches the committed scale.wscr in place for each case. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai cli tests: the note-count guard is what refuses the crafted WSCR
score_render_refuses_a_note_count_its_bytes_cannot_hold wrote a file with no contract section, so the reader refused it with MissingSection(0x01) before parse_notes reserved anything, guard or no guard: the test checked only which message came first. The file now carries a well-formed contract (section 0x01) and a notes section of only the count (0x02), and the same file declaring no notes is shown to render, so without the guard the reader reaches Vec::with_capacity. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai cli tests: the two instr_sizes callers each write their own object file
instr_makes_the_listed_small_sizes and instr_makes_the_listed_large_sizes run at once in the release step, and both removed and rewrote one scratch file, object.instr, while the other's `wai generate --instr` children read it. A remove or a truncating write landing as a child opened the file would refuse the object and fail the test. Each caller now names its own file. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai SPEC §5: the payload of wai.generate.spectral is an instruction object (form v0)
Some checks failed
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Successful in 1h19m26s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m5s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m2s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m7s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 10s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 4m18s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 2m42s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 5s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 28m35s
standards workspaces build + test / aac-rs (pull_request) Successful in 10m55s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 6m27s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 5m23s
standards workspaces build + test / map-rs (pull_request) Successful in 4m43s
standards workspaces build + test / mesh-rs (pull_request) Successful in 1m31s
standards workspaces build + test / openpay (pull_request) Successful in 4m3s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 9m13s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 2m3s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m53s
wai-pack / wai-pack · linux (pull_request) Successful in 1m8s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 1m40s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 22s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m7s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 3m10s
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
The registration is completed as §8 permits: the row named the generator and no byte layout. The payload is one canonical JSON object naming the model by its SHA-256 and giving the prompt, the seed, the steps and every size a sink makes, each within stated bounds and with one serialization per object, so an envelope's content hash names the instructions. A sink makes only listed sizes, with that model only; conformance is generation-equivalence at each listed size, and a sink holding a size's SHA-256 does not present a picture that differs or accept one on a 64-bit FNV-1a alone. The envelope's intent is `create`: a generator does not back `replicate` (§7), and this keeps that rule. The registry row names the payload; §8 lists the completion. score §2.3 documents the integer authoring form `wai score build` reads, and §4 the pcm_sha256 every vector now states. CI builds the `wai` binary with `generate` and `score` in both profiles of the integer-kernel steps and runs tests/cli_generate_score.rs there; the two larger listed sizes of instr-v0.json run in the release step. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai:
wai generate and wai score build|render, with native pins a sink checks against
`wai generate` makes a wai.generate.spectral picture with the reference generator at any size and prints its SHA-256; with --instr it makes a listed size of an instruction object of form v0, which it reads as a sink does, and --write-instr writes one. `wai score build` writes a WSCR from integer note fields only; `wai score render` prints samples, pcm_sha256, mixdown_blake3 and score_hash, and --pcm writes the samples. Vectors: tests/vectors/generate/sizes.json (256x128, 640x320) and instr-v0.json (the object, its four listed sizes and 28 objects a sink refuses); score-conformance gains pcm_sha256 for every vector and notes/<name>.json, the authoring form, which `wai score build` turns back into the committed WSCR byte for byte. Every pin was made natively and equals the shared browser binding's output. `wai wrap` refuses a wai.generate.spectral payload that is not a form-v0 object, in every build. No library source changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>