wai: prove integer video byte-identical, meter it, and publish the method #60

Merged
dcharlot merged 5 commits from wai/video-byte-equality into main 2026-08-29 03:11:48 -04:00
Owner

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 rather than assumed:

cargo test --test int_video                      -> 0 passed
cargo test --test int_video --features video_int -> 1 passed

So the temporal leg of the determinism contract was asserted on four platforms and checked on none.

Why video is the strictest leg, not just 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. An architecture that rounds one 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.

What is covered

clip shape motion role
int_video 5 x 48x48 whole-pel failure here implicates the entropy/residual stage
video_real 8 x 96x96 half-pel (27,960 B vs 38,232 B whole-pel) load-bearing: half-pel bilinear rounding is the arithmetic most at risk across architectures

The real-footage test also asserts the vector still prefers half-pel, so it cannot silently degrade into covering only the whole-pel path while still passing.

Cost stays flat: int_video.rs needs only serde_json and crate::rans, both already present, so all four legs still run in ~1 minute with no codec libraries and no ONNX runtime. rans is re-exported, not included twice — two #[path] includes would compile two structurally identical but distinct types, and one-source-of-truth is why this crate exists.

Also fixes: the workflow could not see its own inputs

The crate compiles five sources. Only one of them could fire this workflow:

included source watched before?
wai-rs/src/rans.rs no
wai-rs/src/int_synth.rs (crate root) no — the trigger named neural/int_synth.rs, a different file
wai-rs/src/int_entropy.rs no
wai-rs/src/jpegai_mans.rs (crate root) no
wai-rs/src/neural/jpegai_mans.rs yes

Any of the four could have broken cross-architecture equality and merged green. All five are now watched, plus int_video.rs and its vectors.

Not covered, and not papered over

video_nk (wai.video.int_hyper, the neural-keyframe variant) is not included. Its I-frame comes from int_hyper_synth::decode_conditional, so it cannot be driven by decode() — an earlier draft of this file tried, and got a slice overrun out of the rANS reader, which is what feeding one codec another codec's bitstream looks like. Covering it means #[path]-including int_hyper_synth.rs as well: a real follow-on, not a line to add here. Until it lands the neural-keyframe leg is proven only where someone runs --features neural_int,video_int locally, and the source comment says so rather than letting a reader assume full coverage.

Verification

  • 17 tests pass in the conformance crate (15 existing + 2 new); both clips reproduce their committed golden hashes (27573cdba1ad6628, 1ec1f0fa7da0d70f).
  • Workflow YAML parses; all four matrix legs intact (linux-x86_64, linux-aarch64, macos-arm64, windows-x86_64).

Second commit: meter the integer video class

Haptics / 4D splats / scores / film are metered by wai_meter, worlds / feeds / avatars by wai_world_meter, quantum circuits by wai_quantum_meter. Video had none — it could be decoded but never accounted. This adds the JWP receipt profile (VideoReceipt) and the wai_video_meter binary, following QuantumReceipt exactly.

Why this profile is stronger than its siblings

In every other cargo class the reconstruction is deterministic by construction and taken on trust. Here it is deterministic and proven on real silicon — by the first commit's four-architecture matrix. So a verifier holding only the codestream can re-derive clip_hash, every frame hash and work_pixel_ops themselves (verify_reconstruction does precisely that), and the receipt collapses to one field that rests on trusting the signer:

field status
codestream_hash, clip_hash, frames, work_pixel_ops verifiable by anyone with the bitstream, on any proven architecture
joules_micro measured-attested — vouched for by the signature and nothing else

The docs say which is which in those words, so a reader cannot conflate them.

Deliberate choices

  • The receipt is NOT in int_video.rs. That file is #[path]-included by byte-exact-conformance, whose three-dependency set is what lets the matrix run everywhere in ~1 minute. Pulling blake3 + 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 ops. 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 beside it. Inter-frame decode is order-dependent; 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, and without macmon the meter emits an UNMETERED receipt rather than an estimate.

Measured, not modelled

Release build, real-footage vector (8 frames 96×96), on this machine:

cpu power  idle     : 20.45 W  (10 samples)
cpu power  busy     : 54.89 W  (14 samples)
marginal (busy-idle): 34.45 W
decodes            : 11548 over 3.54s
-> per decode        : 10564.9 uJ
-> per kilo-subpixel : 47.7654 uJ

A debug build reports 4.9x higher, which is why the meter is documented as a release-build tool. IOReport CPU power is SoC-wide, so the figure is the marginal delta over an idle machine — stated bounds, never a fabricated number.

Verification

  • 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; int_video.rs untouched.
  • No new clippy warnings; default build unaffected (feature off by default).

Fourth commit: the measurement methodology (extensions/energy-measurement.md)

jwp-receipts.md defines joules_micro as "microjoules consumed producing this object" — which fixes the unit and the scope of attribution and nothing else. The field was 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 indistinguishable.

The extension requires two things of any receipt carrying energy: that the figure declare how it was acquired (HwShunt / ModelBased / Estimator — the vocabulary the sibling receipt families already use, not a new one for media), and that the measurement declare whether it was good enough to publish. It also specifies the bracketed marginal protocol, 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 the document forced on the implementation

1. The publication bar moves from 3× to 10×, on evidence. A later reading of the same clip at a 3.8× marginal-to-noise ratio — inside what the previous rule called "usable" — reported 2,469 µJ against 10,565 µJ from a quieter run. A 4.3× 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. And the bias has a direction: a busy machine inflates the idle baseline that is then subtracted from a busy mean that never rose as far, so a poor bracket always reads low. An implementation reporting its own energy errs toward flattering itself — which is exactly why the check has to be automatic rather than left to the operator.

2. The worked example is a failing one, deliberately. My draft carried a clean-looking bracket with an idle standard deviation and a quality ratio for the 10,565 µJ run — numbers that run never produced, because it predates the standard-deviation reporting. Inventing them in a document about measurement honesty is the precise failure the document exists to prevent.

The example is now the real 3.8× bracket, labelled as one this spec forbids publishing, with a note on why a clean bracket isn't 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.


Fifth commit: the neural-keyframe clip joins the matrix

The first 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, so it 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 wasn't 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 ~1 minute with no codec libraries and no ONNX.

Why this is the strictest composition in the container

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 all four architectures instead of only where someone passes --features. The crate goes from 17 tests to 32:

module tests
int_transform 13
neural 6
int_entropy 4
golden 3
neural_keyframe_golden 2
jpegai_golden 2
int_video_golden 2

Both new sources and the int_hyper vectors are added to the 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.

Verification

32 tests pass, the clip reproducing its committed hash a5f53d477999d159; workflow YAML parses with all four legs intact and 13 triggers.

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 rather than assumed: ``` cargo test --test int_video -> 0 passed cargo test --test int_video --features video_int -> 1 passed ``` So the temporal leg of the determinism contract was **asserted on four platforms and checked on none**. ## Why video is the strictest leg, not just 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. An architecture that rounds one 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. ## What is covered | clip | shape | motion | role | |---|---|---|---| | `int_video` | 5 x 48x48 | whole-pel | failure here implicates the entropy/residual stage | | `video_real` | 8 x 96x96 | **half-pel** (27,960 B vs 38,232 B whole-pel) | load-bearing: half-pel bilinear rounding is the arithmetic most at risk across architectures | The real-footage test also asserts the vector *still prefers* half-pel, so it cannot silently degrade into covering only the whole-pel path while still passing. Cost stays flat: `int_video.rs` needs only `serde_json` and `crate::rans`, both already present, so all four legs still run in ~1 minute with no codec libraries and no ONNX runtime. `rans` is **re-exported, not included twice** — two `#[path]` includes would compile two structurally identical but distinct types, and one-source-of-truth is why this crate exists. ## Also fixes: the workflow could not see its own inputs The crate compiles five sources. Only **one** of them could fire this workflow: | included source | watched before? | |---|---| | `wai-rs/src/rans.rs` | no | | `wai-rs/src/int_synth.rs` (crate root) | no — the trigger named `neural/int_synth.rs`, a *different file* | | `wai-rs/src/int_entropy.rs` | no | | `wai-rs/src/jpegai_mans.rs` (crate root) | no | | `wai-rs/src/neural/jpegai_mans.rs` | yes | Any of the four could have broken cross-architecture equality and merged green. All five are now watched, plus `int_video.rs` and its vectors. ## Not covered, and not papered over `video_nk` (`wai.video.int_hyper`, the neural-keyframe variant) is **not** included. Its I-frame comes from `int_hyper_synth::decode_conditional`, so it cannot be driven by `decode()` — an earlier draft of this file tried, and got a slice overrun out of the rANS reader, which is what feeding one codec another codec's bitstream looks like. Covering it means `#[path]`-including `int_hyper_synth.rs` as well: a real follow-on, not a line to add here. Until it lands the neural-keyframe leg is proven only where someone runs `--features neural_int,video_int` locally, and the source comment says so rather than letting a reader assume full coverage. ## Verification - 17 tests pass in the conformance crate (15 existing + 2 new); both clips reproduce their committed golden hashes (`27573cdba1ad6628`, `1ec1f0fa7da0d70f`). - Workflow YAML parses; all four matrix legs intact (linux-x86_64, linux-aarch64, macos-arm64, windows-x86_64). --- ## Second commit: meter the integer video class Haptics / 4D splats / scores / film are metered by `wai_meter`, worlds / feeds / avatars by `wai_world_meter`, quantum circuits by `wai_quantum_meter`. **Video had none** — it could be decoded but never accounted. This adds the JWP receipt profile (`VideoReceipt`) and the `wai_video_meter` binary, following `QuantumReceipt` exactly. ### Why this profile is stronger than its siblings In every other cargo class the reconstruction is deterministic *by construction* and taken on trust. Here it is deterministic **and proven on real silicon** — by the first commit's four-architecture matrix. So a verifier holding only the codestream can re-derive `clip_hash`, every frame hash and `work_pixel_ops` themselves (`verify_reconstruction` does precisely that), and the receipt collapses to **one** field that rests on trusting the signer: | field | status | |---|---| | `codestream_hash`, `clip_hash`, `frames`, `work_pixel_ops` | **verifiable** by anyone with the bitstream, on any proven architecture | | `joules_micro` | **measured-attested** — vouched for by the signature and nothing else | The docs say which is which in those words, so a reader cannot conflate them. ### Deliberate choices - **The receipt is NOT in `int_video.rs`.** That file is `#[path]`-included by `byte-exact-conformance`, whose three-dependency set is what lets the matrix run everywhere in ~1 minute. Pulling blake3 + 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 ops. 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 beside it. Inter-frame decode is order-dependent; 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`, and without `macmon` the meter emits an UNMETERED receipt rather than an estimate. ### Measured, not modelled Release build, real-footage vector (8 frames 96×96), on this machine: ``` cpu power idle : 20.45 W (10 samples) cpu power busy : 54.89 W (14 samples) marginal (busy-idle): 34.45 W decodes : 11548 over 3.54s -> per decode : 10564.9 uJ -> per kilo-subpixel : 47.7654 uJ ``` A debug build reports 4.9x higher, which is why the meter is documented as a release-build tool. IOReport CPU power is SoC-wide, so the figure is the marginal delta over an idle machine — stated bounds, never a fabricated number. ### Verification - 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; `int_video.rs` untouched. - No new clippy warnings; default build unaffected (feature off by default). --- ## Fourth commit: the measurement methodology (`extensions/energy-measurement.md`) `jwp-receipts.md` defines `joules_micro` as *"microjoules consumed producing this object"* — which fixes the unit and the scope of attribution and nothing else. The field was 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 **indistinguishable**. The extension requires two things of any receipt carrying energy: that the figure declare **how it was acquired** (`HwShunt` / `ModelBased` / `Estimator` — the vocabulary the sibling receipt families already use, not a new one for media), and that the measurement declare **whether it was good enough to publish**. It also specifies the bracketed marginal protocol, 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 the document forced on the implementation **1. The publication bar moves from 3× to 10×, on evidence.** A later reading of the same clip at a **3.8×** marginal-to-noise ratio — inside what the previous rule called "usable" — reported **2,469 µJ** against **10,565 µJ** from a quieter run. A 4.3× 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. And the bias has a direction: a busy machine inflates the idle baseline that is then subtracted from a busy mean that never rose as far, so a poor bracket **always reads low**. An implementation reporting its own energy errs toward flattering itself — which is exactly why the check has to be automatic rather than left to the operator. **2. The worked example is a failing one, deliberately.** My draft carried a clean-looking bracket with an idle standard deviation and a quality ratio for the 10,565 µJ run — numbers that run never produced, because it predates the standard-deviation reporting. Inventing them in a document about measurement honesty is the precise failure the document exists to prevent. The example is now the real 3.8× bracket, labelled as one this spec **forbids publishing**, with a note on why a clean bracket isn't 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. --- ## Fifth commit: the neural-keyframe clip joins the matrix The first 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`, so it 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 wasn't 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 ~1 minute with no codec libraries and no ONNX. ### Why this is the strictest composition in the container 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 all four architectures** instead of only where someone passes `--features`. The crate goes from 17 tests to 32: | module | tests | |---|---| | `int_transform` | 13 | | `neural` | 6 | | `int_entropy` | 4 | | `golden` | 3 | | `neural_keyframe_golden` | 2 | | `jpegai_golden` | 2 | | `int_video_golden` | 2 | Both new sources and the `int_hyper` vectors are added to the 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. ### Verification 32 tests pass, the clip reproducing its committed hash `a5f53d477999d159`; workflow YAML parses with all four legs intact and 13 triggers.
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
c9be2adb57
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.
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
256e5dd118
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.
dcharlot changed title from wai: prove integer VIDEO decode byte-identical across architectures to wai: prove integer video byte-identical across architectures, then meter it 2026-08-26 00:02:32 -04:00
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
7dfca26c66
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: 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
3d3486069f
`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.
dcharlot changed title from wai: prove integer video byte-identical across architectures, then meter it to wai: prove integer video byte-identical, meter it, and publish the method 2026-08-26 08:15:21 -04:00
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
d4c922bebe
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.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!60
No description provided.