wai: the integer codecs' binary payloads, pinned in place #139
Merged
dcharlot
merged 35 commits from 2026-10-04 14:05:11 -04:00
wai/land-16-binary-payloads into main 2026-10-01
wai: an unpinned decode reads its set once and is checked by every identity
Some checks failed
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 23s
standards workspaces build + test / openpay (pull_request) Failing after 3m10s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 51s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 3m55s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 38s
standards workspaces build + test / jouleclaw-rs (pull_request) Failing after 15m48s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 2m9s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 24s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 45s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 5m59s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 30s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m4s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 1m8s
wai formal verification (integer core) / kani (pull_request) Successful in 4m22s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 57s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m12s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m0s
WAI section references / cited sections exist (pull_request) Successful in 11s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m53s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m43s
standards workspaces build + test / arl-rs (pull_request) Successful in 2m33s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 2m59s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m1s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 2m42s
standards workspaces build + test / sense-rs (pull_request) Successful in 2m42s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 3m23s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 30s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 6m9s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 31s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 1m35s
Outside the integer path, a sink whose key log only revokes ran check 5 over the registered file's digest and any listing found beside it, then decoded from the path. With no listing beside them, a revoked several- file set decoded, and a file changed after the check was what the decode read. At a registry with a key log, the neural sink now reads once what the decode can read: the registered file of a one-file set; otherwise every file below the directory the decoder reads from (the registered directory, or the registered file's), as pin::listing_of_dir lists it (pin::read_dir_set, which listing_of_dir now uses). Check 5 runs over every digest a pin over it could name: the file's, or the directory's derived listing and each member's, and each listing beside them that matches what was read. The decode then reads only those bytes (neural::ParamSource::Checked, which replaces Authorised and records the registered file within a set), never the path; where the key log holds the capability's sets to jwp-receipts §7.9, only the part §7.9 authorised. The decoders outside the integer path read files by name from that directory, some chosen by the payload, so the set is the directory rather than a fixed list. With no key log the decode reads the path, as before. SPEC §4 (Module authorisation) and jwp-receipts §7.9 state the reference behaviour. Test: neural_native_decode::a_revoke_only_key_log_checks_and_reads_the_set_once (a revoked set beside its listing; with no listing, the decoder and the directory registered; a member's own digest revoked; the tables swapped on disk after the check; no key log). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: an encrypted envelope is inert at the reference dispatchers
Some checks failed
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Has been cancelled
standards workspaces build + test / jouleclaw-rs (pull_request) Has been cancelled
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Has been cancelled
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai formal verification (integer core) / kani (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
The emit paths skip the integer framing check for an envelope whose
manifest declares an encryption, since its payload is ciphertext; but
the reference dispatchers did not apply SPEC §6.4 step 2, so a payload
sent in the clear under a false claim of encryption was decoded as
plaintext, and a WAI2 security member that is not a security object
(true, "aes", [], {"encryption": 5}) was written.
- Wai::dispatch_verified and WaiMulti::pick open no scheme, so an
envelope whose manifest declares an encryption other than "none" is
inert at them before any capability is considered:
unsupported_encryption (container::Inert::Encrypted, and
container::Skip::Encrypted for every WAI2 entry). The neural sink
reports neural::DecodeError::Encrypted, its C ABI WAI_ERR_CONTAINER;
wai-web's dispatchCapability returns undefined.
- WaiMulti::to_emit_bytes, and so the C packer and wai-web's packMulti,
refuse a security member that is not a security object
(EmitError::Security, container::manifest_v2_security); read, such a
member is treated as encrypted.
SPEC §6.4 step 2 names the reference's report, and §7.1 states the WAI2
security member and the reason it gives every entry.
Tests: container's an_encrypted_envelope_is_inert_at_the_reference_dispatchers
(WAI1 and WAI2, "none", null, an absent and an empty member, the four
malformed members refused at emit and inert when read);
neural_native_decode's an_encrypted_envelope_is_inert_at_the_reference_sink
(a valid WIH1 and its JSON form in the clear under the claim, a WAI2
encrypted or with security true); wai-web's writers test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the reference sink applies the declared cost before decoding
No reference sink read the declared cost: a few kilobytes of valid stream could make the neural sink, or its C ABI, decode a clip at the 2^30-byte cap. - neural::ModelRegistry::with_cost_limit takes a limit on each figure of int_payload::DeclaredCost (DeclaredCost::new, a figure left unbounded at its type's maximum). An integer payload over it is refused before any symbol is decoded, with the new code cost_over_limit (int_payload::check_cost, neural::DecodeError::OverCostLimit); it is the sink's policy, so dispatch moves on as for a capability the sink cannot decode: a WAI1 to its fallback, a WAI2 to its next entry. integer-payloads §8 lists the code and its routing, and §7 places the check after the networks are planned. - neural::declared_cost reads the cost over the parameters resolve_verified returns, so a registry user reads it over the bytes a pin verified without building int_payload::IntParams. - The C ABI's neural entry points do not advertise a capability that decodes to integer video, PCM or splat attributes, which have no wai_decoded_t kind (neural::decodes_to_int): such a payload is refused before it is decoded, not after. - wai_int_payload_declared takes the parameter set's path, or null for the header alone, and wai_int_declared_t gains working_bytes, the multiply-accumulates (macs_lo, macs_hi) and cost_known. The header alone fixes them for a keyframe-0 WIV1 (int_wire::Wiv1::keyframe0_working_bytes, which declared_cost now uses too; container::DeclaredSize gains working_bytes and macs). Tests: neural_cost_limit (its own binary, a live-bytes allocator): a clip over the limit refused having held under 64 KiB, the next WAI2 entry decoded; the C ABI refusing the clip under 64 KiB through wai_neural_decode_ex and wai_neural_decode_video; the cost over a registry's set and through the C ABI equal to the library's, and set_incomplete without a member. ffi_envelope and int_payload_cost check the header-only figures. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the declared cost counts the networks' multiply-accumulates
int_payload::DeclaredCost gains macs: the multiply-accumulates the decode's networks comprise, layer by layer, from the same plan that sizes their buffers (int_hyper_synth::plan_net, the audio synthesis's plan): a convolution's every output times c·k·k, a transposed convolution's every input times out·k·k (out·k in the audio synthesis), an inverse GDN's every element times c. It is exact, summed in u128, and 0 for a WIV1 with keyframe 0. A kernel may skip a zero term, so it performs at most this many. wai-web's intPayloadCost gives it as a BigInt (macs). integer-payloads §7 states the definition. Tests: int_hyper_synth's the_planned_macs_are_every_layers_terms (200 random networks, each term counted at the shapes apply_layer forms); int_audio's the_planned_macs_are_every_layers_terms (the committed synthesis, at the lengths the reference kernel gives); int_payload_cost (0 for keyframe 0, more for every network); wai-web's the_declared_cost_is_read_before_decoding. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: a WIV1 keyframe's size is checked before the keyframe is decoded
int_payload::declared_cost refused a keyframe-1 WIV1 whose keyframe does not give the clip's h × w as geometry_mismatch, but the decode compared the size only after decoding the keyframe, so the same bytes could be refused there for the keyframe's stream (stream_noncanonical) instead. The decode now plans the keyframe and compares its size with h × w before it decodes a symbol of it, as declared_cost does; integer-payloads §7 lists the check at step 4. The Rust verifier (wai_int_payload_vectors verify) also requires declared_cost to refuse each decode-layer fixture with the decode's code, unless that code comes from a stream or a network run. Fixtures: wiv1_geometry_flip_* (seven), wiv1_geometry with one byte of its keyframe's last stream words changed, each geometry_mismatch, regenerated through the generator; the Python verifier checks that they parse. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: a granted listing authorises only the files it names
Outside the integer path, an unpinned decode at a sink whose key log holds the capability's sets to jwp-receipts §7.9 read the registered path and any file beside it once check 5 had passed, so a granted listing naming one file authorised every other file in its directory. The registry now reads, once each, the sets that could identify what the decode reads (the registered file for a one-file capability, and each listing beside it whose files all match), runs check 5 over their digests and, for a capability held to §7.9, hands the decode only the set §7.9 authorised (neural::ParamSource::Authorised). The decode reads nothing else, as a pinned decode does: a file outside the set is set_incomplete. A key log that only revokes leaves the decode reading the path, as before. pin::PinAuthority gains requires_grant, with a default; SinkKeyLog answers it from its relying party. SPEC §4 (Module authorisation) states the rule. Test: neural_native_decode::a_granted_listing_authorises_only_the_files_it_names (the decoder's listing beside unauthorised tables, a directory's listing of another file, a listing of both, a one-file grant, a revoking log). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the one-frame preflight clip has the canonical header
Some checks failed
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 44s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m2s
wai formal verification (integer core) / kani (pull_request) Successful in 4m10s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m0s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m16s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m9s
WAI section references / cited sections exist (pull_request) Successful in 11s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m51s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m46s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 6m30s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m28s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 2m1s
standards workspaces build + test / arl-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-ui-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Has been cancelled
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Has been cancelled
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
A one-frame WIV1 carries block 1 and mv_precision 1 (integer-payloads §3). The starved one-frame clip in tests/int_payload_preflight.rs had block 2^32 - 1, so it was refused as field_range at parse, before the decode it exists to measure. With block 1 it parses and is refused at its first exhausted symbol, as the test asserts. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: receipt decode refusals are codes; the Python decode allocates as it goes
- video_receipt::decode_wiv1 reports a decode refusal by its code (stream_exhausted, stream_noncanonical, field_range), as it already did for a parse refusal, not by a sentence. - int_payload_verify.py grows each frame as its symbols decode instead of allocating it before the stream is read. - The receipts workflow runs when the refusal fixtures its test reads change. Test: video_receipt::decode_wiv1_reports_refusal_codes (the run-out and unread-word fixtures, and a JSON form). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: an encrypted integer payload is checked after decryption
The emit paths parsed an encrypted envelope's payload as the integer format, so a ciphertext WIV1 could not be written. Under SPEC §6 the payload is ciphertext and a sink decrypts it before dispatch (§6.4). Wai::check_int_payload_framing and WaiMulti::check_int_payload_framing (and so to_emit_bytes and the C packers), and wai-web's pack and packMulti, skip the check when the manifest's security.encryption is neither absent nor "none" (container::manifest_v2_plaintext reads a WAI2's security member); the decode checks the plaintext. wai-rs has no decrypting path, so no check runs after decryption here. `wai inspect` reports such a payload as encrypted rather than as parsed. The extension and the CHANGELOG say so. Tests: container::tests::an_encrypted_integer_payload_is_emitted (WAI1 and WAI2; the same bytes in plaintext are refused), the wai-web writers' test (extended), cli_wrap_intent (inspect, extended). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the debug JSON readers refuse instead of panicking
wai-web's decodeIntHyper and decodeIntHyperBin read the conditional
codec's JSON through panicking readers and the unchecked decode, so {} or
a hyper-latent of 2^61 elements panicked the page.
- IntModel::try_from_json and CondBitstream::try_from_value read what
from_json and from_value read (an absent number as 0, as before) and
refuse a member of the wrong type, a size that does not fit, or an
unknown layer type.
- The browser's JSON decode goes through them, CondEntropy::try_from_value
and decode_conditional_checked.
- int_video::VideoJson refuses a frame whose motion vectors are not a
list instead of reading it as empty; the Python converter refuses it too.
Tests: wai-web neural_int::tests::the_debug_json_decode_refuses_instead_of_panicking
(the reviewer's {} and 2^61 cases, too many z channels, and the committed
JSON models decoding alike) and
int_payload::tests::a_frame_entry_that_is_not_a_list_is_refused.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the splat converter carries integer ranges exactly
A JSON integer range past 2^53 was read through f64 and rounded (2^60 + 1 became 2^60), so the converter wrote a range the JSON did not state. An integer Number is now read only where an f64 holds it exactly, and then must be a binary32 value like any range; otherwise it is refused (field_range), as the Python verifier refuses it. Test: int_payload::tests::splat_integer_ranges_are_carried_exactly (2^60 converts exactly; 2^60 + 1 and its negation are refused). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: a one-frame WIV1 has one header
A one-frame clip codes no motion vector, so its mv_precision and block changed nothing and let one clip have many headers. The parser (and the Python verifier) now requires mv_precision 1 and block 1 for a one-frame clip (field_range), after the other header fields; the converters write them so. The one-frame end-state fixture is regenerated with that header, and two fixtures refuse block 4 and half-pel. integer-payloads.md §2 now says that a payload's hash identifies the payload, not its output: table entries the stream never selects code the same clip in other bytes, so one output is identified by its decoded digest (a clip's clip_hash). Test: int_payload::tests::a_one_frame_clip_has_one_header (the reviewer's six headers; the converter's canonical header), and the fixtures wiv1_one_frame_block and wiv1_one_frame_mv_precision in both verifiers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the header bounds an integer decode's work, and a sink reads it first
A payload carries its own tables, so a fully valid 3 KB WIV1 decodes a 2^30-byte clip, and a 384-byte WIA1 held gigabytes to present one sample. The stream's length does not bound the work; the header does, within the caps, and a sink applies its own size policy before decoding. - int_payload::declared_cost(cap, payload, params): the output bytes, the symbols, and the most bytes the reference decode holds at once beside the payload and the parsed set, from the header and the set's layer geometry, with the refusals a decode gives before its first symbol. container::declared_size reads the header alone (no feature, no set); the C ABI has wai_int_payload_declared (wai_int_declared_t) and wai-web intPayloadCost. - Each decoder's pre-decode checks are one plan function the decode and the cost share (cond_plan, audio_plan, splat_plan, int_video::check); networks are planned with their live buffer sizes (plan_net). Latents and frames grow to their declared size and no further, and spent buffers are dropped, so the declared figure is what the decode holds. - WIA1: the latent must be the one t_out needs: the synthesis of lat_len gives at least t_out samples and that of lat_len - 1 fewer (geometry_mismatch). Fixture wia1_latent_too_long. - integer-payloads.md §7 states the bound: output, symbols and buffers with their bytes per element, read before decoding; a short stream stops at its first missing symbol; a sink's policy refuses past what it will spend. The claim that work grows with what a stream carries is gone, here and in the CHANGELOG. Tests: tests/int_payload_cost.rs (own binary, live-bytes allocator; CI fast-kernel steps): the declared working bytes bound what each committed decode holds and equal it for keyframe-0 WIV1, including, in release, the 3 KB clip at the cap (declared and held both 1073445624 bytes); tests/int_payload_preflight.rs refuses the reviewer's 384-byte WIA1 (geometry_mismatch, before a symbol, and by declared_cost); ffi_envelope::int_payload_declared_reads_the_header; wai-web the_declared_cost_is_read_before_decoding. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: check 5 covers every identity of the bytes a pinned decode reads
Check 5 ran over the pin's digest only, so a revocation of model.wam's file digest was bypassed by a set-form pin over a listing of that one file, and a revocation of a set's listing by a pin over its members plus a README. After a pin verifies, int_payload::resolve and the neural registry's verify run check 5 again over every identity of the bytes the decode reads (int_payload::read_identities: the listing of the members read and a one-file set's file digest) together with the pin's digest, which keeps a granted pin authorised. SPEC §3.1 check 5 says so. Tests: int_payload::tests::a_pin_by_another_identity_does_not_reach_a_revoked_set (both probes) and neural_native_decode::a_pinned_set_revoked_under_its_file_digest_is_refused_through_a_listing_pin (added to the neural gates step). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: a listing beside an unpinned set counts only when it matches the files read
The neural sink's unpinned check 5 hashed every *.sha256 beside the registered path without reading it, so a copy of a granted listing beside other files authorised them. Each listing is now read as a pinned set's would be: for an integer capability through int_payload::unpinned_read over the members the decode reads (and any other file it names, from beside it), counting only when it names every member read with its digest; for another capability, every file it names must match on disk and it must name the registered file. A listing that does not match is refused (set_malformed, part_mismatch) and contributes no digest. Test: neural_native_decode::a_listing_that_does_not_match_the_files_read_authorises_nothing (added to the neural gates step): a granted listing beside other files is not authorised, for a several-file and a one-file integer set and for a capability outside the integer path; the granted files beside it decode. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the integer-payload pin, as SPEC §8 now permits it, and what is final
Some checks failed
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 46s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m7s
wai formal verification (integer core) / kani (pull_request) Successful in 4m26s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m1s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m15s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 57s
WAI section references / cited sections exist (pull_request) Successful in 11s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m51s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m43s
standards workspaces build + test / jouleclaw-rs (pull_request) Has been cancelled
standards workspaces build + test / aac-rs (pull_request) Has been cancelled
standards workspaces build + test / arl-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-code-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-ui-rs (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Has been cancelled
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Has been cancelled
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
- SPEC §8 gains *Completing a registration*: a revision may complete the registration of a WAI-native string whose row named a decoder and fixed no byte layout by pinning one; envelopes carrying another form become non-conforming, still parse, and are listed in §5; "fixed forever" starts at the pin. SPEC §5, integer-payloads.md §1 and §11, REGISTRY and the CHANGELOG cite it, no longer say the pin redefines nothing, and say that wai.neural.int_hyper's and wai.video.int_hyper's rows named their decoders only. - integer-payloads.md §8: a refusal of the payload or of the set against it is final; set_incomplete, not_dispatchable and unsupported_capability route as SPEC §4 routes a capability the sink cannot decode. The neural sink now moves on to the fallback (WAI1) or the next entry (WAI2) when the build has no decoder for the capability, as it does for set_incomplete. - SPEC §4 and jwp-receipts §7.9 name int_payload::resolve as a place check 5 runs. The CHANGELOG says what JSON the deprecated JSON entry points now refuse, flags the breaking API changes (neural::Decoded gains Int and is non_exhaustive; ParamSource and IntParams), and names the integer capabilities instead of counting them. - The int_hyper demo says it decodes the export tool's debug JSON. - Tests: the WIV1/WIA1/WIS1 equivalence tests say what they compare, and video_nk is anchored to the FNV-1a hashes recorded before this revision; the preflight's hyper-latent case now exceeds the parser's cap and says so. CI runs the conformance workflow on an edit of integer-payloads.md. Test: neural_native_decode::an_integer_capability_without_a_decoder_moves_on_to_the_fallback (added to the neural gates step). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: a network file ends at its last layer; converters check channel counts
- IntModel::from_bytes (WHM1) and AudioModel::from_bytes (WAM1) refuse bytes after the last layer, so one network has one file and one digest; integer-payloads.md §9 says so. Every committed network ends there. - wia1_from_json and wis1_from_json refuse a JSON whose medians, tables or offsets are not one per channel, instead of writing a payload out of step with its header. - The neural sink's unpinned integer decode is checked against the payload first: a JSON form beside a set that lacks a member is bad_magic, and a WIH1 is set_incomplete naming the member (the set is read once, in the first commit of this series). - ffi_neural: one string literal held a run of spaces. Tests: int_payload::tests::a_model_file_with_bytes_after_its_last_layer_is_refused, int_payload::tests::converters_check_the_channel_count, and neural_native_decode::int_hyper_decodes_through_the_neural_dispatch (extended). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: the splat converter carries each range exactly
wis1_from_json read a range within one f64 unit of a binary32 value as that value, standing in for a JSON reader that is not correctly rounded. splat_int now reads JSON numbers correctly rounded (serde_json/float_roundtrip, which `oer` already enables), and a range must be exactly a binary32 value. The Python verifier's converter already refuses one explicitly rather than through assert (earlier commit). Test: int_payload::tests::splat_ranges_are_carried_exactly (a value one f64 unit either side of the committed range is refused; the range itself converts). Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: one refusal order for integer decodes, planned alike on every target
- integer-payloads.md §7 states the order of a decode's checks: the set's members, the set against the payload, every network planned with its caps, what the networks give against the payload (per format), then each stream symbol by symbol, a run-out before the value's range. §2 says a section of one table per channel is read table by table, and field_range covers a field of any section. - The conditional decode plans h_s and g_s before it compares h_s's shape, so a 2100 x 2100 latent whose g_s would pass the cap is too_large, not geometry_mismatch. - int_hyper_synth::plan (used by the conditional and splat decodes) and the audio synthesis's plan work layer by layer in u64: parameter lengths and shifts (model_mismatch), every side and buffer within 2^26 (too_large; a size past u64 is past the cap), then an output left (model_mismatch). A 32-bit sink formed these sizes in usize and refused an overflow as a malformed model where a 64-bit one said too_large. A convolution's padded side is now capped too. - The entropy tables of a set must have 3 to 4097 entries, as §2 says (the reader took 2, and any length past 4097). - Fixtures: wia1_order_table_before_length (parse), wih1_order_caps_before_geometry and wih1_order_exhausted_before_value (decode, against sets/entropy_median_max.json, the tiny tables with a median of i64::MAX). Tests: int_payload::tests::network_plans_refuse_alike_on_every_target, int_payload::tests::entropy_tables_obey_the_table_length_rule, and the fixtures through tests/int_payload.rs and both corpus verifiers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: integer payload streams must end canonically
An unread word after a rANS stream's last symbol, or a final state other than 2^31, coded the same symbols in other bytes, so one decode could have many content hashes. - rans::RansDecoder::is_canonical_end: never ran out, every word read, and the state 2^31 an encoder starts from. - Each stream of WIV1, WIH1 (both streams, nested ones included), WIA1 and WIS1 is checked after its last symbol; otherwise the payload is refused with the new code stream_noncanonical (Refusal::ALL is now 19 codes). - Fixtures: an appended word under each format, a one-pixel WIV1 coded from the state 2^31 + 1 (its canonical twin, coded from 2^31, decodes to a grey pixel in both verifiers), and a one-frame keyframe-1 WIV1 whose empty residual stream is not the state 2^31 alone. The Python verifier checks the end of every stream it decodes. - Every committed stream ends canonically; integer-payloads.md §2 and §8 state the rule. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: integer decodes do only the work their streams back
A 120-byte WIV1 (16 frames of 4729 x 4729 and an 8-byte stream) ran for about a minute and reached gigabytes before it was refused at its last symbol, and the JSON reader panicked on a side of 2^31. - Every integer decode (int_video, int_hyper_synth's checked conditional decode, int_audio, int_splat) stops at the first symbol during whose decode its stream runs out (stream_exhausted), before the value is used. The exhaustion flag is sticky, so a stream that never runs out decodes as before. - A frame, a clip or a latent is allocated only as its symbols are decoded; int_video holds frames as RGB8 and predicts from the last decoded frame, and reserves nothing from n_frames. - WIV1 caps the frame count at 2^20 and the motion-vector field at 2^26 elements, after the frame and clip caps (too_large); refusal fixtures wiv1_too_many_frames and wiv1_mv_field, checked by the generator and the Python verifier. - int_video::VideoJson reads each size as a usize it fits (absent otherwise), and caps every size before it pads a motion-vector list. - wai-web: decodeWiv1 keeps the decoder's frames (DecodedVideo.frame(i)) rather than concatenating the clip. - The Python verifier refuses at the first exhausted symbol, applies the new caps, and refuses a non-convertible JSON source explicitly instead of through assert. - integer-payloads.md §2, §3 and §7 state the early stop, the caps and the memory bound. Test: tests/int_payload_preflight.rs (counting allocator) refuses five starved payloads, the reviewer's two WIV1 among them, at the first exhausted symbol with no allocation sized from the header, and the two JSON headers without a panic or a header-sized allocation. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: every emit path parses an integer payload as a sink does
The pinned-format check read only a payload's magic and version, and only `wai wrap` ran it, so a keyframe-0 WIV1 wrapped under wai.video.int_hyper, or a WIV1 cut short, was written. - container::check_int_payload_framing now parses the payload with the wire parser a sink runs, with the capability's keyframe kind for WIV1, and reports the first parse rule that fails (FramingError gains the failed rule). The wire module is compiled with no feature (`int_wire`, re-exported as int_payload::wire), so the container can run it. - Wai::to_emit_bytes and WaiMulti::to_emit_bytes run it, so the C packers refuse such a payload (WAI_ERR_INVALID_ARG, new EmitError::IntPayload); so do wai-web's pack and packMulti. - `wai inspect` says what it checked: every parse rule, with the decode checking the rest. The CHANGELOG and the extension say the same. - CI runs wai-web's native unit tests. Tests: container::tests::the_emit_path_refuses_an_integer_payload_that_is_not_its_format, int_payload::tests::framing_check_is_the_parser, ffi_envelope::envelope_pack_refuses_an_integer_payload_that_is_not_its_format, cli_wrap_intent::wrap_refuses_a_payload_that_is_not_the_pinned_integer_format (extended), wai-web tests::the_writers_refuse_a_payload_that_is_not_the_pinned_format. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: check 5 runs over the bytes an integer decode reads
An unpinned integer decode now reads exactly the files check 5 identified. - int_payload::resolve, unpinned: a listing the held set carries must be well formed and match its files (set_malformed, part_mismatch), and the decode reads only the capability's members it lists. Check 5 runs under the listing's digest, the digest of the listing of the members read, and a one-file set's file digest, so a set held with an empty listing is no longer decoded under a revoked digest. - IntParams is opaque: only resolve builds one that holds a set, and IntParams::none() holds none. The pinned constructors are crate-private, and the verified-reference lookup is bounds-checked. - The neural registry reads an integer capability's set once, from the paths one function gives (inside a registered model directory included), runs check 5 over those bytes and hands the decode the same bytes (ParamSource::UnpinnedRead; ParamSource is now non_exhaustive). A form-less pin over wai.neural.int_synth resolves against a directory registration too. - A member the unpinned set lacks is refused set_incomplete after the payload's framing is checked, so dispatch moves on. Tests: int_payload::tests::unpinned_check_5_covers_the_files_the_decode_reads and neural_native_decode::int_synth_check_5_covers_the_spec_a_model_directory_holds (added to the neural gates step). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main into wai/land-16-binary-payloads
Main now holds links 12 to 15. This makes main the only merge base, so the pull request's diff is this link's own change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai/CHANGELOG: the integer codecs' payloads pinned in place
A new subsection at the top of v0.4.0. It records the WIV1, WIH1, WIA1 and WIS1 payloads pinned under the existing strings, and why that is a pin and not a redefinition. It records that the JSON forms are converter inputs, lists the envelopes this makes non-conforming, and records the one integer decode path and its closed refusal codes. It also records the checked decoders, the parameter-set members and the audio and splat widenings to one file, the WIV1 identity of video receipts with legacy receipts unchanged, the jwp_hash module, the browser entry points, and the conformance corpus and CI. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ci: run the integer payload tests, generator, verifier and per-feature checks
wai-conformance.yml: - Both fast-kernel steps, with overflow checks on and off, run tests/int_payload.rs and tests/int_payload_preflight.rs beside --lib. --lib carries int_payload's unit tests, among them decode_int_without_neural, since the step's features include no `neural`. - A new unix step runs `cargo check --lib` for neural_int, video_int, audio_int and splat_int, each alone, and for wasm32 with the three media features. - The corpus loops, unix and Windows, add video_int, audio_int and splat_int to F and verify ../int-payload-conformance with wai_int_payload_vectors. - The independent-verifiers job runs int_payload_verify.py. wai-byte-equality.yml fires on int_payload/wire.rs, which the crate now includes. wai-neural-gates.yml fires on the integer decoders, int_payload and the vectors its tests read. It runs int_hyper_decodes_through_the_neural_dispatch in the model-free list, and integer_media_decode_through_the_neural_dispatch in a step with the media features. wai-web-wasm.yml checks the wasm32 decodeWiv1, decodeWih1, decodeWia1 and decodeWis1 against the committed payloads' sidecars. wai-energy-receipts.yml already fires on every change under wai/wai-rs. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-web: decodeWiv1, decodeWih1, decodeWia1 and decodeWis1
The browser crate decodes the payloads SPEC §5 pins to the integer codecs through wai::int_payload::decode_int, the Rust a native sink runs, over the parameter files the host passes in, named as a set lists them. decodeWiv1 takes the envelope's capability, so the keyframe kind is checked against it. decodeWia1's output gains sampleRate. decodeWis1's output gains nGaussians and the per-attribute ranges, which are presentation data outside the digest. A refusal's message starts with its code (bad_magic for a JSON form). The entry points that read the tools' JSON forms (decodeIntVideo, decodeIntVideoPframes, decodeIntHyper, decodeIntHyperBin, decodeIntAudio, decodeIntSplat) stay, and are documented as for debugging and conversion. A native test decodes every committed payload through the crate's path to its sidecar's SHA-256. demo/verify_int_payload_wasm.mjs does the same in the wasm32 build under Node and checks that a JSON form is refused. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: SPEC §5 pins the integer codecs' payloads; extensions/integer-payloads.md
SPEC §5 gains *Payloads of the WAI-native integer codecs*. It pins WIV1 to wai.video.int_motion (keyframe 0) and to wai.video.int_hyper (keyframe 1), WIH1 to wai.neural.int_hyper, WIA1 to wai.audio.int_codec and WIS1 to wai.splat.int_codec, each with its parameter set. These rows named a decoder and the tool that wrote a bitstream, and no byte layout, so the pin completes their registration and redefines nothing. The JSON the tools write is a converter input; an encoder must not carry it under these strings. The subsection lists the envelopes the pin makes non-conforming; they still parse. The passages the pin contradicted now say what holds. The §5 introduction no longer says that every payload is a codec's own bytes. The neural introduction no longer says that the standard specifies no neural payload layout. The integer rows name their formats, and name the tools only as writers of converter input. The parameter-set paragraph names the members the integer decoders read and registers wai.audio.int_codec (model.wam) and wai.splat.int_codec (g_s.whm) as one file; that is the widening the code made. The prior-carriage §7 table gives the same members. REGISTRY.md's definition of "registered" says these strings got their formats in v0.4.0. The README says the payloads are binary and the JSON is converted. extensions/integer-payloads.md defines each layout field by field, the rANS stream and CDF table rules, the order of the checks, each decode, the caps and the checks a decode makes, the closed list of refusal codes, the parameter sets, the converter rules for the JSON forms, and the reference implementation. codecs::registry's spec_pins_the_integer_payloads_the_registry_lists holds SPEC's table to PINNED_INT_PAYLOADS and to each set's registered shape and members, and the extension to one section per format. `wai registry export --check` passes with nothing written: no exported field records a set's shape. Co-Authored-By: Claude Opus 5.5 <[email protected]>
byte-exact-conformance: WIV1 and WIH1 goldens over the committed payloads
The crate #[path]-includes int_payload/wire.rs, which uses nothing from wai-rs, and parses the committed binary payloads with the parser a sink runs. It decodes them through the checked typed decoders: - the WIV1 keyframe-0 clips, synthetic and half-pel real footage; - the WIV1 keyframe-1 clip, whose nested WIH1 keyframe decodes from the tiny conditional codec's compact networks and entropy tables; - the WIH1 payload alone. Each payload is pinned by its SHA-256. Each decode must give, on every leg of the matrix, the per-frame, clip and image SHA-256 that the vectors' sidecars state and that the JSON forms' goldens decode to. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: a wai.video.int_motion receipt identifies its WIV1 payload
VideoReceipt::seal_decode_wiv1 decodes a WIV1 payload (keyframe 0) and seals a receipt whose codestream hash is BLAKE3 over the payload, the bytes an envelope carries. verify_reconstruction_wiv1 re-derives it from the payload alone. video_receipt::decode_wiv1 parses with int_payload::wire and decodes through int_video::decode_typed. seal_decode and verify_reconstruction, which read the tool's JSON form, are deprecated and unchanged. Every receipt sealed over the JSON form, and every pinned digest of one, still verifies byte for byte. wai_video_meter meters and seals the WIV1 payload. Given a JSON bitstream, it converts it first, so its receipt identifies the converted payload. tests/video_receipt.rs: a WIV1 receipt carries the same frames, clip commitment, geometry and work as the JSON form's receipt. Neither receipt vouches for the other's codestream. A one-byte change is refused. The signed bytes of metered, unmetered and chained WIV1 receipts are pinned as introduced. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: wai wrap refuses, and wai inspect reports, a payload that is not its integer format
`wai wrap` writes nothing when the payload for an integer capability is not the format SPEC §5 pins to it, as `container::check_int_payload_framing` reads it (magic, then version). This covers the WAI1 capability, a WAI1 fallback whose decode reads the same payload, and every WAI2 component. A tool's JSON output is converted first, never wrapped. `wai inspect` prints the framing check for an envelope that names an integer capability, and its code when the check fails. tests/cli_wrap_intent.rs wraps each committed JSON form and is refused with bad_magic. It wraps a WIV1 under wai.audio.int_codec and is refused with format_capability_mismatch. It wraps every binary payload. It inspects an envelope that carries a JSON form. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: the neural sink delegates the integer capabilities to decode_int
neural::decode_payload sends wai.neural.int_synth, wai.neural.int_mlicpp, wai.neural.int_hyper, wai.video.int_motion, wai.video.int_hyper, wai.audio.int_codec and wai.splat.int_codec to int_payload::decode_int, so integer decoding has one path and that path needs no ONNX runtime. A pinned decode hands it the verified bytes. An unpinned decode reads the set's members beside the registered path, as int_synth and int_mlicpp read theirs before: the int_synth.json beside the path, and, for the other one-file sets, the registered file itself. A member that a pinned set lacks is set_incomplete, so dispatch moves on as it does for any decoder. A payload refusal is final, so the fallback is not tried. The neural/int_synth.rs and neural/int_mlicpp.rs shims are removed. Decoded gains Int(IntDecoded): integer video, PCM and splat attributes come back in the integer form their digests are taken over, never converted. Integer images still decode to Decoded::Image. The C ABI's decode_ex refuses an Int output, which no wai_decoded_t kind carries. ModelRegistry::builtin advertises wai.video.int_motion, which reads no parameter set and so has no path to register. tests/neural_native_decode.rs decodes wai.neural.int_hyper's WIH1 from its three-file set, pinned through a listing under the strict gate and unpinned. A listing without h_s.whm gives set_incomplete. The JSON form is refused as bad_magic and the fallback is not tried. The integer video, audio and splat capabilities decode to Decoded::Int with their committed SHA-256, unpinned and under a form-less pin over their one file. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: int_payload — the WIV1, WIH1, WIA1 and WIS1 payloads, and decode_int
The payloads of the WAI-native integer codecs get binary formats: WIV1 for wai.video.int_motion (keyframe 0) and wai.video.int_hyper (keyframe 1, a nested WIH1), WIH1 for wai.neural.int_hyper, WIA1 for wai.audio.int_codec (with its sample rate) and WIS1 for wai.splat.int_codec (with each attribute's presentation range). codecs::PINNED_INT_PAYLOADS maps each string to its format's magic; it is the one table int_payload and the framing check read. int_payload::wire parses and writes the four formats. It is self-contained, so the cross-architecture crate can include it. Every size is formed in u64 and capped alike on every target. A refusal is a code from a closed list (Refusal::code): bad_magic, which a JSON form gets, format_capability_mismatch, keyframe_capability_mismatch, version, reserved_nonzero, field_range, too_large, cdf_malformed, stream_length, nested_length, trailing, stream_exhausted, geometry_mismatch, model_mismatch, set_incomplete, not_dispatchable, unsupported_capability and payload_malformed. int_payload::decode_int decodes every integer capability, these five and wai.neural.int_synth and wai.neural.int_mlicpp, from parameter files held in memory (IntParams), with no ONNX runtime and no filesystem, and only through a dispatchable capability. int_payload::resolve verifies a pin over sets held in memory with pin::verify_bytes_with, and runs SPEC §3.1's check 5 over the set an unpinned decode reads, under every digest a pin over it could name. The converters wiv1_from_json, wih1_from_json, wia1_from_json and wis1_from_json turn the tools' JSON into payloads and parse what they write. wai.audio.int_codec and wai.splat.int_codec are registered with sets of one file (model.wam, g_s.whm): each decoder reads one file that holds every parameter. container::check_int_payload_framing and the Wai and WaiMulti methods check a payload's magic and version without neural_int. wai_int_payload_vectors writes each committed JSON vector's payload beside it, refusal fixtures derived from those payloads, and the index int-payload-conformance/vectors.json; `verify` regenerates them byte for byte, decodes each payload to its sidecar's SHA-256 and checks each fixture's code. int-payload-conformance/int_payload_verify.py checks the same corpus independently, in Python's standard library. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: typed, checked integer decoders that the JSON forms are read into
int_video, int_audio and int_splat gain a typed stream (VideoStream, AudioStream, SplatStream) and decode_typed. Before allocating, it checks every field, size and CDF table and caps every tensor at 2^26 elements; it rebuilds each latent with dequantize, runs each network only after checking its arithmetic on the values present, and refuses a stream that runs out before its last symbol. The same input is refused in a build with overflow checks and one without. The JSON decoders read their input into the typed form (VideoJson, AudioJson, SplatJson) and call the same function, with what the old readers left implicit stated: an absent mv_precision is 1 and only 1 and 2 are read; the first frame carries no motion vectors; a short motion-vector list is padded with (0, 0), the vector the old decoder read for a missing block; the JSON afrac must be the model's; every audio channel's table has one length; t_out may not exceed the synthesised length. int_hyper_synth gains decode_conditional_checked, CondStream and CondEntropy::try_from_value; decode_conditional is unchanged. AudioModel::from_bytes forms its sizes in checked arithmetic and reserves no more than its bytes allow. int_synth refuses a side of 2^64 or more instead of shifting by it, and int_synth::decode_bytes and int_mlicpp::decode_bytes name the byte-input entries. Every committed integer vector decodes to its committed hashes through the new paths, under every kernel policy. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-rs: hoist the JWP object content hash into jwp_hash
jwp-receipts §2.1's content hash, BLAKE3 over "moq-jwp:object\x01" and the envelope, moves out of claim_receipt into its own module, jwp_hash, gated on a new feature `jwp_hash = ["dep:blake3"]` that `receipt_claims` enables. claim_receipt re-exports it under its old names (object_content_hash, DOMAIN_OBJECT), so its public API and every caller stay valid; jwp_delivery, key_log and their corpora and tests call jwp_hash::content_hash directly. Behaviour does not change. A known-answer test pins the hash of the claim corpus's canonical fixture object to the value its independent verifier computes. Regenerating the jwp, claim and signer corpora into empty directories gives files byte-identical to the committed ones; every corpus verifies, as do jwp_verify.py, claim_verify.py and signer_verify.py; the corpora and include/wai.h have no diff after a build. joule-moq keeps its own copy of the domain and the Python verifiers keep their constants; they are separate implementations and are not touched. Co-Authored-By: Claude Opus 5.5 <[email protected]>