wai packaging train: a title's whole ladder in one package, steps on the fabric with the least measured energy, decode-equivalence on GPUs (#426 #438 #452's GPU tier) #465

Merged
dcharlot merged 41 commits from train/pack-stack into main 2026-10-26 08:43:11 -04:00
Owner

The packaging stack (#426, #438, and #452's GPU-tier part) as one train onto main (now 9d984511a), with every MUST-FIX and SHOULD-FIX of the three reviews applied as its own commit, and #452's platform-decode part left out by the reviews' split. Branch train/pack-stack, head 7971c3338. It lands as one squashed history: commit 836d0255d carries the three PRs' changes, and every later commit is one fix, named by the finding it closes.

What the three PRs bring

  • #426, a title's whole ladder in one package (packaging §7.1, §7.7, §7.8, §11.4, §11.5, §9.4). One package carries a title's AV1 ladder over one integer base:
    • several floor rungs;
    • a re-pack that takes its base from a parent package;
    • a floor that is the ladder's own CMAF segments, bound byte for byte through floor.listing;
    • a floor-only profile;
    • a streaming packer;
    • the independent verifier at a full title's scale.
  • #438, each step on the fabric with the least measured energy (packaging §11.6, jwp-receipts §2.4.8, energy-measurement §6.3).
    • Every pack and verify step is named.
    • A backend runs a step only after it qualifies, so package bytes and verdicts are the CPU's on every fabric.
    • A metered package's claim may carry a fabric record.
    • It adds the wai-pack-gpu crate (WGSL integer kernels for the motion search, SSE and BLAKE3), wai-pack fabric, the macOS fabric meter, and wai-pack floor-decode.
  • #452, its GPU-tier part only (determinism-tiers §5).
    • The conditions under which a decoder may claim decode-equivalence for output a GPU computed.
    • WGSL's integer semantics suite (wai/wgsl-conformance/).
    • The rules check on naga's IR (tests/wgsl_rules.rs).
    • The kernels' shift masks and min(max()) clamps. These also remove a shift by 32 that main's q_shr_fill reaches on Metal.

How they were integrated

  • Built as a squash onto origin/main at b16816671 (#438 review M6). git merge --squash pr/452 brings in #426, #438 and #452, since #452's head contains the other two.

  • The only textual conflict, wai/CHANGELOG.md, is the union of both sides. The stack's entries come first, since it lands after main's. No line of either side is dropped.

  • #438's research note is rewritten inside the squash, so its original text never enters history (#438 review M6). It moves from docs/research/wai-cross-fabric.md to wai/research/cross-fabric.md, where the name check scans it.

    • It names no host, address, fleet role, company, chip or product. Hardware is named by architecture, PCI vendor and device id, and OS version, as main does; the test title is "a 596 s, 24 fps open-licence film".
    • Every table is marked as one run.
    • The same commit rewords a floor_decode.rs comment that named a chip vendor, and a wai_pack.rs comment that named the title.
    • A grep of the whole train diff and its messages for fleet addresses and host names finds none.
  • Left out by the review's split, for EN-C to take over: #452's platform decode in dispatch. That is its commits 6ad92e2e8, 8695bc75f and fed8694f4 (reversed in the squash) and its CHANGELOG entry:

    • wai/extensions/platform-decode.md;
    • wai/platform-decode-conformance/;
    • wai::platform_decode (wai-rs/src/platform_decode.rs and its tests, and the lib.rs line);
    • wai-web's platform_decode feature, src/platform_decode.rs, and its demo pages (demo/platform_decode.{html,js}, demo/verify_platform_decode.mjs), with their .gitignore line;
    • the two SPEC.md sentences (§4's "advertising is per envelope in one other place" and the §7.1 pointer);
    • the "Dispatch: what a web platform says it decodes" CHANGELOG entry.

    So SPEC.md, wai-rs/src/lib.rs, wai-web and wai/.gitignore are main's, byte for byte.

  • Semantic interactions with main, checked:

    • Every MeasurementClaim constructed in the merged tree sets fabrics.
    • Main's bearer claim classes and #438's fabric record merge cleanly in claim_receipt.rs, claim_verify.py and jwp-receipts.
    • The claim corpus's 567-vector prefix is unchanged.
    • Main's exact-upscale GPU step runs through the changed wai-ops-gpu kernels and passes (below).

The fixes, one commit each

Finding Commit What changed
#426 M1, the C header 72ab8756e The header now holds #define PIECE_KIND_NONE 6, the six lines the build writes, so a build leaves the tree clean (and the falsify shards pass, below).
#426 M2, #452 media prober 4108c473e The media prober reads key frames as frame indices. It divides each pts by the sample duration and requires every sample on that grid: constant duration, no gap, in order. The CMAF floor's ticks (48000 per frame at 1/1200000) now read 0 60 85 135 160, and the step reaches video-floor-only-02.
#426 M3 f62ff0c23 §11.4's pack-source-missing applies to the standard profile only; the code already agreed.
#426 M4 b876b404d The meter starts before the source's first read and brackets the whole pack, and §9.4 says so as a MUST. The fabric meter starts at the same call.
#426 S1, S7, S8, S9, S10, S12 d911d11e0 Spec wording: a re-pack holds its parent whole; §11.5's checks and when they run; §11.2 needs the same packager identity; what intent: "replicate" on a floor promises; what a floor-only sink can check; §7.2's sentence.
#426 S2 d2dbcf011, 5757156dd A CMAF init's av1C and sample-entry size must be the sequence header's, in both Rust readers and pack_verify.py, with tests.
#426 S3 098489d73 Every CMAF sample is a sync sample exactly when its unit starts at a shown key frame, in both readers and both Python paths, with a test in d2dbcf011.
#426 S4 0ba8e5577 pack_verify.py checks a metered package's claim with claim_verify.check_figure.
#426 S5 4e0c3fd8c cmaf_diff.py's timescale case now alters mdhd's timescale (+16 in version 0, +24 in version 1).
#426 S6 26ca4d787, 37b3cfa6a The reseal propagates a failed CMAF check. segment-not-the-supplied-one is resealed with catalogs naming the replacement, so its one fault is the binding to floor.listing.
#426 S11 b60c03327 verify --parent reports an unreadable parent as repack-parent-invalid.
#438 M1–M4, S1–S4 321aa53a2, e9a3acb58, a74adcb3e, fbabae76e, c6b41ee5c The fabric meter, rebuilt on a pure attribution (src/fabric_attribution.rs, compiled on every OS): GPU clients sampled every 200 ms and keyed by registry id, a vanished client or a negative difference refused, nothing clamped, the busy window enclosing the rail's; a frozen or failed reading refused; the whole rail; OnChipCounter, filtering Unknown, with a 5% declared uncertainty computed in integers; task = ri_energy_nj + ri_billed_energy − ri_serviced_energy; the reading thread's fold checked; a 1 s and five-interval minimum span; 11 unit tests. The packer refuses a fabric that ran steps with no share or a share of 0.
#438 M2 (claims), M3, S11 4e9e53abe, e3dd5a7cc Rule 6 refuses a share of 0 on a stepped fabric (measurement_fabric_unmetered), in the text and both verifiers. The accept vector is OnChipCounter. Seven vectors are appended (581 → 588); the corpus is regenerated.
#438 M5 25b34b2ae wai-pack-gpu takes tokio 1.54.1 (RUSTSEC-2026-0384).
#438 the fabric term f1544724e npu, not neural, everywhere.
#438 S5, S9 20833bcec §11.6 item 1 states the qualifying set normatively. §7.5's MUST carries a hardware encoder's device and driver.
#438 M1, M3, S1–S3, S10 (spec) b37e2986f, 2aa4e54d3 Energy-measurement §6.3: the class, task, how sole use is sampled and its residual, the rail's idle draw and window, and that a profile without a step vocabulary MUST NOT carry a record.
#438 S6, S7, N12 6b62aa482 wai-pack-gpu uses per-call Validation and OutOfMemory error scopes (thread-local in wgpu 30 with std). The kernels are claimed exact on Metal only. The CHANGELOG says older verifiers refuse fabrics.
#438 S8 6d90c17df encode_with refuses a vector outside the search window (field_range).
#438 N6 9b5c99e49 wai::jwp_hash::DOMAIN_OBJECT replaces a hand-written domain.
#452 M1 ae487223f wgsl-conformance gets its sidecar exclusion. This was the cargo-class corpora jobs' root cause: every_decoded_output_states_a_sha256 read a sha256.json the new corpora lack. With platform-decode left out, only this one entry is needed.
#452 M2 344bbcbbc The rules check refuses atomicLoad/atomicStore (a load or store through a pointer to an atomic), with the review's plants and a storage barrier alone.
#452 M3 841d7a66e Item 3 requires one atomic kind per word, with its result unused.
#452 S1 4b5f73c1d Rule 8 looks for naga's signed wrapping (as_type<int>(as_type<uint>(, asint(asuint(), with a test that strips it. The workflow counts 17 tests.
#452 S3 328121086 No signed left shift in a kernel; item 4 says why.
#452 S2, S4–S7, corrections, N5, N13; G2 reuse 0ec788fe7, 9b5c99e49, e71980901 The tier is claimed only where a run on this revision's kernels is recorded, with each run's report lines committed in wai/research/ops-gpu-runs.txt (minus the adapter-name field, a product name): Metal on an arm64 desktop and Chromium 148's WebGPU on it (the forge's run 10236, job 46928), and Vulkan on PCI 0x1002:0x1586 (Mesa 26.0.8) and llvmpipe (this train's run). The hand runs with no record (Linux 0x10de and 0x8086, Windows Vulkan and DX12, WARP) are named and not claimed. Item 6 covers backends with no PCI id. The rules check's scope is stated. "Every integer operation WGSL defines" is narrowed to what the kernels may use. The corrections: SPIR-V's signed %, HLSL clamp, FXC, §8.8/§8.10, the doc links. The §6 row cites the run. The subsection opens with an accelerator-general form, so #440 (G2) can rebase onto it rather than write a parallel rule.

The packaging CHANGELOG gains a line for the review fixes (b270ac75d).

Checks

Heavy checks ran on the build host through rb, with one target directory per workspace as CI has. A first run with one shared target directory let wai-pack pick up a wai built with another workspace's features, which no CI job can hit; its wai-pack steps were rerun. The trees: 87618bbe (the train before main's #451), f3a04b82 (after it), and the head for the last two rows.

Check Command (as the workflow runs it) Result
Merge cross-wiring python3 ~/kani-logs/wfsteps.py HEAD origin/main pr/426 pr/438 pr/452 2 problems, both steps changed on purpose: wai-ops-gpu.yml metal "The probe, the corpus…" (the test count 16 → 17) and wai-pack.yml media "The goldens' floors read and decode" (the prober fix)
Workflows parse ruby -ryaml -e 'ARGV.each{|f| YAML.load_file(f)}' .github/workflows/*.yml ok
Repo checks check-tests-in-ci.py, check-workflow-concurrency.sh, check-spec-refs.py, check-wai-section-refs.py, check-no-vanity-metrics.sh, test-public-text-checks.sh, check-comparative-prose.sh, check-orphan-sources.py all pass
Public names WAI_NAME_DENYLIST=… bash scripts/check-public-names.sh <every changed text file>; grep -E over every commit message clean (232 files); messages clean; no address, host or vendor name in the diff
Advisories python3 -I scripts/check-advisories.py the train adds none (tokio fixed). It fails on main's own RUSTSEC-2026-0385 (ctutils) and RUSTSEC-2026-0387 (crypto-bigint), in lockfiles identical to main's; #449 fixes those
wai-rs, the cargo-class corpora job (unix) build; lib unit tests; JPEG AI math; container limits; fast kernels with overflow checks on and in release; each feature alone and the wasm32 builds; carriage, CLI and provenance; http commands; world; staged MoQ; C ABI; signer ids, wai-keys, key_log wasm32 all pass (formerly red at int_kernels_vectors)
Corpora regenerate byte for byte the conformance workflow's v … loop over all 21 corpora, wai_claim_vectors included all pass
registry export --check cargo run -q --no-default-features --bin wai -- registry export --check ok
include/wai.h after a build touch cbindgen.toml && cargo build … --bin wai_http_vectors && git diff --quiet -- wai/wai-rs/include/wai.h unchanged
HTTP corpus falsify bash wai/http-conformance/falsify/run.sh <work> --patches I/3 for I = 0, 1, 2, as the CI job runs it all three pass (formerly red at the first patch)
Independent verifiers claim_verify.py and differential.py --random 2000, jwp_verify.py, signer_verify.py, http_verify.py and its fuzz differential, pin_verify.py, the audio provenance check, the OER C kernel all pass
wai-pack cargo clippy --locked --all-targets -- -D warnings; cargo test --release --locked --no-fail-fast; the test-count floors; wai-pack conformance check ../pack-conformance (after conformance regen) all pass
wai-pack on the GPU (Metal) cargo clippy --all-targets --features gpu,fabric-meter -- -D warnings; WAI_PACK_GPU_REQUIRE=1 cargo test --release --locked --features gpu --test fabric pass: every golden packed on the GPU is the committed package byte for byte, and the conformance check above recomputes them on the CPU, so CPU and GPU packs are identical
wai-pack-gpu (Metal) clippy -D warnings; WAI_PACK_GPU_REQUIRE=1 cargo test --release --locked with the workflow's greps pass
wai-pack's meter and attribution cargo test --release --locked --features fabric-meter --lib fabric pass
pack_verify.py pack_verify.py pack-conformance, and --jobs 2 pass
Differentials source_diff.py (debug and release), policy_diff.py, segment_diff.py, stage_diff.py, cmaf_diff.py, png_diff.py pass
wai-ops-gpu clippy -D warnings; the metal job of wai-ops-gpu.yml, its text run step by step: the probe, the corpus at both widths, the mutants and the semantics suite with WAI_OPS_GPU_REQUIRE=1, the capability corpora with their graphs on the GPU, main's exact-upscale derivations on the GPU, and the browser leg all pass, 17 tests
Vulkan, cross-vendor WAI_OPS_GPU_REQUIRE=1 cargo test --locked --release -- --nocapture --test-threads=1 on a Linux x86_64 host, PCI 0x1002:0x1586 (Mesa 26.0.8) and llvmpipe pass: 17 tests; semantics 254,464 cases with none differing, guarded or not; the probe equal; the corpus mismatches=0 errors=0; 18 of 18 mutants. The report is committed. The Linux host with PCI vendors 0x10de and 0x8086 needed an interactive login and was not reached
Lockfiles ./scripts/check-lockfiles.sh; cargo metadata --locked --offline for wai-rs, wai-pack, wai-pack-gpu, wai-ops-gpu and wai-web clean
Media prober the step's committed text, extracted from wai-pack.yml and run over the goldens with ffmpeg 9.0.2 (CI has 4.4.2) every golden passes, video-cmaf-01 and video-floor-only-02 included

Falsifications

Every new check was committed before it was falsified. Each case broke the rule in rb's checkout, required the guarding test to fail, restored the file through git, and required the test to pass again (.ps-falsify.sh, not committed):

  • The fabric attribution:

    • the sole-user rule removed: fails;
    • another process's vanished client no longer charged: fails;
    • rail liveness removed: fails;
    • the whole rail replaced by a busy-time split: this first passed, because the fixture gave this process all the GPU's time. The fixture was fixed (c6b41ee5c), and the case now fails.
  • Zero shares: the packer's zero-share refusal removed (fails); claim rule 6's > 0 removed in Rust (wai_claim_vectors verify, fails) and in Python (claim_verify.py, fails).

  • The CMAF floor: the per-sample sync check removed (fails); the av1C/size check removed (fails); pack_verify.py's init_agrees made always true (an altered av1C level is then accepted).

  • Other code checks: encode_with's window check removed (fails); the rules check's atomic-load refusal and signed-left-shift refusal each removed (wgsl_rules, fails).

  • The media prober, on a scratch copy of the corpus with the committed step text:

    • the golden passes, and so does a control remux of its source;
    • a real key frame moved in the bitstream (temporal unit 59 dropped and 61 repeated, so the key frame of 60 sits at 59, remuxed with supplied_cmaf.py's ffmpeg recipe) fails: "key frames at 0 59 85 135 160; the plan says 0 60 85 135 160";
    • a sample duration of 47999 ticks fails by name;
    • an edited plan fails.

    Editing the trun sync flags alone does not move ffmpeg's K flag, because its AV1 parser takes key frames from the frame header. So the step reads real key frames.

  • The header: without the regenerated header, a build dirties the tree (the CI failure, reproduced on the build host). With it, the forced rebuild leaves the tree clean and the three falsify shards pass.

  • Rule 8: its test strips naga's wrapping from ops32's MSL and HLSL and requires a refusal; the stripped MSL still carries the bare bitcasts, which the old check took for the wrapping.

Not done

  • Platform decode in dispatch (#452 part 2) is left out by the review's split; EN-C takes it over.
  • The capability corpora on the Vulkan adapter: wai-rs/tests/ops_gpu.rs did not run there, and §5 says so.
  • Unreached GPU hosts: the Linux host with PCI vendors 0x10de and 0x8086 (it needs an interactive login) and the Windows host's adapters. Their hand runs stay unclaimed until a recorded run.
  • The metered pack's figures in wai/research/cross-fabric.md are the meter's first revision, one run each; the note says so. No metered pack was repeated under the new meter.
  • No verifier enforces "no fabric record without a step vocabulary" (#438 S10). It is a producer MUST in energy-measurement §6.3.
  • The reviews' NOTEs not acted on:
    • #426: N1, N2, N4–N12;
    • #438: N5, N7–N11, N13, N14;
    • #452: N6–N12, other than N7 and N13, which were applied.
  • After this lands: G2 (#440) rebases onto the accelerator-general subsection of determinism-tiers §5; its three conflicts there are expected.
  • CI: the media prober uses CI's ffmpeg 4.4.2, which this train did not run locally (9.0.2 was used). The forge run of this branch will show it.

What deploys beyond the repo

  • The status page (wai-transaction-science-web, branch status/wai-gpu-int-tier, commit 980639b, not merged). Before it goes live:
    • envelope-tiers-gpu's adapters must match §5 as narrowed: Metal and its browser WebGPU, and Vulkan on PCI 0x1002 and llvmpipe;
    • the envelope-dispatch-platform row, and the WebCodecs and Media Capabilities references, belong to the platform-decode part that this train leaves out, so they should not go live with it;
    • envelope-tiers and the WGSL reference row stand.
  • No other site page, service or published binary changes. wai-pack with features gpu and fabric-meter, and wai-pack-gpu, are repository crates, not published.

🤖 Generated with Claude Code

The packaging stack (#426, #438, and #452's GPU-tier part) as one train onto main (now `9d984511a`), with every MUST-FIX and SHOULD-FIX of the three reviews applied as its own commit, and #452's platform-decode part left out by the reviews' split. Branch `train/pack-stack`, head `7971c3338`. It lands as **one squashed history**: commit `836d0255d` carries the three PRs' changes, and every later commit is one fix, named by the finding it closes. ## What the three PRs bring - **#426, a title's whole ladder in one package** (packaging §7.1, §7.7, §7.8, §11.4, §11.5, §9.4). One package carries a title's AV1 ladder over one integer base: - several floor rungs; - a re-pack that takes its base from a parent package; - a floor that is the ladder's own CMAF segments, bound byte for byte through `floor.listing`; - a floor-only profile; - a streaming packer; - the independent verifier at a full title's scale. - **#438, each step on the fabric with the least measured energy** (packaging §11.6, jwp-receipts §2.4.8, energy-measurement §6.3). - Every pack and verify step is named. - A backend runs a step only after it qualifies, so package bytes and verdicts are the CPU's on every fabric. - A metered package's claim may carry a fabric record. - It adds the `wai-pack-gpu` crate (WGSL integer kernels for the motion search, SSE and BLAKE3), `wai-pack fabric`, the macOS fabric meter, and `wai-pack floor-decode`. - **#452, its GPU-tier part only** (determinism-tiers §5). - The conditions under which a decoder may claim `decode-equivalence` for output a GPU computed. - WGSL's integer semantics suite (`wai/wgsl-conformance/`). - The rules check on naga's IR (`tests/wgsl_rules.rs`). - The kernels' shift masks and `min(max())` clamps. These also remove a shift by 32 that main's `q_shr_fill` reaches on Metal. ## How they were integrated - **Built as a squash onto `origin/main` at `b16816671`** (#438 review M6). `git merge --squash pr/452` brings in #426, #438 and #452, since #452's head contains the other two. - **The only textual conflict, `wai/CHANGELOG.md`, is the union of both sides.** The stack's entries come first, since it lands after main's. No line of either side is dropped. - **#438's research note is rewritten inside the squash, so its original text never enters history** (#438 review M6). It moves from `docs/research/wai-cross-fabric.md` to `wai/research/cross-fabric.md`, where the name check scans it. - It names no host, address, fleet role, company, chip or product. Hardware is named by architecture, PCI vendor and device id, and OS version, as main does; the test title is "a 596 s, 24 fps open-licence film". - Every table is marked as one run. - The same commit rewords a `floor_decode.rs` comment that named a chip vendor, and a `wai_pack.rs` comment that named the title. - A grep of the whole train diff and its messages for fleet addresses and host names finds none. - **Left out by the review's split, for EN-C to take over:** #452's platform decode in dispatch. That is its commits `6ad92e2e8`, `8695bc75f` and `fed8694f4` (reversed in the squash) and its CHANGELOG entry: - `wai/extensions/platform-decode.md`; - `wai/platform-decode-conformance/`; - `wai::platform_decode` (`wai-rs/src/platform_decode.rs` and its tests, and the `lib.rs` line); - `wai-web`'s `platform_decode` feature, `src/platform_decode.rs`, and its demo pages (`demo/platform_decode.{html,js}`, `demo/verify_platform_decode.mjs`), with their `.gitignore` line; - the two `SPEC.md` sentences (§4's "advertising is per envelope in one other place" and the §7.1 pointer); - the "Dispatch: what a web platform says it decodes" CHANGELOG entry. So `SPEC.md`, `wai-rs/src/lib.rs`, `wai-web` and `wai/.gitignore` are main's, byte for byte. - **Semantic interactions with main, checked:** - Every `MeasurementClaim` constructed in the merged tree sets `fabrics`. - Main's bearer claim classes and #438's fabric record merge cleanly in `claim_receipt.rs`, `claim_verify.py` and jwp-receipts. - The claim corpus's 567-vector prefix is unchanged. - Main's exact-upscale GPU step runs through the changed `wai-ops-gpu` kernels and passes (below). ## The fixes, one commit each | Finding | Commit | What changed | |---|---|---| | #426 M1, the C header | `72ab8756e` | The header now holds `#define PIECE_KIND_NONE 6`, the six lines the build writes, so a build leaves the tree clean (and the falsify shards pass, below). | | #426 M2, #452 media prober | `4108c473e` | The media prober reads key frames as frame indices. It divides each `pts` by the sample duration and requires every sample on that grid: constant duration, no gap, in order. The CMAF floor's ticks (48000 per frame at 1/1200000) now read 0 60 85 135 160, and the step reaches `video-floor-only-02`. | | #426 M3 | `f62ff0c23` | §11.4's `pack-source-missing` applies to the standard profile only; the code already agreed. | | #426 M4 | `b876b404d` | The meter starts before the source's first read and brackets the whole pack, and §9.4 says so as a MUST. The fabric meter starts at the same call. | | #426 S1, S7, S8, S9, S10, S12 | `d911d11e0` | Spec wording: a re-pack holds its parent whole; §11.5's checks and when they run; §11.2 needs the same packager identity; what `intent: "replicate"` on a floor promises; what a floor-only sink can check; §7.2's sentence. | | #426 S2 | `d2dbcf011`, `5757156dd` | A CMAF init's `av1C` and sample-entry size must be the sequence header's, in both Rust readers and `pack_verify.py`, with tests. | | #426 S3 | `098489d73` | Every CMAF sample is a sync sample exactly when its unit starts at a shown key frame, in both readers and both Python paths, with a test in `d2dbcf011`. | | #426 S4 | `0ba8e5577` | `pack_verify.py` checks a metered package's claim with `claim_verify.check_figure`. | | #426 S5 | `4e0c3fd8c` | `cmaf_diff.py`'s timescale case now alters `mdhd`'s timescale (+16 in version 0, +24 in version 1). | | #426 S6 | `26ca4d787`, `37b3cfa6a` | The reseal propagates a failed CMAF check. `segment-not-the-supplied-one` is resealed with catalogs naming the replacement, so its one fault is the binding to `floor.listing`. | | #426 S11 | `b60c03327` | `verify --parent` reports an unreadable parent as `repack-parent-invalid`. | | #438 M1–M4, S1–S4 | `321aa53a2`, `e9a3acb58`, `a74adcb3e`, `fbabae76e`, `c6b41ee5c` | The fabric meter, rebuilt on a pure attribution (`src/fabric_attribution.rs`, compiled on every OS): GPU clients sampled every 200 ms and keyed by registry id, a vanished client or a negative difference refused, nothing clamped, the busy window enclosing the rail's; a frozen or failed reading refused; the whole rail; `OnChipCounter`, filtering `Unknown`, with a 5% declared uncertainty computed in integers; `task` = `ri_energy_nj + ri_billed_energy − ri_serviced_energy`; the reading thread's fold checked; a 1 s and five-interval minimum span; 11 unit tests. The packer refuses a fabric that ran steps with no share or a share of 0. | | #438 M2 (claims), M3, S11 | `4e9e53abe`, `e3dd5a7cc` | Rule 6 refuses a share of 0 on a stepped fabric (`measurement_fabric_unmetered`), in the text and both verifiers. The accept vector is `OnChipCounter`. Seven vectors are appended (581 → 588); the corpus is regenerated. | | #438 M5 | `25b34b2ae` | `wai-pack-gpu` takes tokio 1.54.1 (RUSTSEC-2026-0384). | | #438 the fabric term | `f1544724e` | `npu`, not `neural`, everywhere. | | #438 S5, S9 | `20833bcec` | §11.6 item 1 states the qualifying set normatively. §7.5's MUST carries a hardware encoder's device and driver. | | #438 M1, M3, S1–S3, S10 (spec) | `b37e2986f`, `2aa4e54d3` | Energy-measurement §6.3: the class, `task`, how sole use is sampled and its residual, the rail's idle draw and window, and that a profile without a step vocabulary MUST NOT carry a record. | | #438 S6, S7, N12 | `6b62aa482` | `wai-pack-gpu` uses per-call Validation and OutOfMemory error scopes (thread-local in wgpu 30 with `std`). The kernels are claimed exact on Metal only. The CHANGELOG says older verifiers refuse `fabrics`. | | #438 S8 | `6d90c17df` | `encode_with` refuses a vector outside the search window (`field_range`). | | #438 N6 | `9b5c99e49` | `wai::jwp_hash::DOMAIN_OBJECT` replaces a hand-written domain. | | #452 M1 | `ae487223f` | `wgsl-conformance` gets its sidecar exclusion. This was the cargo-class corpora jobs' root cause: `every_decoded_output_states_a_sha256` read a `sha256.json` the new corpora lack. With platform-decode left out, only this one entry is needed. | | #452 M2 | `344bbcbbc` | The rules check refuses `atomicLoad`/`atomicStore` (a load or store through a pointer to an atomic), with the review's plants and a storage barrier alone. | | #452 M3 | `841d7a66e` | Item 3 requires one atomic kind per word, with its result unused. | | #452 S1 | `4b5f73c1d` | Rule 8 looks for naga's signed wrapping (`as_type<int>(as_type<uint>(`, `asint(asuint(`), with a test that strips it. The workflow counts 17 tests. | | #452 S3 | `328121086` | No signed left shift in a kernel; item 4 says why. | | #452 S2, S4–S7, corrections, N5, N13; G2 reuse | `0ec788fe7`, `9b5c99e49`, `e71980901` | The tier is claimed only where a run on this revision's kernels is recorded, with each run's report lines committed in `wai/research/ops-gpu-runs.txt` (minus the adapter-name field, a product name): Metal on an arm64 desktop and Chromium 148's WebGPU on it (the forge's run 10236, job 46928), and Vulkan on PCI 0x1002:0x1586 (Mesa 26.0.8) and llvmpipe (this train's run). The hand runs with no record (Linux 0x10de and 0x8086, Windows Vulkan and DX12, WARP) are named and not claimed. Item 6 covers backends with no PCI id. The rules check's scope is stated. "Every integer operation WGSL defines" is narrowed to what the kernels may use. The corrections: SPIR-V's signed `%`, HLSL `clamp`, FXC, §8.8/§8.10, the doc links. The §6 row cites the run. The subsection opens with an accelerator-general form, so #440 (G2) can rebase onto it rather than write a parallel rule. | The packaging CHANGELOG gains a line for the review fixes (`b270ac75d`). ## Checks Heavy checks ran on the build host through `rb`, with one target directory per workspace as CI has. A first run with one shared target directory let wai-pack pick up a `wai` built with another workspace's features, which no CI job can hit; its wai-pack steps were rerun. The trees: `87618bbe` (the train before main's #451), `f3a04b82` (after it), and the head for the last two rows. | Check | Command (as the workflow runs it) | Result | |---|---|---| | Merge cross-wiring | `python3 ~/kani-logs/wfsteps.py HEAD origin/main pr/426 pr/438 pr/452` | 2 problems, both steps changed on purpose: `wai-ops-gpu.yml` metal "The probe, the corpus…" (the test count 16 → 17) and `wai-pack.yml` media "The goldens' floors read and decode" (the prober fix) | | Workflows parse | `ruby -ryaml -e 'ARGV.each{\|f\| YAML.load_file(f)}' .github/workflows/*.yml` | ok | | Repo checks | `check-tests-in-ci.py`, `check-workflow-concurrency.sh`, `check-spec-refs.py`, `check-wai-section-refs.py`, `check-no-vanity-metrics.sh`, `test-public-text-checks.sh`, `check-comparative-prose.sh`, `check-orphan-sources.py` | all pass | | Public names | `WAI_NAME_DENYLIST=… bash scripts/check-public-names.sh <every changed text file>`; `grep -E` over every commit message | clean (232 files); messages clean; no address, host or vendor name in the diff | | Advisories | `python3 -I scripts/check-advisories.py` | the train adds none (tokio fixed). It fails on main's own RUSTSEC-2026-0385 (ctutils) and RUSTSEC-2026-0387 (crypto-bigint), in lockfiles identical to main's; #449 fixes those | | wai-rs, the cargo-class corpora job (unix) | build; lib unit tests; JPEG AI math; container limits; fast kernels with overflow checks on and in release; each feature alone and the wasm32 builds; carriage, CLI and provenance; http commands; world; staged MoQ; C ABI; signer ids, wai-keys, key_log wasm32 | all pass (formerly red at `int_kernels_vectors`) | | Corpora regenerate byte for byte | the conformance workflow's `v …` loop over all 21 corpora, `wai_claim_vectors` included | all pass | | `registry export --check` | `cargo run -q --no-default-features --bin wai -- registry export --check` | ok | | `include/wai.h` after a build | `touch cbindgen.toml && cargo build … --bin wai_http_vectors && git diff --quiet -- wai/wai-rs/include/wai.h` | unchanged | | HTTP corpus falsify | `bash wai/http-conformance/falsify/run.sh <work> --patches I/3` for I = 0, 1, 2, as the CI job runs it | all three pass (formerly red at the first patch) | | Independent verifiers | `claim_verify.py` and `differential.py --random 2000`, `jwp_verify.py`, `signer_verify.py`, `http_verify.py` and its fuzz differential, `pin_verify.py`, the audio provenance check, the OER C kernel | all pass | | wai-pack | `cargo clippy --locked --all-targets -- -D warnings`; `cargo test --release --locked --no-fail-fast`; the test-count floors; `wai-pack conformance check ../pack-conformance` (after `conformance regen`) | all pass | | wai-pack on the GPU (Metal) | `cargo clippy --all-targets --features gpu,fabric-meter -- -D warnings`; `WAI_PACK_GPU_REQUIRE=1 cargo test --release --locked --features gpu --test fabric` | pass: every golden packed on the GPU is the committed package byte for byte, and the conformance check above recomputes them on the CPU, so CPU and GPU packs are identical | | wai-pack-gpu (Metal) | clippy `-D warnings`; `WAI_PACK_GPU_REQUIRE=1 cargo test --release --locked` with the workflow's greps | pass | | wai-pack's meter and attribution | `cargo test --release --locked --features fabric-meter --lib fabric` | pass | | pack_verify.py | `pack_verify.py pack-conformance`, and `--jobs 2` | pass | | Differentials | `source_diff.py` (debug and release), `policy_diff.py`, `segment_diff.py`, `stage_diff.py`, `cmaf_diff.py`, `png_diff.py` | pass | | wai-ops-gpu | clippy `-D warnings`; the `metal` job of `wai-ops-gpu.yml`, its text run step by step: the probe, the corpus at both widths, the mutants and the semantics suite with `WAI_OPS_GPU_REQUIRE=1`, the capability corpora with their graphs on the GPU, main's exact-upscale derivations on the GPU, and the browser leg | all pass, 17 tests | | Vulkan, cross-vendor | `WAI_OPS_GPU_REQUIRE=1 cargo test --locked --release -- --nocapture --test-threads=1` on a Linux x86_64 host, PCI 0x1002:0x1586 (Mesa 26.0.8) and llvmpipe | pass: 17 tests; semantics 254,464 cases with none differing, guarded or not; the probe equal; the corpus mismatches=0 errors=0; 18 of 18 mutants. The report is committed. The Linux host with PCI vendors 0x10de and 0x8086 needed an interactive login and was not reached | | Lockfiles | `./scripts/check-lockfiles.sh`; `cargo metadata --locked --offline` for wai-rs, wai-pack, wai-pack-gpu, wai-ops-gpu and wai-web | clean | | Media prober | the step's committed text, extracted from `wai-pack.yml` and run over the goldens with ffmpeg 9.0.2 (CI has 4.4.2) | every golden passes, `video-cmaf-01` and `video-floor-only-02` included | ## Falsifications Every new check was committed before it was falsified. Each case broke the rule in rb's checkout, required the guarding test to fail, restored the file through git, and required the test to pass again (`.ps-falsify.sh`, not committed): - **The fabric attribution:** - the sole-user rule removed: fails; - another process's vanished client no longer charged: fails; - rail liveness removed: fails; - the whole rail replaced by a busy-time split: this first passed, because the fixture gave this process all the GPU's time. The fixture was fixed (`c6b41ee5c`), and the case now fails. - **Zero shares:** the packer's zero-share refusal removed (fails); claim rule 6's `> 0` removed in Rust (`wai_claim_vectors verify`, fails) and in Python (`claim_verify.py`, fails). - **The CMAF floor:** the per-sample sync check removed (fails); the `av1C`/size check removed (fails); `pack_verify.py`'s `init_agrees` made always true (an altered `av1C` level is then accepted). - **Other code checks:** `encode_with`'s window check removed (fails); the rules check's atomic-load refusal and signed-left-shift refusal each removed (`wgsl_rules`, fails). - **The media prober**, on a scratch copy of the corpus with the committed step text: - the golden passes, and so does a control remux of its source; - a real key frame moved in the bitstream (temporal unit 59 dropped and 61 repeated, so the key frame of 60 sits at 59, remuxed with `supplied_cmaf.py`'s ffmpeg recipe) fails: "key frames at 0 59 85 135 160; the plan says 0 60 85 135 160"; - a sample duration of 47999 ticks fails by name; - an edited plan fails. Editing the `trun` sync flags alone does not move ffmpeg's K flag, because its AV1 parser takes key frames from the frame header. So the step reads real key frames. - **The header:** without the regenerated header, a build dirties the tree (the CI failure, reproduced on the build host). With it, the forced rebuild leaves the tree clean and the three falsify shards pass. - **Rule 8:** its test strips naga's wrapping from `ops32`'s MSL and HLSL and requires a refusal; the stripped MSL still carries the bare bitcasts, which the old check took for the wrapping. ## Not done - **Platform decode in dispatch** (#452 part 2) is left out by the review's split; EN-C takes it over. - **The capability corpora on the Vulkan adapter:** `wai-rs/tests/ops_gpu.rs` did not run there, and §5 says so. - **Unreached GPU hosts:** the Linux host with PCI vendors 0x10de and 0x8086 (it needs an interactive login) and the Windows host's adapters. Their hand runs stay unclaimed until a recorded run. - **The metered pack's figures** in `wai/research/cross-fabric.md` are the meter's first revision, one run each; the note says so. No metered pack was repeated under the new meter. - **No verifier enforces "no fabric record without a step vocabulary"** (#438 S10). It is a producer MUST in energy-measurement §6.3. - **The reviews' NOTEs not acted on:** - #426: N1, N2, N4–N12; - #438: N5, N7–N11, N13, N14; - #452: N6–N12, other than N7 and N13, which were applied. - **After this lands:** G2 (#440) rebases onto the accelerator-general subsection of determinism-tiers §5; its three conflicts there are expected. - **CI:** the media prober uses CI's ffmpeg 4.4.2, which this train did not run locally (9.0.2 was used). The forge run of this branch will show it. ## What deploys beyond the repo - **The status page** (`wai-transaction-science-web`, branch `status/wai-gpu-int-tier`, commit `980639b`, not merged). Before it goes live: - `envelope-tiers-gpu`'s adapters must match §5 as narrowed: Metal and its browser WebGPU, and Vulkan on PCI 0x1002 and llvmpipe; - the `envelope-dispatch-platform` row, and the WebCodecs and Media Capabilities references, belong to the platform-decode part that this train leaves out, so they should not go live with it; - `envelope-tiers` and the WGSL reference row stand. - **No other site page, service or published binary changes.** `wai-pack` with features `gpu` and `fabric-meter`, and `wai-pack-gpu`, are repository crates, not published. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
One squashed history of three stacked PRs, onto main at b16816671:

- #426 (wai/pack-efficiency): a title's whole AV1 ladder in one package over one
  integer base; several floor rungs (packaging §7.1), a re-pack from a parent
  (§11.5), a floor that is the ladder's own CMAF (§7.7), a floor-only profile
  (§7.8), a streaming pack (§11.4), and the independent verifier at scale (§9.4).
- #438 (wai/cross-fabric): each pack and verify step on the fabric with the least
  measured energy (§11.6); the `fabrics` member of measurement claims
  (jwp-receipts §2.4.8, energy-measurement §6.3); the wai-pack-gpu crate;
  `wai-pack fabric`; `wai-pack floor-decode`.
- #452 (wai/gpu-int-tier), its GPU-tier part only: claiming decode-equivalence on a
  GPU (determinism-tiers §5), the WGSL integer semantics suite, the rules check on
  naga's IR, and the kernels' shift masks and min(max()) clamps.

Left out, by the review's split (EN-C takes it over): #452's platform decode in
dispatch, its commits 6ad92e2e8, 8695bc75f and fed8694f4 and its CHANGELOG entry:
extensions/platform-decode.md, platform-decode-conformance/, wai::platform_decode,
wai-web's platform_decode bundle and demo, and its two SPEC.md sentences.

#438's research note is not carried as written: it is rewritten as
wai/research/cross-fabric.md, with hardware named by architecture, PCI id and OS
version, and every table marked as one run. floor_decode.rs and a wai_pack.rs
comment name the platform's media engine and a full-length film the same way.

wai/CHANGELOG.md is the union of both sides' entries, the stack's first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review M2. The media-prober job (test 14) compared ffprobe's packet pts with
the plan's frame numbers. A pts is in the track's timescale: the packager's own
floors tick once per frame, so they matched, but video-cmaf-01's floors are a
muxer's fMP4 at timescale 1/1200000 with 48000 ticks per sample, so its key frames
read 0 2880000 4080000 6480000 7680000 against the plan's 0 60 85 135 160. The
floor was right; the check was wrong.

Each key frame's index is now its pts over the sample duration, and every sample
must sit one duration after the one before it (constant duration, no gap, in
order), so the index is also the packet's ordinal, the review's NR-1, and an
off-grid sample is refused by name instead of read as a moved key frame. The step
now reaches video-floor-only-02, which passes. The packages are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#438 review M5. #438 committed wai/wai-pack-gpu/Cargo.lock with tokio 1.54.0
(RUSTSEC-2026-0384, yanked), reached through wasm-bindgen-futures; main's advisory
sweep (#443) moved every other lockfile to 1.54.1, and its gate
(scripts/check-advisories.py) refuses the new one. Resolved with
`cargo update -p tokio --precise 1.54.1`; nothing else in the lockfile moves.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review M1, the root cause of its red cargo-class corpora jobs (linux,
linux-arm64, macos). int_kernels_vectors.rs every_decoded_output_states_a_sha256
holds every wai/*-conformance directory to a sha256.json sidecar, or to an
exclusion naming why it has no decoded output. #452 added wgsl-conformance/ (and
platform-decode-conformance/, which this train leaves out) with neither, so the
test read a sidecar that does not exist, and every step after it never ran.

wgsl-conformance decodes nothing: each case states its operands and result word in
full. It is listed with that reason, as ops-conformance is. The rule is unchanged:
a corpus with neither a sidecar nor a reason still fails.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review M1. #426's stage_index.rs adds `pub const PIECE_KIND_NONE: u8 = 6`,
which cbindgen exports, but #426 left the committed header as main's. So the first
build of wai-rs rewrote include/wai.h, the tree was dirty, and every HTTP corpus
falsify-patch shard failed its first "the tree is clean after reversing the patch"
check. The header now holds the define, exactly the six lines the build writes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review M3. §11.4 refused "a component with no source (pack-source-missing)",
which contradicts §7.8, whose floor-only component has no source by definition
(and §3.4 item 8 refuses one that has a source). The refusal is now the standard
profile's. The packer already agrees: pack.rs asks for a source only when the
component is not floor-only.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review M4. pack_into started the meter only after the source's first read and
scene cut, every supplied-floor check (nearly all of a floor-only pack) and a
re-pack's full verification of its parent (about 40% of a re-pack), while the
receipt's figure read as the pack's energy and no text said what it bracketed.

The meter now starts once the policy's own refusals have passed, before the
source's first read, so it covers both reads, the floor checks, the parent's
verification, every piece and every file, and stops before the receipt is sealed.
§9.4 states that bracket as a MUST. The fabric meter (#438) is started at the same
call, so the fix carries through it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review M2. naga lowers `atomicLoad` to a plain `Expression::Load` and
`atomicStore` to a plain `Statement::Store` through a pointer to an atomic, and the
closed lists accepted both without looking at the pointee; only `Statement::Atomic`
and `AtomicResult` were inspected. So `O[t] = atomicLoad(&F[...])`,
`atomicStore(&F[...], 0u)`, and `atomicOr` then `atomicStore` on one word all passed
rule 6, though each result depends on scheduling.

Rule 6 now refuses a load from, or a store to, any pointer whose pointee is atomic.
The planted cases are the review's three, plus a storage barrier alone (N7), which
rule 6 refuses on its own rather than through rule 2's workgroup plant.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review S3. naga routes only signed add, subtract and multiply through unsigned
in MSL; a signed `<<` goes out as written, and in MSL (C++14) a left shift of a
negative or unrepresentable signed value is undefined. The suite marked shl_i32
guarded for every amount below 32, and the rules check accepted
`bitcast<i32>(A[t]) << 31u`. No kernel shifts a signed value left today.

Rule 5 now refuses a left shift with a signed left operand in a kernel (shift the u32
and bitcast), with that plant. Item 4 and the paragraph before it name the case, and
say that a right shift of a negative value, which MSL leaves to the implementation,
is held by item 5's suite on the adapter.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review M3. Item 3 listed atomicOr, atomicAnd, atomicMin, atomicMax, atomicAdd
and atomicSub as order-free. Each is, alone; two on one word are not (atomicOr then
atomicAnd gives 0 from 0, the reverse 1; atomicMin with atomicMax the same). Item 3
now requires every atomic operation on a word to be of one kind (atomicAdd and
atomicSub counting as one), no load, store, exchange or compare-exchange to reach
it, and its result unused. The rules check enforces this for the shipped modules:
rule 6 admits atomicOr alone, with its result unused, and refuses atomic loads and
stores (the previous commit).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The fabric meter is rebuilt on a pure attribution (src/fabric_attribution.rs,
compiled on every OS so its tests run in every leg) over what the macOS meter reads.

- #438 review M1, the 99% sole-user rule. GPU time was summed over the clients
  present at each end, so a client that exited mid-span took its whole lifetime's
  time with it, and `d_all.max(m)` then read a shared GPU as 100% this process's.
  The clients are now read every 200 ms through the span, keyed by registry entry
  id and differenced between reads: a negative difference, a failed read or a
  vanished client of this process refuses the span; another process's vanished
  client is charged its whole interval; nothing is clamped. The first client read
  is before the rail's start edge and the last after its end edge, so the busy
  window encloses the rail's.
- #438 review M2, no 0 J share from a missing or frozen reading. A failed registry
  or rail read refuses the span; the rail must be live through it
  (energy-measurement §3.1, wai::energy_report::Liveness, as CounterMeter); GPU time
  with a rail of 0 refuses; a span with no GPU time has no GPU share at all; and the
  packer's fabric_record refuses a fabric that ran steps with no share or a share of
  0 (so GPU calls whose time went unseen are refused there). A begin() that fails
  keeps its reason.
- #438 review M3, the class. The figure is sealed OnChipCounter, filtering Unknown,
  with a declared 5% relative uncertainty combined with the register resolution over
  the span's window, never ModelBased; Meter::kind says OnChipCounter.
- #438 review M4, `rail`. The GPU share is the whole rail over the span, never the
  rail times a share of busy time.
- #438 review S1, `task` is ri_energy_nj + ri_billed_energy - ri_serviced_energy
  (rusage_info_v6 fields 40, 31 and 32, checked against the SDK header), EN-A's
  definition.
- #438 review S2. Each end's task read is taken only once the reading thread's own
  count (PROC_PIDTHREADCOUNTS) is seen to fold across a sleep, as sandbox-meter's
  probe does; a span is at least 1 s and five sampling intervals.
- #438 review S3. The rail's idle and static draw and its window are stated in the
  module, the attribution and §6.3 (next commits); the window is sealed through the
  uncertainty's window_us.
- #438 review S4. The attribution's outcomes are unit tests: the sole user, no GPU
  time, a shared GPU, another process's vanished client, this process's vanished
  client, time going backwards, failed client reads, a frozen or lump rail, a failed
  rail read or no rail, unread or non-advancing task energy, and spans under the
  minimum.

`wai-pack fabric calibrate` takes its spans at 1 s or more, and prints the meter's
reason when it gives no figure. GpuRail's Send note no longer cites a lock that does
not exist, and two `GPU Energy` channels are refused rather than summed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#438 review SHOULD-FIX: the neural-processor fabric was `neural`, while
determinism-tiers §5 and G2 (#440, `wai-ops/1-npu`) say NPU. The term is now `npu`
in energy-measurement §6.3, packaging §2, jwp-receipts §2.4.8 rule 6 and its reasons
table, wai::claim_receipt::FABRICS, claim_verify.py and wai-pack's Fabric (variant
Fabric::Npu). No committed vector names the old term.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #438 review M2, the claim half. jwp-receipts §2.4.8 rule 6 accepted a GPU step
  with a GPU share of 0, which is how a missing or frozen GPU reading was sealed. A
  fabric a step names now needs a share of more than 0
  (`measurement_fabric_unmetered`), in the text, the reasons table,
  wai::claim_receipt and claim_verify.py.
- #438 review M3. The fabric accept vector's figure is an OnChipCounter one,
  declared 5% over 1.2 s, as the reference meter seals; the fabric vectors sit after
  the pinned prefix, which is unchanged.
- #438 review S11. Appended: a GPU share of 0 beside GPU steps, an unknown fabric
  in a step, a (step, fabric) pair twice, fabrics out of order within one step, steps
  with no share, a step missing its backend (missing_required_field) and an extra
  member on the record (unknown_member).

The corpus is regenerated in a later commit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #438 review S5. Item 1 defined a MUST by pointing at a code function
  (`wai_pack::fabric::qualifying_frames`), which a second implementer cannot meet. It
  now states what a qualifying set holds at the least, for the motion search (noise,
  a smooth field, a flat field, alternating columns, sizes not a whole number of
  blocks, three block sizes, full-pel and half-pel, ranges to the edge), for SSE and
  for BLAKE3 (lengths around a chunk and past four chunks), each of which the
  reference set covers; the reference's set is named as informative.
- #438 review S9. Item 3 required the device and driver of a hardware-encoded floor
  in `derived_from.renderer`, which §7.5 does not. §7.5's MUST now carries them for a
  hardware encoder, and item 3 points to it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #438 review M3. A figure divided by fabric is sealed under its weakest share's
  class; the reference meter's shares are OnChipCounter readings (§2.9), filtering
  Unknown, with a declared 5% uncertainty over the span, so its figure is
  OnChipCounter. A fabric that ran a step has a share of more than 0.
- #438 review S1. `task` on the reference hosts is ri_energy_nj + ri_billed_energy
  - ri_serviced_energy, and S2: each end's read waits for the reading thread's fold,
  and a span lasts at least 1 s and five intervals.
- #438 review M1. `rail` states how sole use is read: every 200 ms, per user by a
  stable identity, the busy window enclosing the rail's, a vanished user of the
  work's own or a negative difference giving no share, another's charged its
  interval, nothing clamped; and the residual, a user that lives between two reads.
- #438 review S3. A `rail` share includes the fabric's idle and static draw, and
  its window can exceed the span by up to one republish period on each side.
- #438 review S10. A figure profile defines its step vocabulary, and a report about
  a figure whose profile defines none MUST NOT carry a fabric record.

M4 needs no text change: §6.3 already defined `rail` as the whole rail; the code now
seals that.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review S1. Rule 8 checked signed add, subtract and multiply by looking for
`as_type<uint>(` in the MSL and `asuint(` in the HLSL, which every
`bitcast<u32>(i32)` also writes: modules with no signed arithmetic carried both, and
ops32 passed for a reason the check did not test. It now requires naga's nesting,
`as_type<int>(as_type<uint>(` (and its two-component form) in MSL and
`asint(asuint(` in HLSL. A new test takes the wrapping out of ops32's translations,
leaving its bitcasts, and shows each refused; wai-ops-gpu.yml counts 17 tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #452 review S6, S7. The adapters claimed are those the forge's run 10236 (job
  46928) of wai-ops-gpu.yml shows on this revision's kernel text: Metal on an arm64
  desktop (macOS 27.0.1) and Chromium 148's WebGPU on that GPU. The Linux and Windows
  Vulkan, DX12 and software adapters were hand runs with no record committed, and
  G1's 0x1002 adapter ran the kernel text before the shift masks; none is claimed now.
  Committing their report lines would publish adapter product names, so the claims are
  narrowed instead. The §6 row and summary cite the forge run (N13).
- #452 review S5. Item 6 says what a claim names where the backend reports no PCI
  identity and no driver (Metal, a browser's WebGPU).
- #452 review S2. The rules check holds items 1, 2 and 4 and item 3's atomic and
  barrier parts; write-once and in-bounds rest on the host's indexing and wgpu's
  bounds checks, which the checked module creation keeps on.
- #452 review S4. The suite covers every integer operation a kernel may use (rule 7),
  not every one WGSL defines: in §5, wgsl-conformance/README.md.
- The corrections: SPIR-V's signed remainder is guarded even with the checks off;
  HLSL also writes integer `clamp` as `clamp` (spec and semantics::UNGUARDED);
  DX12 goes through FXC; semantics.rs cites WGSL §8.8 and §8.10; its intra-doc links
  name `Op::guarded_case` and `Op::ShlU32`, which exist (N5).
- The subsection now opens with the conditions in general form for any accelerator,
  and states that the items are their GPU instance, so G2's NPU text (#440) can reuse
  it rather than write a parallel rule.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`wai_claim_vectors gen` over the changed fabric vectors: the accept vector's class
is OnChipCounter, and seven vectors are appended (581 to 588). The 567-vector prefix
before the fabric record is unchanged, as its pinned digest requires.
claim_verify.py gives every vector its expected verdict.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-pack denies floating-point arithmetic (clippy's float_arithmetic, so no package
byte can depend on it), and the meter's OnChipCounter declaration was computed in
f64. It is now computed in integers: the declared 5% and the register resolution
(⌈408,249 / µJ⌉ ppm) in quadrature, each step rounded up, through
Uncertainty::new.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #426 review S1. §11.4 said what a packer holds is not a function of the source's
  length; a re-pack holds its parent whole while it verifies it (load_parent reads
  every file), so its memory grows with the parent. §11.4 now says so.
- #426 review S7. §11.5 said every check runs before anything is written, but check
  3 runs as each piece is coded; it now says checks 1 and 2 before, check 3 as it
  reads each piece, leaving nothing written.
- #426 review S8. §11.2's re-pack equivalence needs a parent packed by a conforming
  packager of the same identity, as §11.2 itself exempts other identities.
- #426 review S9. §7.4 and §7.8 said no `replicate` claim covers a floor, while
  every floor object's manifest writes `intent: "replicate"`. They now say that it
  promises only the capability's decoder conformance, and that no tier and no claim
  against a primary or a source covers it.
- #426 review S10. §7.8 said a sink checking an object's hash receives the signer's
  bytes, but a floor-only package's catalogs list no WAI object. It now states what
  a sink can check in each form, and that browser-sink §7's binding does not apply.
- #426 review S12. §7.2's first sentence is rewritten so it no longer reads as if a
  floor-only floor names a base.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S5. The "timescale altered" branch wrote at mdhd's type offset + 20,
which in version 0 is the duration, not the timescale (+16; +24 in version 1).
Neither reader reads the duration, so the branch always gave ok/ok and a timescale
of 0 was reached only by a stray bit flip. The offset now follows the box's version;
on video-cmaf-01's init, +16 reads 1,200,000 and +20 the duration, 0. The elst
offsets were right.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S11. `wai-pack verify --parent` mapped every read_strict error to
`unexpected-file`, the parent's too. A parent that cannot be read is one that does
not verify, which §11.5 names `repack-parent-invalid`; `unexpected-file` stays the
package's own.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S4. measurement_claim_fault compared profile, index, group, joules,
class and signer by hand, beside claim_verify.check_figure, the normative step 6 of
jwp-receipts §3.1 with its own reasons; #438's `fabrics` would have drifted from a
private copy. It now builds the receipt's view (profile, receipt hash, no group, its
one figure with the class class_of_json reads, its signer) and calls
CV.check_figure, keeping as local additions the subject type, the class's evidence
members as written, and the record's §11.6 step vocabulary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S3. In the CMAF form only each segment's first sample had its sync
flag checked (floor.rs, verify.rs, and pack_verify.py's two readers), so a non-key
frame flagged as a sync sample was accepted, while the ladder's flags reach players
unchanged and players seek by them. §7.7 (step 4) and §11.3 now require every
sample to be a sync sample exactly when its unit starts at a shown key frame
(`floor-cmaf-malformed` at the packer, `floor-cmaf-mismatch` against a package), and
the packer's check_cmaf, the verifier's cmaf_supplied and pack_verify.py's
verify_supplied_cmaf and cmaf_package_files hold every sample to it, from the units'
own key frames.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S6. reseal_as swallowed cmaf_supplied's error, so the
`segment-not-the-supplied-one` vector silently lost its `hi` floor: its catalogs
listed `lo` only and its overlay removed hls/classic/floor-hi.m3u8, three faults
where its README describes one. reseal_as now propagates the error, and the mutation
reseals through reseal_renamed, which renders the catalogs naming the replacement
segment, so the one fault is the segment's binding to `floor.listing`. The corpus is
regenerated in a later commit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#426 review S2. With a CMAF floor the playlists' CODECS and RESOLUTION come from the
in-band sequence header, while players (and Media Capabilities, through
http-delivery §12.2) configure from the ladder's own av1C, and nothing checked that
the two agree. §7.7 (step 4) and §11.3 now refuse an init whose av01 entry has no
av1C, or whose av1C profile, level, tier, bit depth, monochrome and chroma fields,
or sample-entry width and height, are not the sequence header's and its maximum frame
size. Both Rust readers (cmaf_read::read_init reads the record and the size;
floor::init_disagrees compares, in check_cmaf and in verify's cmaf_supplied) and
pack_verify.py (cmaf_init and init_agrees, in both CMAF paths) apply it.

tests/cmaf.rs refuses an av1C one level higher and a sample entry one pixel wider,
and (for S3) a segment whose tfhd default flags make every non-key frame a sync
sample, each `floor-cmaf-malformed`. On video-cmaf-01, both rungs' inits agree
(81000c00 at 64x36 and 32x18).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#438 review S8. encode_with checked only how many vectors a MotionSearch returned,
so a search (a GPU backend among them) that gave a vector past -range..=range was
encoded: the payload still decodes, but it is not packaging §5.5's search, and §11.2
would break silently. Such a vector is now refused `field_range`, and the test adds a
search that returns one a step past the window.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #438 review S7. Device errors were collected in one uncaptured-error sink per
  device, and `settled()` took them all, so under `--jobs N` one thread could consume
  another call's validation or out-of-memory error and that call returned its output
  as Ok. Each `run` now pushes its own Validation and OutOfMemory error scopes and
  pops them after its read-back, refusing the call on either; wgpu 30's scopes are
  thread-local with its `std` feature, which this crate enables.
- #438 review S6. The crate docs, both Cargo.toml comments and the CHANGELOG said the
  kernels are exact on Metal, Vulkan and DX12; they were shown on Metal only. They now
  say so, that Vulkan and DX12 were not run and nothing is claimed for them, and that
  qualification at open is the gate on any adapter.
- #438 review N12. The CHANGELOG entry says a verifier before this revision refuses a
  claim carrying `fabrics`; it also states the meter's new class, its sampled sole use,
  the share of more than 0, and the `npu` term.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- #452 review S4, S6, S7. The GPU entry claimed the suite covers every integer
  operation WGSL defines, and listed Vulkan and DX12 results with no committed
  record. It now says every operation a kernel may use, the rules check's new
  refusals, the identity for backends with no PCI id, the accelerator-general form,
  and that the tier is claimed on Metal and its browser WebGPU, the forge run's.
- #438 review N6. wai-pack's GPU object-hash call wrote the domain
  `moq-jwp:object\x01` and its 15 bytes by hand; it uses wai::jwp_hash::DOMAIN_OBJECT.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The #426 entry records what its review's fixes changed: the meter brackets the whole
pack (§9.4), a CMAF floor's av1C and sample entry are its sequence header's and every
sample's sync flag is its unit's (§7.7, §11.3), and a re-pack holds its parent whole
while it verifies it (§11.4).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
check-wai-section-refs.py resolves a cross-document section only to a heading, and
packaging's 11.6 is a numbered paragraph under §11; §6.3's new sentence on step
vocabularies cited "§11.6". It cites "§11, its steps and fabrics", as the sentence
after it already does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
#452 review S7 asked for the hand-run evidence in the repository, or the claims
removed. The Metal and browser claims rest on the forge's run 10236 (job 46928);
this train ran the crate's tests with WAI_OPS_GPU_REQUIRE=1 on a Linux x86_64 host's
integrated GPU of PCI vendor 0x1002, device 0x1586 (Mesa 26.0.8), and its llvmpipe,
on this revision's kernels: the semantics suite (254,464 cases, none differing,
guarded or not), the probe, the corpus at both widths and the 18 mutants. Both
runs' WAI_OPS_GPU_REPORT lines are committed in wai/research/ops-gpu-runs.txt, each
as written but for its `adapter=` field, the device's product name. §5 claims the
0x1002 adapter and llvmpipe again; the §6 row and the CHANGELOG say what ran where,
and that the capability corpora did not run on the Vulkan adapters.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`wai-pack conformance regen` after the reseal fix: `segment-not-the-supplied-one`
now removes only the replaced segment, and its playlists and MPD name the
replacement (hls/classic/floor-hi.m3u8 is back, the masters list both rungs), so
the case's one fault is the segment's binding to `floor.listing`. Its moq catalog
names no segment and is the golden's, so the overlay no longer carries it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
clippy's type_complexity (denied in wai-pack's `--features gpu,fabric-meter` lint)
refused join's five-member tuple; it is the alias `Joined`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
One textual conflict, wai/CHANGELOG.md, where both sides added entries at the top
of v0.4.0; resolved as their union, the stack's first, no line of either dropped.
#451's registry export and vocabulary are main's: the train changes neither their
inputs nor wai-conformance.yml.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The packer's fabric_record refuses a fabric that ran steps of the pack with no share
or a share of 0 (#438 review M2); no test held it. the_fabric_record_rides_in_the_
measurement_claim now packs with an empty split and requires the packer's own reason,
not only the claim's sum rule one layer down.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Two of the review-fix tests were wrong, not the checks:
- the "sample entry wider" case (#426 review S2) took the first `av01` in the init,
  which is ftyp's compatible brand, so it edited ftyp and the pack was accepted; it now
  finds the av01 entry after stsd (64x36 on video-cmaf-01's hi init);
- the_package_binds_the_supplied_bytes replaced a segment and resealed with the plain
  reseal, which now (#426 review S6) refuses a supplied floor that does not check; it
  reseals with golden::reseal_renamed, as the corpus case does, so the package's one
  fault is the binding, which the verifier still refuses (floor-cmaf-mismatch).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Falsifying #438 review M4 (the rail sealed whole) showed its test could not fail:
the sole-user fixture gave this process all of the GPU's time, so the rail times
mine/all was the rail itself. Another client now holds 0.5% of the GPU's time, still
sole use, so a busy-time split would give 2,388,000 uJ against the whole rail's
2,400,000, and the test requires the latter.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main (#462, #464) into train/pack-stack
Some checks failed
wai-pack / wai-pack · linux (pull_request) Successful in 1m51s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 13m48s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 9s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 20m46s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 23s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m23s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 13m36s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 2m53s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 20s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 44s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 4m51s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 5m51s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 7m57s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 4m13s
wai-pack / wai-pack · macos (pull_request) Successful in 2m30s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 2m7s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 39m31s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 30m46s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 30m29s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 5m21s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m6s
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 2m3s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m16s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 5m31s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m18s
wai-pack / wai-pack · the floor through a media prober (pull_request) Failing after 21s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m7s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 6m17s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 30m55s
7971c3338f
One textual conflict, wai/CHANGELOG.md (both sides added entries at the top of
v0.4.0), resolved as their union, the stack's first. Every other file main changed
(joule-moq-relay, joule-moq-room's tests, co-performance, wai-quantum-service) is
outside the train's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-pack media prober: the sample spacing from the first two timestamps, not the first duration
Some checks failed
wai-pack / wai-pack · macos (pull_request) Successful in 4m54s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m13s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 23m1s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 12m7s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 23m56s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 35m15s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m53s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 5m45s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 5m16s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 32m33s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 5s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 32m43s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m49s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m31s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 49m47s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 21s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 2m0s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m32s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m25s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m55s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m15s
WAI conformance / cargo-class corpora · linux (pull_request) Failing after 9s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 29s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m12s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 2m23s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 4m20s
wai-pack / wai-pack · linux (pull_request) Successful in 2m26s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 10m21s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 2m46s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 4m18s
e73ea1667f
CI's ffprobe 4.4.2 reports no duration (N/A) for the first sample of the CMAF floor,
so the step refused video-cmaf-01 before reading a key frame. The spacing is now the
second sample's pts less the first's. Every sample must sit on that grid, and a
duration ffprobe does report must equal the spacing. A gap, an uneven duration or a
missing pts is still refused (checked on synthetic ffprobe output), and every golden's
key frames read as its plan.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge origin/main into train/pack-stack (Train C and wai-quantum 0.6.15)
All checks were successful
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m21s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 31m36s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m1s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h2m52s
joule-code conformance gate / Build + round-trip C1-C4 vectors (pull_request) Successful in 3m39s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 6s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 6s
wai-quantum on every processor / emulated · aarch64-unknown-linux-gnu (pull_request) Successful in 1m2s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 1m42s
wai-quantum on every processor / emulated · armv7-unknown-linux-gnueabihf (pull_request) Successful in 1m6s
wai-quantum on every processor / emulated · loongarch64-unknown-linux-gnu (pull_request) Successful in 1m44s
wai-quantum on every processor / emulated · powerpc64-unknown-linux-gnu (pull_request) Successful in 2m26s
wai-quantum on every processor / emulated · powerpc64le-unknown-linux-gnu (pull_request) Successful in 4m10s
wai-quantum on every processor / emulated · riscv64gc-unknown-linux-gnu (pull_request) Successful in 2m33s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 10m46s
wai-quantum on every processor / emulated · s390x-unknown-linux-gnu (pull_request) Successful in 2m33s
wai-quantum on every processor / emulated · sparc64-unknown-linux-gnu (pull_request) Successful in 4m33s
wai-quantum on every processor / emulated · i686-unknown-linux-gnu (pull_request) Successful in 2m40s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 6s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m22s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 35s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 9m43s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m43s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 2m58s
wai-pack / wai-pack · linux (pull_request) Successful in 1m36s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 19m48s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 2m48s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 4m53s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m50s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m49s
ad283d9281
Six files conflicted; both sides kept in each:
- claim-conformance: main's span vectors stay where main published them, and
  this train's fabric-record vectors follow them, so main's 615 vectors are an
  unchanged prefix of the 636. vectors.json regenerated with
  `wai_claim_vectors gen`; it verifies, and claim_verify.py passes all 636.
- jwp-receipts.md: a claim's two optional-member exceptions, the hybrid
  pq-signatures members and a measurement claim's `fabrics`.
- wai-ops-gpu: both modules (`semantics`, `splat`); the workflow header names
  both suites.
- CHANGELOG: this train's sections above Train C's, newest first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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!465
No description provided.