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

2026-10-26

Transaction Science
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
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]>
2026-10-26 02:28:39 -04:00

2026-10-25

Transaction Science
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
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]>
2026-10-25 21:14:57 -04:00
Transaction Science
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
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]>
2026-10-25 14:18:48 -04:00
Transaction Science
wai-pack fabric attribution: the sole-user case tells the whole rail from a busy-time split (#438 review M4)
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]>
2026-10-25 14:18:21 -04:00
Transaction Science
wai-pack tests/cmaf.rs: the width case edits the sample entry; the binding case reseals by rename
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]>
2026-10-25 04:48:09 -04:00
Transaction Science
wai-pack tests: a fabric that ran steps with no share is refused by the packer (#438 review M2)
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]>
2026-10-25 04:00:28 -04:00
Transaction Science
Merge origin/main (#451, live room train D) into train/pack-stack
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]>
2026-10-25 03:58:09 -04:00
Transaction Science
wai-pack fabric meter: a type for what a span's join gives back
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]>
2026-10-25 03:57:14 -04:00
Transaction Science
pack-conformance: cmaf-mutations regenerated (#426 review S6)
`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]>
2026-10-25 03:57:13 -04:00

2026-10-24

Transaction Science
determinism-tiers §5: the Vulkan run on PCI 0x1002, with both runs' reports committed (#452 review S7)
#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]>
2026-10-24 21:20:06 -04:00
Transaction Science
energy-measurement §6.3: cite packaging §11, as the section checker reads it
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]>
2026-10-24 21:14:59 -04:00
Transaction Science
CHANGELOG (packaging): the figure's bracket, the CMAF floor's agreements
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]>
2026-10-24 21:12:16 -04:00
Transaction Science
CHANGELOG (GPU tier) to what was shown; wai-pack names the object domain (#452 review S4, S6, S7; #438 review N6)
- #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]>
2026-10-24 21:12:05 -04:00
Transaction Science
wai-pack-gpu: per-call error scopes; the backends claimed are the one shown (#438 review S6, S7, N12)
- #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]>
2026-10-24 21:11:34 -04:00
Transaction Science
wai-rs encode_with: a search vector outside the window is refused (#438 review S8)
#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]>
2026-10-24 21:10:15 -04:00
Transaction Science
CMAF floors: the init's av1C and size are the sequence header's (#426 review S2)
#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]>
2026-10-24 21:09:39 -04:00
Transaction Science
wai-pack golden: a reseal that fails its CMAF check says so (#426 review S6)
#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]>
2026-10-24 21:06:25 -04:00
Transaction Science
CMAF floors: every sample's sync flag held to its unit (#426 review S3)
#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]>
2026-10-24 21:04:41 -04:00
Transaction Science
pack_verify.py: a metered package's claim checked by claim_verify's step 6 (#426 review S4)
#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]>
2026-10-24 21:02:52 -04:00
Transaction Science
wai-pack verify --parent: an unreadable parent is repack-parent-invalid (#426 review S11)
#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]>
2026-10-24 21:02:14 -04:00
Transaction Science
cmaf_diff.py: the timescale case alters mdhd's timescale (#426 review S5)
#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]>
2026-10-24 21:01:58 -04:00
Transaction Science
packaging: six wording findings (#426 review S1, S7, S8, S9, S10, S12)
- #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]>
2026-10-24 21:01:30 -04:00
Transaction Science
wai-pack fabric meter: its declared uncertainty in integers
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]>
2026-10-24 21:00:40 -04:00
Transaction Science
claim-conformance: the corpus regenerated, 588 vectors (#438 review M3, S11)
`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]>
2026-10-24 21:00:40 -04:00
Transaction Science
determinism-tiers §5: what the GPU leg showed, and an accelerator rule (#452 review S2, S4-S7, corrections, N5, N13)
- #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]>
2026-10-24 20:59:21 -04:00
Transaction Science
wai-ops-gpu rules: rule 8 finds naga's signed wrapping, not a bitcast (#452 review S1)
#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]>
2026-10-24 20:59:21 -04:00
Transaction Science
energy-measurement §6.3: the class, task, sole use sampled, the rail's window (#438 review M1, M3, S1-S3, S10)
- #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]>
2026-10-24 20:55:15 -04:00
Transaction Science
packaging §11.6 item 1 states the qualifying set; §7.5 holds the device (#438 review S5, S9)
- #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]>
2026-10-24 20:55:15 -04:00
Transaction Science
claims rule 6: a stepped fabric's share of 0 is unmetered; vectors (#438 review M2, M3, S11)
- #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]>
2026-10-24 20:55:15 -04:00
Transaction Science
fabric term npu, not neural (#438 review, the fabric term)
#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]>
2026-10-24 20:54:54 -04:00
Transaction Science
wai-pack fabric meter: sampled sole use, the whole rail, OnChipCounter (#438 review M1-M4, S1-S4)
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]>
2026-10-24 20:54:30 -04:00
Transaction Science
determinism-tiers §5 item 3: one atomic kind per word, its result unused (#452 review M3)
#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]>
2026-10-24 20:43:50 -04:00
Transaction Science
wai-ops-gpu rules, determinism-tiers §5: no signed left shift (#452 review S3)
#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]>
2026-10-24 20:43:35 -04:00
Transaction Science
wai-ops-gpu rules: refuse atomicLoad and atomicStore (#452 review M2)
#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]>
2026-10-24 20:42:59 -04:00
Transaction Science
wai-pack: the meter brackets the whole pack, and §9.4 says so (#426 review M4)
#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]>
2026-10-24 20:40:57 -04:00
Transaction Science
packaging §11.4: pack-source-missing is the standard profile's (#426 review M3)
#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]>
2026-10-24 20:40:13 -04:00
Transaction Science
wai-rs: include/wai.h regenerated with PIECE_KIND_NONE (#426 review M1)
#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]>
2026-10-24 20:32:37 -04:00
Transaction Science
wai-rs tests: wgsl-conformance names why it states no output digest (#452 review M1)
#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]>
2026-10-24 20:31:55 -04:00
Transaction Science
wai-pack-gpu: tokio 1.54.1, as #443 moved every other lockfile (#438 review M5)
#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]>
2026-10-24 20:31:48 -04:00
Transaction Science
wai-pack CI: the media prober reads key frames as frame indices (#426 review M2)
#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]>
2026-10-24 20:31:48 -04:00
Transaction Science
wai packaging stack: #426, #438 and #452's GPU tier, squashed onto main
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]>
2026-10-24 20:31:28 -04:00