wai: the integer codecs' binary payloads, pinned in place #139

Merged
dcharlot merged 35 commits from wai/land-16-binary-payloads into main 2026-10-04 14:05:11 -04:00

2026-10-01

Transaction Science
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]>
2026-10-01 23:08:03 -04:00
Transaction Science
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]>
2026-10-01 22:50:58 -04:00
Transaction Science
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]>
2026-10-01 22:31:18 -04:00
Transaction Science
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]>
2026-10-01 22:22:38 -04:00
Transaction Science
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]>
2026-10-01 22:18:32 -04:00
Transaction Science
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]>
2026-10-01 22:14:48 -04:00
Transaction Science
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]>
2026-10-01 21:23:20 -04:00
Transaction Science
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]>
2026-10-01 21:15:43 -04:00
Transaction Science
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]>
2026-10-01 21:13:36 -04:00
Transaction Science
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]>
2026-10-01 21:10:41 -04:00
Transaction Science
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]>
2026-10-01 21:08:21 -04:00
Transaction Science
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]>
2026-10-01 21:07:11 -04:00
Transaction Science
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]>
2026-10-01 21:04:22 -04:00
Transaction Science
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]>
2026-10-01 20:47:09 -04:00
Transaction Science
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]>
2026-10-01 20:42:47 -04:00
Transaction Science
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]>
2026-10-01 19:47:27 -04:00
Transaction Science
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]>
2026-10-01 19:33:45 -04:00
Transaction Science
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]>
2026-10-01 19:29:40 -04:00
Transaction Science
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]>
2026-10-01 19:25:37 -04:00
Transaction Science
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]>
2026-10-01 19:18:08 -04:00
Transaction Science
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]>
2026-10-01 19:08:03 -04:00
Transaction Science
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]>
2026-10-01 18:52:25 -04:00
Transaction Science
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]>
2026-10-01 18:45:06 -04:00
Transaction Science
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]>
2026-10-01 15:01:02 -04:00
Transaction Science
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]>
2026-10-01 13:14:29 -04:00
Transaction Science
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]>
2026-10-01 13:14:28 -04:00
Transaction Science
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]>
2026-10-01 13:13:31 -04:00
Transaction Science
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]>
2026-10-01 13:12:44 -04:00
Transaction Science
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]>
2026-10-01 12:36:19 -04:00
Transaction Science
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]>
2026-10-01 12:35:37 -04:00
Transaction Science
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]>
2026-10-01 12:26:04 -04:00
Transaction Science
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]>
2026-10-01 12:24:33 -04:00
Transaction Science
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]>
2026-10-01 12:20:06 -04:00
Transaction Science
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]>
2026-10-01 12:19:42 -04:00
Transaction Science
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]>
2026-10-01 10:26:09 -04:00