wai: D2c M8 — WIV1 and WIR1 through wai-ops/1's stage operators, goldens unchanged #308
Merged
dcharlot
merged 45 commits from 2026-10-18 07:19:04 -04:00
wai/d2c-m8 into main 2026-10-18
Merge origin/main into wai/d2c-m8; CHANGELOG keeps every entry
All checks were successful
wai formal verification (integer core) / kani (stage) (pull_request) Successful in 2m40s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 46m28s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 4m52s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 45m7s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 45m18s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 4s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 5m40s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m40s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m6s
wai-ops integer operators / linux-aarch64 (pull_request) Successful in 59s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 5m19s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 25s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m15s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m12s
wai formal verification (integer core) / kani (isqrt512) (pull_request) Successful in 43m34s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m12s
wai formal verification (integer core) / kani (stage-long) (pull_request) Successful in 21m19s
wai formal verification (integer core) / kani (integer-core) (pull_request) Successful in 5m45s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 2m31s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m21s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m28s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 32s
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 53s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 24s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 12s
wai-pack / wai-pack · linux (pull_request) Successful in 1m17s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m8s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m5s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m7s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m20s
Main gained wai.live.recording and wai.text.timed (#303, with #299) and a wai-quantum change (#302). The only conflict was the CHANGELOG's top insertion; M7a's and M8's entries stay first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17
Merge remote-tracking branch 'origin/wai/d2c-m7a' into wai/d2c-m8
All checks were successful
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 13m58s
wai formal verification (integer core) / kani (isqrt512) (pull_request) Successful in 46m23s
wai formal verification (integer core) / kani (stage-long) (pull_request) Successful in 22m13s
wai formal verification (integer core) / kani (integer-core) (pull_request) Successful in 5m52s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m16s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 2m43s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m23s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 32s
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 55s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 22s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 13s
wai-pack / wai-pack · linux (pull_request) Successful in 1m32s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m15s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m5s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m7s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m33s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 46m9s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 4m42s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 45m16s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 45m30s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 4s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m36s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 5m28s
wai-ops integer operators / linux-aarch64 (pull_request) Successful in 59s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m3s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 5m10s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 16s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m10s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m9s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 3m53s
Merge remote-tracking branch 'origin/main' into wai/d2c-m7a
Some checks failed
wai formal verification (integer core) / kani (plan) (pull_request) Has been cancelled
wai formal verification (integer core) / kani (sound) (pull_request) Has been cancelled
wai formal verification (integer core) / kani (stage) (pull_request) Has been cancelled
wai formal verification (integer core) / kani (rans64-t2) (pull_request) Has been cancelled
wai formal verification (integer core) / kani (stage-long) (pull_request) Has been cancelled
wai formal verification (integer core) / kani (integer-core) (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (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 conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (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 / quantum core and corpus under wasm32-wasip2 (wasmtime) (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 / delivery telemetry · CMCD and CMSD against an independent library (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 / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
wai cross-architecture byte-equality / does this change touch it (pull_request) Has been cancelled
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Has been cancelled
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Has been cancelled
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
WIV1 and WIR1 gate 7: results
On f2513980, all green: gate.sh d2c-m8-g7 GREEN (build, lib tests, carriage,
the corpus loop 21 of 21, the fast kernels, byte-exact, wai-web wasm32, the
neural gates); each integer feature alone (cargo check --lib); wai-verify's
build and lib tests; byte-exact 101.
Kani, under memguard at 48 GB and a 45-minute budget: 8 of 8 verified,
e11_up2_between_its_neighbours, e12_rdiv_matches_its_definition and
e12_rate_at_reads_only_source_samples (the predictors' proofs, moved to
the operators a decode runs), K29 on the registered ranges, and the direct
decode's own harnesses (staged_predict::, staged_wir1_arith::step_in_range),
which still compile under their new cfg.
Falsified: the test-only direct decodes broken (int_video::legacy::predict's
half-pel rounding without its +1, wir1_arith::step without its clamp). The
production decode stays green: int_video, int_video_halfpel,
int_video_keyframe, int_payload, staged_resources, cli_stage, the lib tests,
byte-exact 101, and both corpora's verify. The comparisons go red:
int_video_ops (video_real), wir1_ops (attested_across_drop L1, element 24:
255 through the operator set, 7 directly; and the refusal sweep), and both
halves of the differential. Restored.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main into wai/d2c-m7a; CHANGELOG keeps both entries
Main gained wai.live.compose (#296). The only conflict was the CHANGELOG's top insertion; both entries are kept, this one first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 7 (WIP, committed before running): the direct predictors and step leave production
The arithmetic guards of the direct decodes (their own predictors, and the
saturating step of wir1_arith) no longer run outside the test-only decode;
the stage operators carry them now.
- int_video::predict is E10 on an RGB8 frame (the encoder predicts with it,
as the decode does); the direct predictor, verbatim, is
int_video::legacy::predict, test-only.
- staged::wir1: the direct decode's pred_at and step are legacy's. The
encoder predicts with the decode's E11, E12 or the element below
(ops::prediction) and steps with E9; it refuses a stage below of the wrong
shape or element type up front. ops::{up2_prediction, rate_prediction} are
E11 and E12 on the interleaved layouts, which the staged-measurement and
staged-corpus tools now call.
- staged::predict's up2_at, rate_at, rate_index and rdiv, and the
wir1_arith module, are test-only (legacy_int; and cfg(kani), for the
harnesses that still prove them); rate_len, the rate predictor's geometry,
stays. wai-verify declares legacy_int.
- The predictors' proofs move to the operators a decode runs: wai-ops'
e11_up2_between_its_neighbours, e12_rdiv_matches_its_definition and
e12_rate_at_reads_only_source_samples, in the stage shard.
Gate 6's results, for the record (the switch at 9a377f9b): gate.sh GREEN;
the release fast-kernel step; staged_verify.py and int_payload_verify.py;
wai-web native 32 and wasm32, verify_int_payload_wasm and verify_staged_wasm
(69 of 69 cases, 146 unit stage hashes equal the native ones); include/wai.h
unchanged. Falsified with the switch live: E10's half-pel rounding without
its +1 and E12's rdiv halves toward zero turn the file-based goldens red
(byte-exact wiv1_keyframe_0_payloads_are_byte_identical, video_real frame 2;
int_video_real_footage_exercises_the_half_pel_predictor;
staged_audio_rate_ladder_is_byte_exact; wai-rs int_video_halfpel), and the
corpora (wai_int_payload_vectors verify, FAIL video_real; wai_staged_vectors
verify, the encoder's reconstruction differs from the decode); the Python
verifiers stay green. The decode cloning the previous frame for E10 turns
int_payload_cost red: int_video held 42524 bytes against 35612 declared.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 6 (WIP, committed before running): the switch, and its text
- int_video::{decode_typed, decode_pframes_typed} decode through
int_video::ops (E1, E10, E9); staged::wir1::apply_unit and
Wir1::check_streams through staged::wir1::ops (E1, E11 or E12, E9). The
int_payload decode, the staged sink, the receipts and the browser crate
reach them through these. The direct decodes, int_video::legacy and
staged::wir1::legacy, are test-only (legacy_int).
- integer-operators: §5E writes E10, E11 and E12 out; §13.5 the WIV1 and
WIR1 drivers (no graph, the step and the predictions, and their widths);
the status note names the stage-only capabilities; §15.3 item 5: none.
- integer-payloads §3 and §12 and staged-delivery A.4 cite the stage
operators; SPEC §8: no planned break; CHANGELOG.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 5 (WIP, committed before running): the 32-bit form behind a feature, held to the exact form
A stage-only decode has no fast kernel behind an interpreter. What a faster
fabric runs instead is E9's 32-bit form (§5E E9, Width): the form D3b's
integer GPU legs take. Gate 5 holds it to the exact form.
- wai-ops: residual_step_i32 and i32_form_fits behind the new i32_forms
feature (and cfg(test), cfg(kani), so the unit tests and K29 keep them);
residual_step_by_i32, E9 through its 32-bit form for a driver whose
operands are i64. wai-verify declares the feature name its included
sources test.
- wai-rs i32_forms: int_video::ops::{decode_typed_i32,
decode_pframes_typed_i32} and staged::wir1::ops::apply_unit_i32, the
drivers with E9 as a parameter.
- Parity: every committed clip and layer through the 32-bit form as through
the exact form (tests/int_video_ops.rs, tests/wir1_ops.rs), changed
streams too; the differential compares the 32-bit form on every random
case; byte-exact-conformance (i32_forms on by default) decodes WIV1 and the
staged sets through it to the pinned digests on every leg.
- CI: the fast-kernel steps carry i32_forms, appended so gate.sh's grep
still finds them.
Gate 4's falsification, for the record: ops::frame's block grid taken as
w / block, which only a grid with a partial last column reaches (every
committed clip's sides are multiples of its block). Gates 1 to 3 stayed
green (int_video_ops 5, wir1_ops 5); int_video_random_clips_decode_alike
failed at seed 3372 (h 5, w 3, block 4). Timed 300 s, seed 20261017: debug
2,402,935 clips and 408,439 layers, release 11,948,953 and 3,322,036,
alike.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIR1 gate 4: a layer whose damaged stream the parser refuses is counted, not decoded
The damage can cut a one-word stream below 8 bytes, which the parse refuses (stream_length) before either decode runs. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 4 (WIP, committed before running): the differential against the direct decodes
tests/int_ops_differential.rs gains two halves, each behind its decoder's feature (video_int, staged), which the fast-kernel steps and now the nightly workflow carry: - int_video_random_clips_decode_alike: random clips (partial block grids, both precisions, q to 65535, tables of 3 to 64 entries at offsets to the ends of i32, vectors anywhere in i16, keyframe 1 with its I-frame, escaped and extreme residuals, a broken field one clip in 64, damaged streams) through int_video::ops and int_video::legacy: the same frames or the same refusal, and no panic. - wir1_random_layers_apply_alike: random layers of every kind and predictor (rates to 2^20, small tables so most residuals escape, q to 65535, one table or one per unit) coded by the reference encoder, a stream damaged one layer in eight, a unit applied to another shape or type one in sixteen: every unit and the streams' check alike, no panic. There is no planned break: integer-operators §15.3 lists none for these decoders, so the oracle is equality. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 gate 3: the sink's parameters outlive the call; the changed-stream sweep thinned
The sweep cut the clip's stream at every word and changed every seventh byte, 6684 cases of two decodes each (64 s in a debug build). It now cuts at each of the last 64 words and every 61st word before them, and changes every 31st byte: 682 cases, 7.5 s. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 3 (WIP, committed before running): refusal parity, the ops members, SPEC's citations
- Refusal parity. tests/int_video_ops.rs: every committed WIV1 fixture the
decode refuses (int-payload-conformance), refused alike by both decodes with
its code and by the sink; one fixture per refusal of the decode in its
order; the stream cut at every word, and bytes changed across it.
tests/wir1_ops.rs: every committed layer's streams checked alike (the
corpus's stream_exhausted and stream_noncanonical cases with their codes);
A.4 step 1 broken once per rule for each predictor; a coded layer of each
kind and predictor cut at every word, a word appended, every byte changed.
- Registry: wai.video.int_motion and the four int_refine capabilities carry
an ops member with no graph, { wai-ops/1, stage: rans64 t4097 lenient
canonical }. OpsMember's profile, subset and lowering are optional; the
schema requires set, the three together, and a lowering or a stage.
- Text: integer-operators §11 (a member with no graph), SPEC §5 (the
int_motion and int_hyper rows, the refinement table) and §7
(StandardDefined), CHANGELOG.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIR1 gate 2: a unit that differs is reported at its first differing element
Gate 2's falsification (E12's rdiv rounding halves toward zero) printed both units in full. Results, both falsified red and restored: - E10's half-pel rounding without its +1: int_video_ops, video_real differs (the whole-pel clips, the 65 staged bases and video_nk alike); byte-exact wiv1_through_the_stage_operators_is_golden, video_real frame 2; the file-based goldens stay green (pre-switch); wai-verify vectors verify, stage/mc_predict.jsonl line 17. - E12's rdiv rounding halves toward zero: wir1_ops, audio_flac_rate_ladder L1 unit 0 (-272 against -273); byte-exact staged_sets_through_the_stage_operators_are_byte_exact, the audio set; wai-verify vectors verify, stage/rate_predict.jsonl line 1. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 2: the crate's rANS decoder is imported only where the direct decode runs
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 2 (WIP, committed before running): the decodes through the stage operators
- wai-ops: E1's symbol decode takes its table in any width (Rans::symbol_in;
symbol is it over a Table); E10, E11 and E12 gain their per-element forms,
mc_predict_at, up2_at and rate_at, which read a frame, a picture or the
source samples in whatever layout the driver holds them, so a decode forms
no copy. mc_predict, up2_predict and rate_predict are them over a Tensor.
- int_video::ops::{decode_typed, decode_pframes_typed}: one E1 decode of the
residual stream (t4097, lenient, canonical), GREY or E10 for the
prediction, E9 on [0, 255]. The direct decode moves, unchanged, into
int_video::legacy; decode_typed and decode_pframes_typed still call it
(the switch is gate 6).
- staged::wir1::ops::{apply_unit, check_streams}: E1 per unit, identity, E11
or E12 for the prediction, E9 on the kind's range. The direct decode moves,
unchanged, into wir1::legacy; A.4 step 1 (the unit's geometry) is shared.
- Goldens: tests/int_video_ops.rs, every committed WIV1 payload (the staged
bases among them) through the stage operators as directly, and the three
vectors and the keyframe-0 JSON forms to every committed digest;
tests/wir1_ops.rs, every committed WIR1 layer's every unit as directly, and
each layer's stream check; byte-exact-conformance,
wiv1_through_the_stage_operators_is_golden and
staged_sets_through_the_stage_operators_are_byte_exact, with the pinned
constants.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 gate 1: the 4098-entry table breaks only its length
Its entries were not strictly increasing, so E1 refused it for that too, and the case could not tell E1's length bound from the payload's. They now rise by 15, and only the length is past the rule. Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 1: a test's payload bytes outlive the parse that borrows them
Co-Authored-By: Claude Opus 5.5 <[email protected]>
WIV1 and WIR1 gate 1 (WIP, committed before running): the stage forms
A clip and a refinement layer run no network, so neither has a lowering or a bounds certificate (integer-operators §13.5: graphs none). Gate 1 for them is the stage form: the operands each decode hands each stage operator. - int_video::ops::stages: E1 rans64_decode (t4097, lenient, canonical) on the clip's table and offset; E10 mc_predict at mv_precision; E9 residual_step with q on [0, 255]. - staged::wir1::ops::stages: E1 per unit; the prediction (identity, E11 up2, E12 rate); E9 with q on the unit kind's range. - wai-ops: E1's table rule reads its entries as i64 from whatever width a parser keeps them in, so a driver checks its table without a copy. - tests/int_video_ops.rs and tests/wir1_ops.rs: every committed WIV1 payload and WIR1 layer has its stage form; E1's t4097 rule is each payload's table rule; the stage vectors cover the modes and ranges used. Both run in the fast-kernel steps. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-ops: K27's narrower harnesses withdrawn; K27's totality stays kani_open
All checks were successful
wai-ops integer operators / linux-x86_64 (pull_request) Successful in 1m4s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m29s
wai-ops integer operators / wasm32 under Node (pull_request) Successful in 23s
wai-ops integer operators / wasm32-wasip2 (wasmtime) (pull_request) Successful in 30s
wai-ops integer operators / independent checker (Python) (pull_request) Successful in 12s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 13s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 26s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m18s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m14s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m36s
wai-pack / wai-pack · linux (pull_request) Successful in 1m31s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m30s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m17s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m55s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 14m24s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 16m44s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 49m4s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 6m11s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 48m16s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 48m25s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 6s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m54s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m40s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m13s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m42s
wai-ops integer operators / linux-aarch64 (pull_request) Successful in 1m5s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 27s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m22s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m24s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m13s
None of the narrower windows fits a memory budget. On the build host, under memguard: the existing kani_open harnesses (16-byte streams, a span or a row of up to 5) grew past 48 GB (peak resident 76 and 91 GB); one over a 10-byte stream with a span and a row of 3 past 40 GB (57 GB); and the latent and the hyper-latent harness over 8-byte streams with 2 positions each still ran past 25 minutes and 24 GB. Each was stopped. Run in the stage shard, any of them would take its runner's memory, so they are withdrawn and K27's totality harnesses stay kani_open as on main. The stage shard's k27 and k28 harnesses that do fit (k27_mans_bounds_are_unsigned, k28_mans_entry_fields) verify. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge remote-tracking branch 'origin/main' into wai/d2c-m7a
origin/main at bea79dc6 (the live-room, live-events and capture-binding extensions,
#284 to #288 among them). CHANGELOG: both sides kept, this branch's section first.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-ops: K27 split into a latent and a hyper-latent harness over 8-byte streams
The harness over a 10-byte stream with a latent span and a hyper-latent row of 3 also grew past its memory guard on the build host (40 GB; peak resident 57 GB) and was stopped. It is replaced by two harnesses over 8-byte streams, a span of up to 2 and a row of up to 2. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-ops: K27 at a window a CI shard can hold
The two K27 totality harnesses (16-byte streams, spans of up to 5) are kani_open: on the build host each grew past a 48 GB memory guard (peak resident 76 and 91 GB) and was stopped. k27_mans_is_total_small checks the same property on 10-byte streams, a latent span of up to 3 positions and then a hyper-latent row of up to 3 symbols from the same window; the stage shard's filter (proofs::stage::k27) runs it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai: the CHANGELOG names the retired duplicates
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge remote-tracking branch 'origin/main' into wai/d2c-m7a
origin/main at f18ce9ac (#275, #278, #280, #281, #282, #283). CHANGELOG: both sections
kept, this branch's first.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 7: results
Results (build host, release, pinned inputs, no skip): tests/jpegai_ops.rs 9 passed;
the CI trio (jpegai_e2e_full, jpegai_reconstruction_binding, jpegai_cross_platform:
all 9 hashes and WAI_JPEGAI_EXPECT_SHA256); jpegai_e2e_frontend and jpegai_e2e_chroma;
jpegai_hyperscale_calibration on both planes (max|Δ| = 0); jpegai_mans_golden 12 passed
on E8 alone; the neural dispatch 3; the float path (jpegai_e2e, jpegai_live 5/196608 at
1 LSB, jpegai_scope_ort); byte-exact jpegai_golden 2; wai-ops' bundle tests 2;
jpegai_memory (front half luma 2,114,160 against 2,218,884, chroma 1,290,864 against
1,357,586); the differential, 1,500 cases, no disagreement. Each build's cargo check
(neural_int; neural_int,legacy_int,provenance; neural; the differential's features;
the default features with neural; wai-web; the byte-equality crate) adds no warning.
Falsified: the test-only direct mANS port refills its window to 48 bits instead of 56.
Production green (the CI trio, byte-exact's E8 golden); the comparisons red:
jpegai_ops 4 of 9 (the planes, the whole decode, both stream-parity tests), byte-exact's
direct-port golden, the differential ("Luma: the two decodes differ", seed
10208061212434326836). Restored: green.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 7 (WIP, committed before running): the direct path leaves production; the duplicates go
The duplicate ports neural/jpegai_hyper.rs and neural/jpegai_mans.rs, which the float decode path ran its front half with, are deleted (O10): that path runs the shared driver since the switch. The direct pieces of the exact decoder leave production, test-only (legacy_int): the crate-root mANS port (jpegai_mans), the hyper-scale network (jpegai_synthesis::decode_hyper_scale and its convolution) and the pipeline's skip_mask, rvs_additive, rvs_likely and sigma_index. The calibration tests that read them require legacy_int. jpegai_mans_golden runs on E8 and the scale graph alone; jpegai_e2e (the float chain against the reference PNG) takes its front half from the driver, still checking the dumped RVS additions, masks and residuals; the byte-equality crate drops the neural port and keeps E8 and the direct port. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 6: the switch, its text and its memory
Results (build host, release, pinned jpegai/v1 inputs, no skip): - tests/jpegai_ops.rs 9 passed (the whole decode through the operator set equals the direct decode at all 7 stages and WAI_JPEGAI_EXPECT_SHA256; the stream parity on the committed bundle 4 alike / 326 refused where the direct decode panicked, on jpegai/v1 39 / 291; every kernel policy alike). - The file-based goldens, now through the operator set: jpegai_e2e_full, jpegai_reconstruction_binding (the pinned pixel hash), jpegai_cross_platform (all 9 hashes), jpegai_e2e_frontend and jpegai_e2e_chroma, jpegai_hyperscale_calibration on both planes (max|Δ| = 0), jpegai_mans_golden 13, byte-exact jpegai_golden 3. - The neural dispatch: the exact bundle decodes; an absent bundle takes the float path; a bound of 256 is reported as model_mismatch and does not fall back; a missing member is set_incomplete. - The float path through the shared driver: jpegai_e2e and jpegai_live 5/196608 samples at 1 LSB, as before; jpegai_scope_ort green. - Memory (reference kernels): the direct decode held 175,465,380 bytes; with the scale path loaded beforehand (14,083,663 bytes to load, 7,557,178 held) the decode through the operator set held 175,465,380. Each plane's front half alone: luma 2,114,160 against 2,218,884 directly, chroma 1,290,864 against 1,357,586. The test now asserts both. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 6 (WIP): a plane's masks and σ_idx are formed into its spans
The front half held about 10% more than the direct computation (luma 2,445,680 bytes against 2,218,884; chroma 1,489,776 against 1,357,586): every mask and σ_idx was held twice while the latent decoded, once as the plane's and once in its span. They are now formed into each channel's span and taken back after the decode. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 6 (WIP): the text, and the front half's memory reported
integer-operators: the status note names jpegai's scale path and entropy decodes; §15.3 item 4 adds the acc32 refusal, the order (scope, bundle, streams) and that a refusal is not replaced by the float path. determinism-tiers §5: both paths decode the claim's stages through the operator set at acc32; the two codes; a sink holding the bundle reports the exact decode's refusal and does not fall back (O9). SPEC §5's row and §8's planned breaks; the capability constant's comment; CHANGELOG. tests/jpegai_memory.rs also reports each plane's front half through the operator set and directly. First run (before this): the direct decode held 175,465,380 bytes; with the scale path loaded beforehand (14,083,663 bytes to load, 7,557,178 held) the decode through the operator set held 175,465,380; loading and decoding in one call 183,012,574. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16
jpegai gate 6 (WIP): the fast-kernel scale test lives in jpegai_ops; the memory test
The byte-equality crate includes int_ops.rs without jpegai_ops, so the scale path's fast-kernel test moves into jpegai_ops' own test module. tests/jpegai_memory.rs (own binary, a live-bytes allocator, the pinned bundle): with the scale path loaded beforehand, the decode through the operator set holds no more than the direct decode; named in wai-jpegai-e2e.yml. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 6 (WIP, committed before running): the switch
jpegai_decode::{decode, decode_with_stages} decode through the integer operator set and
return Result<Rgb, Refusal>; load and decode_loaded run a scale path loaded once. The
direct decode is jpegai_decode::legacy and jpegai_ops::legacy, test-only (legacy_int).
The neural sink's exact path lowers and loads the scale path from the members' bytes
through the store of loaded sets (int_set_cache, keyed by the listing of norm.json and
weights/hs_{y,uv}.json); a refusal of the exact decode (model_mismatch, stream_exhausted,
or set_incomplete for a member the set lacks) is the decode's result and does not fall
back to the float decode (O9). Only an absent bundle, or a target or floating-point
environment the float stages cannot run in, takes the float decode.
The float decode path (neural::jpegai) runs its scale path and entropy decodes through
the same driver (jpegai_ops::plane, O10), from its own bundle's members; one whose
hyper-latent offsets are not 31, or that fails a load check, is refused.
The browser crate's decodeJpegAiMans decodes through E8 (jpegai_ops::latent_span) and
throws on a refusal; decodeJpegAiFull reports the decode's refusal.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 4 (WIP): a shift past 63 is an acc32 refusal, not a break of its own
acc32 holds every shift to at most 63 (integer-operators §7.1), so a bundle with a shift of 64 to 127 is refused at load under the capability's profile; the classifier's acc32 kind covers it. The first release run: 1,500 cases, planes decoded alike 226, refused where the direct decode panicked 2,194, computed on 0; breaks acc32 55, bounds 27, cdfs 36, dims 51, gains 24, per_channel 16, pmf 34, shift (128) 47. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 4 (WIP): shifts past 8 drawn per network, not per element; gate 5's tests
The first per-push run reached no decodable case: a shift of 128 drawn per element (1 in 64, over 2,560 elements) put nearly every bundle under a load check. One network in about eight now has one shift of 31 to 40 per block, and one in 64 a shift of 64 to 127 or of 128. Gate 5 (WIP, committed before running): int_ops' equivalence tests run the committed bundle's scale graphs on the fast kernels under every fast policy (three convolutions each, every value the interpreter's, z over [-31, 32]); tests/jpegai_ops.rs holds both planes' integers to the reference policy under every fast policy, on the committed and the pinned bundle, payloads whole and cut. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 4 (WIP): the generator draws chroma's channel counts first
Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 4 (WIP, committed before running): the differential against the direct computation
tests/int_ops_differential.rs gains the jpegai half: random bundles (pmf rows of widths 1 to 64, bounds among 0, 1, 2, 4, 30, 127, 128, 200 and 255, CDF rows, gains that put most, some or no positions coded, scale networks of 1 to 3 channels between blocks, with shifts up to 40 and, rarely, weights of 2^20, shifts of 64 to 128 or wrong dims) and random or damaged payloads (the committed codestream's, cut, lengthened at the front, bit-flipped, or random bytes). Outside the planned breaks, both planes' integers equal the direct computation's, or the stream is refused (stream_exhausted) where the direct computation panics with overflow checks on; a planned break (a load check, acc64 but not acc32, or a shift of 64 to 127 that now has its exact meaning) is classified from the members alone, and refused from the bytes and from the parsed bundle alike. The nightly workflow's header names it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge remote-tracking branch 'origin/main' into wai/d2c-m7a
origin/main ata76522da: #274 (M6, this branch's base) merged as80477972, and #262, #272, #276 and #277, none of which touches wai/. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 3 (WIP): the stream-parity test lengthens payloads too
On the committed bundle every cut stream runs out (its tables are not the ones the test codestream was coded with), so the test had no case decoded alike. Payloads lengthened at their front (16, 256, 4096 bytes) decode further before they run out. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 3 (WIP): the registry export; the new constants kept out of the C header
registry/capabilities.json regenerated (wai registry export): wai.image.jpegai's ops member. The stage constants (the coded threshold, the hyper-latent offset, the RVS edges and additions) and the profile are crate-only, so cbindgen does not put them in include/wai.h; jpegai_ops::stage_constants gives the first three to tests. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 3 (WIP, committed before running): refusal parity, the ops member, SPEC's citations
The registry gains wai.image.jpegai's ops member: wai-ops/1, acc32, full, jpegai-int/1 (no stage modes: mANS and the scale path's stage operators have none). Its registry test holds it, beside the NeuralIntegerExact capabilities' acc64 members. SPEC §5's row cites integer-operators §13.6.1 and jpegai_ops.rs; SPEC §7's NeuralEntropyExact entry says the stages its class covers decode through the operator set at acc32. tests/jpegai_ops.rs: every load check of §13.6.1 broken one change at a time (and a sum past i32 that meets acc64), refused model_mismatch from the members' bytes and from the parsed bundle; the three entropy payloads cut at every length, on the committed bundle and on the pinned one: decoded alike, or refused stream_exhausted where the direct decode panics (with overflow checks; without them it may compute on, counted); a codestream out of scope refused with check_scope's reason, before the bundle's checks. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 2: golden equality through the lowering (the payload helper's lifetime; results)
The compile fix of the gate's WIP commit (a payload helper with two borrowed inputs
needs its lifetime named), and gate 2's results.
Results (build host, release; pinned jpegai/v1 inputs fetched and checked against
tools/jpegai-e2e-v1.sha256; the reference-decoder stage fixtures rebuilt from the local
assets' dumps and checked by the unchanged tests first):
- tests/jpegai_ops.rs 4 passed, no skip: both planes' z, v, mask, likely, rvs, σ_idx
and y_q through the lowering equal the direct computation's; the whole decode through
the operator set equals the direct decode at all 7 stages and matches
WAI_JPEGAI_EXPECT_SHA256.
- jpegai_hyperscale_calibration, luma and chroma: the scale graph (acc32) vs the
reference I_s, 40960/40960 and 24576/24576 exact, max|Δ| = 0.
- jpegai_mans_golden 12 passed: E8's tables (4 golden, 32 normative), the reference
encoder's sgm and fac streams, codestream → E8, the 258-call replay, the scale graph on
both planes, the sigma chain through the stage operators.
- byte-exact jpegai_golden 3 passed (E8 on the reference stream).
- jpegai_e2e_frontend and jpegai_e2e_chroma: y_q through the operator set 40960/40960
and 24576/24576 exact; every later stage as before (U,V 3.377%, Y 1.398% at 1 LSB).
- The file-based goldens (jpegai_e2e_full, jpegai_reconstruction_binding,
jpegai_cross_platform's 9 hashes) unchanged; wai-ops 35 + 7 + 3 + 4 + 2 + 1 + 1 tests.
Falsified (Part 3.5):
- Chroma's fac decode skips the 160 luma rows' reads (a fresh decoder over only its own
96 rows). Red: jpegai_ops 2 of 4 (the planes test, Refusal { StreamExhausted,
Symbol(711) }; the whole decode, Ops(StreamExhausted)), jpegai_e2e_chroma (the same
refusal). The file-based goldens stay green: the switch is gate 6. Restored: green.
- B_y read as signed in E8. Every M7a golden stays green: no reference stream decodes an
escape at a distribution whose bound is 128 or more, so the prediction that
jpegai_mans_golden carries this row is corrected. Red: wai-verify vectors verify,
stage/mans_decode.jsonl line 12 (a vector with a bound of 128). Restored: green.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 2 (WIP, committed before running): golden equality through the lowering
jpegai_decode: each plane's integers come from a front half, the direct computation (jpegai_ops::legacy, still the production decode until the switch) or the integer operator set (jpegai_ops::plane, from the bundle's loaded ScalePath). jpegai_decode::ops decodes through the operator set: the codestream's scope, then the scale path lowered and loaded under acc32, then the decode; it refuses with the operator set's codes (Refusal::Ops). LEF's sigma is v + rvs, which is i_s + gain + rvs. jpegai_ops: PlaneSetup and plane_with (one plane from its graph, rows, tables and bounds); scale_net_of_blocks (the float path's bundle form of the same network); load_scale and fac_rows for one plane. wai-ops: lower::jpegai::scale, one plane's graph. Goldens through the lowering: tests/jpegai_ops.rs (the planes' integers and the whole decode, stage by stage, against the direct decode, and the pinned RGB hash); jpegai_hyperscale_calibration (the scale graph, max|Δ| = 0); jpegai_mans_golden (E8's tables, the reference encoder's streams, the 258-call replay, the scale graph on both planes, the sigma chain); byte-exact jpegai_golden (E8 on the reference stream); jpegai_e2e_frontend and jpegai_e2e_chroma (steps 1-4, the chroma plane discarding the 160 luma rows). Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai gate 1: the scale path's lowering from the parsed bundle, and its certificates
wai-ops: lower::jpegai is now parse_jpegai (the members of norm.json and Table 13.6-A, typed) followed by the lowering, and gains lower::jpegai_net and jpegai_net_loaded, the same lowering of a bundle already parsed, loaded under a profile without writing and parsing the graphs again; stage::mans::decode_sgm_tables decodes with latent tables built once. tests/goldens.rs holds the parsed path to the bytes path. wai-rs: jpegai_ops (new) converts the bundle this crate parses (NormTables, IntNet) to wai-ops' form and loads the scale path under acc32 (ScalePath: the two graphs, the latent tables, the rows and the gains), and decodes one plane through §13.6.1 steps 1-4 (plane); jpegai_ops::legacy is the front half as jpegai_decode computes it, test-only. NormTables' bounds and CDF rows are i64, so the load checks see what the file says rather than a value wrapped to a byte. tests/jpegai_ops.rs: the committed synthetic bundle and the pinned jpegai/v1 bundle lower, from their bytes and from the parsed form, to the committed certificates' graphs, and load under acc32. Named in wai-conformance's fast-kernels steps and in wai-jpegai-e2e.yml (pinned bundle, missing input = failure). Results (build host, release): wai-ops goldens 7 passed (the parsed lowering test on the committed set and on the pinned jpegai/v1 bundle); tests/jpegai_ops.rs 2 passed, no skip, jpegai/v1 at 3e243dc1 meeting acc32; jpegai_mans_golden 12 passed; the pinned whole decode (jpegai_e2e_full, jpegai_reconstruction_binding, jpegai_cross_platform: 9 stage hashes and WAI_JPEGAI_EXPECT_SHA256) unchanged; frontend and chroma stage tests green. Falsified: the conversion reads the depthwise block's shifts from conv1's member. Red: jpegai_ops EXIT=101, both tests at "the converted bundle is the one wai-ops parses from the bytes". Restored with git: green above. Co-Authored-By: Claude Opus 5.5 <[email protected]>
jpegai: the residual-variance bands start where the reference decoder's tables change
The exact decoder (and integer-operators §13.6.1 step 3, transcribed from it) put a block whose likely was exactly 1003, 1352 or 1937 in the next band, for its σ addition and its dequantisation multiplier. The reference decoder's own residual-variance tables (4352 entries per branch, indexed by likely; dumped from the reference decoder, and the tables the float decode path reads) change value at 1004, 1353 and 1938. The edges are now 1004, 1353 and 1938 in jpegai_pipeline and in §13.6.1; §15.3 item 4 records it. tests/jpegai_mans_golden.rs gains jpegai_rvs_bands_are_the_reference_tables: for every likely and both branches, the band the edges give selects the reference's σ addition and dequant multiplier. On test256.bin no block's likely is within 2 of an edge (the reference's likely, luma 0..1357 and chroma 0..908), so no output changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>