wai: prove integer video byte-identical, meter it, and publish the method #60
Merged
dcharlot
merged 5 commits from 2026-08-29 03:11:48 -04:00
wai/video-byte-equality into main 2026-08-28
wai: bring the neural-keyframe clip into the cross-arch matrix
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 14s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 30s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 1m5s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 14s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 1m22s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m11s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 24s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 56s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 17s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
The previous commit named this gap and left it open: `wai.video.int_hyper` — the variant whose I-frame is decoded by the *learned* conditional codec rather than as an ordinary integer keyframe — could not be driven by `int_video::decode` and so sat outside the four-platform matrix. Covering it meant pulling `int_hyper_synth.rs` in rather than adding a line, which is why it was deferred rather than bodged. It needed one more source than expected: `int_hyper_synth` depends on `int_transform::igdn`, which was not included either. `int_transform` turns out to have no crate-internal dependencies at all, so both drop in cleanly and the legs still run in about a minute with no codec libraries and no ONNX. This is the strictest composition the container has — a learned decode feeding a feedback loop. The keyframe comes out of a quantised transform network, and every later frame predicts from the previously reconstructed one, so a divergent byte in the learned synthesis does not stay in the keyframe; it propagates through the clip. Frame 0 is therefore pinned in its own test as well as inside the clip, so a regression in the conditional codec is distinguishable from one in the motion predictor rather than leaving both suspect. A side effect worth naming: including a source brings its `#[cfg(test)]` module with it, so `int_transform`'s 13 unit tests now run on linux-x86_64, linux-aarch64, macos-arm64 and windows-x86_64 instead of only where someone passes `--features`. The crate goes from 17 tests to 32. Both new sources and the `int_hyper` vectors are added to the workflow's path triggers, on the same rule as before: every source the crate compiles must be able to fire the matrix, or a change can break cross-arch equality and merge green. Verified: 32 tests pass in the conformance crate, the clip reproducing its committed hash `a5f53d477999d159`; workflow YAML parses with all four legs intact and 13 triggers.
2026-08-26
wai: publish the energy-measurement methodology (extensions/energy-measurement.md)
All checks were successful
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 2s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 18s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Successful in 25s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 51s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 34s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 17s
WAI conformance / cargo-class corpora · windows (pull_request) Successful in 1m30s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 1m16s
WAI conformance / cross-arch byte-equality · windows (pull_request) Successful in 23s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m0s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 5m21s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 6m51s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 1m5s
`jwp-receipts.md` defines `joules_micro` as "microjoules consumed producing this object". That fixes the unit and the scope of attribution and nothing else, so the field is a number-shaped hole: one implementation can write a counter reading, another a model, a third a constant, and all three are conformant, incomparable, and — worse — indistinguishable. This extension closes it. Any receipt carrying energy must declare how the figure was acquired (`HwShunt` / `ModelBased` / `Estimator`, the vocabulary the sibling receipt families already use rather than a new one for media), and must declare whether the measurement was good enough to publish. Also specified: the bracketed marginal protocol (idle bracket with standard deviation, saturating multi-thread burst, busy bracket, marginal delta divided by completions), the five bracket parameters that must accompany any published figure, and what the number is not — machine-specific, marginal over idle, scoped to what the interface reports, build-dependent, and never verifiable by re-execution. Two corrections this document forced on the implementation: **The publication bar moves from 3x to 10x, on evidence.** A later reading of the same clip at a 3.8x marginal-to-noise ratio — inside what the previous rule called "usable" — reported 2,469 uJ against 10,565 uJ from a quieter run. A 4.3x disagreement from a reading the rule had passed. The 3-10 band is sound for comparing two workloads back-to-back on one machine, where the bias applies to both; it is not sound for an absolute figure. The bias has a direction, too: a busy machine inflates the idle baseline that is then subtracted, so a poor bracket always reads LOW. An implementation reporting its own energy errs toward flattering itself, which is why the check has to be automatic. **The worked example is a failing one, deliberately.** The draft of this file carried a clean-looking bracket with an idle standard deviation and a quality ratio for the 10,565 uJ run — numbers that run never produced, because it predates the standard-deviation reporting. Inventing them in a document about measurement honesty is the exact failure the document exists to prevent, so the example is now the real 3.8x bracket, labelled as one this spec forbids publishing, with a note saying why a clean bracket is not currently obtainable on the authoring machine. The quiet row in the comparison table is marked as predating the rule rather than given a ratio it never had. Linked from SPEC.md beside the receipt sub-spec, and from the `joules_micro` row of jwp-receipts.md that it constrains.
wai: seal how the energy was acquired, and refuse to publish a bad reading
All checks were successful
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 16s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Successful in 32s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 35s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 17s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 2m17s
WAI conformance / cargo-class corpora · windows (pull_request) Successful in 2m27s
WAI conformance / cross-arch byte-equality · windows (pull_request) Successful in 23s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 2m41s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m58s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 9m14s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 23m40s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 4m47s
Two gaps found by running the meter rather than reasoning about it. **The number had no acquisition class.** `joules_micro` was a bare integer, so two conformant implementations could put a counter reading and a modelled constant in the same field and no reader could tell. `VideoReceipt` now carries `energy_provenance` using the family's existing ladder — `HwShunt | ModelBased | Estimator`, the same three names `mesh-schema` and `proof-schema` already define — rather than a new vocabulary invented for this class. The coupling is enforced in `verify()`, not merely documented: an unlabelled non-zero figure is rejected (a number nobody can compare), and so is a labelled zero (a measurement that did not happen). The class is inside the signing payload, so an intermediary cannot promote a modelled figure to a measured one. **The meter would publish a badly wrong number without complaint.** The same clip, same binary, minutes apart: 10,565 uJ/decode on a quiet box, 497 uJ while a build was running — a 21x error, in the flattering direction, caused entirely by an inflated idle baseline collapsing the marginal delta. Nothing in the output distinguished the two. The meter now computes the idle standard deviation and reports the marginal-to-noise ratio with a plain verdict (clean / usable / NOISY - do not publish / UNUSABLE - the box was not idle), warns when the burst barely rises above the machine's own fluctuation, and — the part that matters — emits an UNMETERED receipt when the figure rounds to zero or sits below the noise. A decode that measured 0 uJ did not consume no energy; it failed to measure, and saying so is the only honest report. That path was found by the coupling rule above firing on the meter's own output: it tried to seal `HwShunt` on a zero and its own receipt refused to verify. Verified: 7 receipt tests (the new one pins both halves of the coupling and that the class is signed); meter re-run end to end, sealing `HwShunt` on a good reading and an unmetered receipt on a noisy one.
wai: meter the integer video class — the last cargo class with no meter
All checks were successful
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 20s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Successful in 23s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 46s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 49s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 21s
WAI conformance / cargo-class corpora · windows (pull_request) Successful in 1m15s
WAI conformance / cross-arch byte-equality · windows (pull_request) Successful in 22s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 1m39s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 22s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 42s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 40s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 14s
Haptics, 4D splats, scores and film are metered by `wai_meter`; worlds, feeds and avatars by `wai_world_meter`; quantum circuits by `wai_quantum_meter`. Video had none, so `wai.video.int_motion` could be decoded but never accounted. This adds the JWP receipt profile and the meter binary. `VideoReceipt` follows `QuantumReceipt` exactly — codestream hash as identity, per-frame decoded-pixel hashes as the group's objects, Merkle root over them, exact recomputable work, measured joules, `parent_receipt_hash` chaining, one Ed25519 signature over the lot. What makes this profile stronger than its siblings is the preceding commit's matrix. In every other class the reconstruction is deterministic *by construction* and taken on trust; here it is deterministic *and proven on real silicon* across four architectures. So a verifier holding only the codestream can re-derive `clip_hash`, every frame hash and `work_pixel_ops` themselves — `verify_reconstruction` does exactly that — and the receipt collapses to a single field that rests on trusting the signer: `joules_micro`. The docs say which fields are verifiable and which is attested, in those words, so a reader cannot conflate them. Deliberate choices: - The receipt lives in `video_receipt.rs`, NOT in `int_video.rs`. That file is `#[path]`-included by `byte-exact-conformance`, whose three-dependency set is what lets the cross-arch matrix run everywhere in about a minute; pulling blake3 and ed25519 into it would break the very proof this profile leans on. `video_receipt = ["video_int", "world"]` mirrors `quantum_receipt`. - Work counts decoded *subpixels*, not motion-vector or residual operations. Only the output is fixed by the format — a future encoder may spend fewer residual ops on the same clip — so counting output keeps the figure comparable across encoders, and recomputation stops it being inflated to flatter an energy number. - The frame index is inside each leaf hash, not merely beside it. Inter-frame decode is order-dependent, so a receipt whose frames could be permuted without changing a leaf would vouch for a clip nobody can play. - `uj_per_kilopixel_op()` returns `None` when unmetered, never `0`. Zero would read as "this decode was free", a stronger and false claim than "nobody measured". `to_json` emits `null` to match, and without `macmon` the meter emits an UNMETERED receipt rather than an estimate. Measured on this machine (release build, real footage vector, 8 frames 96x96): idle 20.45 W, busy 54.89 W, marginal 34.45 W over 11,548 decodes in 3.54 s → 10,565 µJ per decode, 47.77 µJ per kilo-subpixel. A debug build reports 4.9x higher, which is why the meter is documented as a release-build tool. Verified: 6 receipt tests (round-trip on both committed clips, chaining, and tamper cases for every checkable field — flipped frame hash, permuted frames, inflated work, restated geometry, wrong codestream, restated energy); the byte-exact conformance crate still passes 17/17 unchanged; no new clippy warnings; default build unaffected since the feature is off by default.
2026-08-25
wai: prove integer VIDEO decode byte-identical across architectures
Some checks failed
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 21s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Successful in 24s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 34s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 50s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 40s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 14s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 51s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 42s
WAI conformance / cross-arch byte-equality · windows (pull_request) Successful in 23s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 3m7s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 53s
WAI conformance / cargo-class corpora · windows (pull_request) Failing after 12m5s
The cross-arch byte-equality matrix covered the still-image and synthesis paths — rANS, int_synth, the JPEG-AI entropy stage — but not the inter-frame video decoder. `wai.video.int_motion` was verified only by `wai-rs/tests/int_video.rs`, which is `#![cfg(feature = "video_int")]`, and no CI job passes `--features`. Measured, not assumed: `cargo test --test int_video` reports 0 tests without the feature and 1 with it. So the temporal leg of the determinism contract was asserted on four platforms and checked on none. Video is the strictest leg of that contract, not merely another one. Still-image decode is a single shot: one divergent byte is one wrong byte. Inter-frame decode is a feedback loop — each P-frame predicts from the previously *reconstructed* frame — so one architecture rounding a half-pel sample differently produces a frame that then predicts the next frame, and the error compounds for the rest of the clip. That is why per-frame hashes are asserted and not only the clip hash: they say where divergence began, which a single terminal hash cannot. - `int_video.rs` is `#[path]`-included into `byte-exact-conformance`. It needs only `serde_json` and `crate::rans`, both already present, so all four legs still run in about a minute with no codec libraries and no ONNX runtime. - `rans` is re-exported rather than included a second time. Two `#[path]` includes would compile two structurally identical but distinct types, and one-source-of-truth is the whole reason this crate exists. - Two clips: the synthetic 5x48x48 (whole-pel) and the real-footage 8x96x96, which the encoder chose half-pel for (27_960 bytes against 38_232). The real clip is the load-bearing one — half-pel bilinear rounding is the arithmetic most at risk of differing between architectures — and the test asserts the vector still *prefers* half-pel, so it cannot silently degrade into covering only the whole-pel path. The pair also separates the failure modes: a synthetic failure implicates the entropy/residual stage, a real-footage-only failure implicates the predictor. Also fixes a pre-existing hole in the workflow's own path triggers. The crate compiles five sources; only one of them (`neural/jpegai_mans.rs`) could fire this workflow. `rans.rs`, `int_entropy.rs`, crate-root `int_synth.rs` and crate-root `jpegai_mans.rs` were unwatched — the trigger named `neural/int_synth.rs`, which is a different file from the one actually included. Any of them could have broken cross-arch equality and merged green. All five are now watched, plus `int_video.rs` and its vectors. Not covered, and deliberately not papered over: `video_nk` (`wai.video.int_hyper`, the neural-keyframe variant). Its I-frame comes from `int_hyper_synth::decode_conditional`, so it cannot be driven by `decode()` — an earlier draft tried and got a slice overrun out of the rANS reader. Covering it means including `int_hyper_synth.rs` too; until that lands, the neural-keyframe leg is proven only where someone runs the feature locally. The source comment says so rather than leaving a reader to assume full coverage. Verified: 17 tests pass in the conformance crate (15 existing + 2 new), both clips reproducing their committed golden hashes; workflow YAML parses with all four matrix legs intact.