wai: staged delivery — a base first, refinements after #149

Merged
dcharlot merged 37 commits from wai/land-17-staged-delivery into main 2026-10-05 04:55:35 -04:00
439 changed files with 23777 additions and 198 deletions

View file

@ -15,7 +15,9 @@ name: wai cross-architecture byte-equality
# and the MLIC++-topology codec (`wai.neural.int_mlicpp`), whose entropy network runs
# before every checkerboard pass and must give every platform the encoder's scale
# bucket for every element. The binary payloads SPEC §5 pins (WIV1, WIH1) are parsed
# with the wire parser a sink runs and decoded to the same digests. Video is the strictest leg — inter-frame decode is a
# with the wire parser a sink runs and decoded to the same digests, and the staged-delivery
# residual layers (WIR1) of the staged corpus are applied stage by stage to pinned digests.
# Video is the strictest leg — inter-frame decode is a
# feedback loop, so one divergent half-pel rounding does not stay one byte, it
# predicts the next frame and compounds for the rest of the clip.
#
@ -40,6 +42,10 @@ on:
- 'wai/wai-rs/src/int_hyper_synth.rs'
- 'wai/wai-rs/src/int_mlicpp.rs'
- 'wai/wai-rs/src/int_payload/wire.rs'
- 'wai/wai-rs/src/staged/predict.rs'
- 'wai/wai-rs/src/staged/wir1.rs'
- 'wai/wai-rs/src/staged/wir1_arith.rs'
- 'wai/staged-conformance/**'
# The fast kernels int_synth, int_transform and int_hyper_synth dispatch to
# by default: the goldens here decode through them.
- 'wai/wai-rs/src/int_kernels.rs'
@ -65,6 +71,10 @@ on:
- 'wai/wai-rs/src/int_hyper_synth.rs'
- 'wai/wai-rs/src/int_mlicpp.rs'
- 'wai/wai-rs/src/int_payload/wire.rs'
- 'wai/wai-rs/src/staged/predict.rs'
- 'wai/wai-rs/src/staged/wir1.rs'
- 'wai/wai-rs/src/staged/wir1_arith.rs'
- 'wai/staged-conformance/**'
# The fast kernels int_synth, int_transform and int_hyper_synth dispatch to
# by default: the goldens here decode through them.
- 'wai/wai-rs/src/int_kernels.rs'

View file

@ -33,6 +33,9 @@ on:
# A library test checks SPEC §5's pinned integer payloads against this
# extension's sections, so an edit of it is checked here too.
- 'wai/extensions/integer-payloads.md'
# A library test (staged::tests::staged_delivery_text_lists_the_codes) checks
# that this extension's §4.2 and A.6 list the codes the sink reports.
- 'wai/extensions/staged-delivery.md'
- 'wai/wai-web/**'
- '.github/workflows/wai-conformance.yml'
pull_request:
@ -55,6 +58,9 @@ on:
# A library test checks SPEC §5's pinned integer payloads against this
# extension's sections, so an edit of it is checked here too.
- 'wai/extensions/integer-payloads.md'
# A library test (staged::tests::staged_delivery_text_lists_the_codes) checks
# that this extension's §4.2 and A.6 list the codes the sink reports.
- 'wai/extensions/staged-delivery.md'
- 'wai/wai-web/**'
- '.github/workflows/wai-conformance.yml'
@ -114,11 +120,12 @@ jobs:
# and is checkable on this matrix with no ONNX Runtime present. receipt_claims
# is in the set because the reference meters (wai_meter, wai_world_meter) write a
# measurement report by default and require it: without it they would drop out
# of this build on every leg of this matrix, without a word.
run: cargo build --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,receipt_claims
# of this build on every leg of this matrix, without a word. staged and the integer
# media features build the staged-delivery core, its corpus tool and `wai stage`.
run: cargo build --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,receipt_claims,staged,video_int,audio_int,splat_int
- name: Library unit tests (the fixed-point determinism floors)
working-directory: wai/wai-rs
run: cargo test --lib --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,oer,receipt_claims,key_discovery
run: cargo test --lib --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,oer,receipt_claims,key_discovery,staged,video_int,audio_int,splat_int
# The JPEG AI exact decoder reproduces across platforms only if no platform math
# library is on its path. Two guards, each failing the step: clippy's
# disallowed-methods (wai-rs/clippy.toml), which each module on the decode path
@ -168,7 +175,11 @@ jobs:
# allocator) checks that a header past the caps is refused before anything sized from it
# is allocated; tests/int_payload_cost.rs (its own binary, a live-bytes allocator) checks
# that int_payload::declared_cost bounds what each decode holds, and, in the release
# step only, decodes a 2^30-byte clip a 3 KB payload codes. Cargo.toml declares them, and the other
# step only, decodes a 2^30-byte clip a 3 KB payload codes. tests/staged_resources.rs (its
# own binary, a counting allocator) checks that the staged sink's work and memory per
# layer grow linearly in the layer's units, that a layer past the chain budget is
# refused before any stream is decoded, that what no unit holds is dropped, and that a
# WIR1 parse holds no more than its declared working bytes. Cargo.toml declares them, and the other
# feature-gated targets named here, with required-features, so if this step ever loses a
# feature, cargo stops with an error instead of compiling an empty binary that reports ok.
# Each committed vector's decoded output is also checked against the SHA-256 in
@ -178,10 +189,10 @@ jobs:
# wai.generate.spectral vector, which `generate` enables.
- name: Fast integer kernels ≡ reference kernels (overflow checks on)
working-directory: wai/wai-rs
run: cargo test --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight --test int_audio --test int_splat --test generate --test int_payload --test int_payload_preflight --test int_payload_cost
run: cargo test --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate,staged --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight --test int_audio --test int_splat --test generate --test int_payload --test int_payload_preflight --test int_payload_cost --test cli_stage --test staged_resources
- name: Fast integer kernels ≡ reference kernels (release, overflow checks off)
working-directory: wai/wai-rs
run: cargo test --release --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight --test int_audio --test int_splat --test generate --test int_payload --test int_payload_preflight --test int_payload_cost
run: cargo test --release --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate,staged --lib --test int_kernels_vectors --test int_kernels_geometry --test int_mlicpp --test int_mlicpp_preflight --test int_audio --test int_splat --test generate --test int_payload --test int_payload_preflight --test int_payload_cost --test cli_stage --test staged_resources
# The integer decode path builds under each of its features alone, so a sink can take
# one medium without the others, and for wasm32 (a browser sink); `int_payload` arms a
# medium only under its feature, and none needs `neural`.
@ -191,11 +202,11 @@ jobs:
working-directory: wai/wai-rs
run: |
set -euo pipefail
for f in neural_int video_int audio_int splat_int; do
for f in neural_int video_int audio_int splat_int staged; do
cargo check --lib --no-default-features --features "$f"
done
rustup target add --toolchain 1.98.0 wasm32-unknown-unknown
cargo check --lib --target wasm32-unknown-unknown --no-default-features --features video_int,audio_int,splat_int
cargo check --lib --target wasm32-unknown-unknown --no-default-features --features video_int,audio_int,splat_int,staged
# carriage: every registered capability round-trips byte-exact. cli_wrap_intent and
# cli_registry run the `wai` binary, which builds without the codecs feature: the
# intent rule of `wai wrap`, its refusal of candidate capabilities (SPEC §5), its media
@ -266,7 +277,7 @@ jobs:
working-directory: wai/wai-rs
run: |
set -euo pipefail
F=world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int
F=world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged
v() { echo "::group::$1"; cargo run -q --no-default-features --features "$F" --bin "$2" -- verify "$3"; echo "::endgroup::"; }
v worlds wai_world_vectors ../world-conformance
v spatial-audio wai_audio_vectors ../audio-conformance
@ -285,6 +296,7 @@ jobs:
v pin wai_pin_vectors ../pin-conformance
v signers wai_signer_vectors ../signer-conformance
v int-payload wai_int_payload_vectors ../int-payload-conformance
v staged wai_staged_vectors ../staged-conformance
# The pin corpus's second implementation: Python standard library only, sharing no
# code with wai-rs. One leg is enough — it checks digests and listing rules, which
# do not depend on the architecture — and the macOS host has python3.
@ -313,7 +325,7 @@ jobs:
shell: pwsh
working-directory: wai/wai-rs
run: |
$F = "world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int"
$F = "world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,quantum,quantum_ops,oer,receipt_claims,key_discovery,video_int,audio_int,splat_int,staged"
function v($grp, $bin, $path) {
Write-Output "::group::$grp"
cargo run -q --no-default-features --features $F --bin $bin -- verify $path
@ -337,6 +349,7 @@ jobs:
v pin wai_pin_vectors ../pin-conformance
v signers wai_signer_vectors ../signer-conformance
v int-payload wai_int_payload_vectors ../int-payload-conformance
v staged wai_staged_vectors ../staged-conformance
# The generated v2 vocabulary (wai/vocab/v2.*) is checked as a consumer uses it:
# sample manifests, typed and untyped, WAI1 and WAI2, are expanded through the
@ -367,7 +380,8 @@ jobs:
# under a fixed seed, so a run is reproducible), jwp_verify.py (every JWP vector), and
# signer_verify.py (every key-discovery vector and the canonical fixture, with its
# verdicts required to equal wai_signer_vectors' line for line), and
# int_payload_verify.py (the integer payloads and their refusal fixtures).
# int_payload_verify.py (the integer payloads and their refusal fixtures), and
# staged_verify.py (the staged-delivery corpus).
# Each exits non-zero on any failure or any difference, and the step fails with it.
# One platform: what they check is the reading of the text, not the architecture.
independent-verifiers:
@ -412,6 +426,15 @@ jobs:
working-directory: wai
shell: bash
run: python3 int-payload-conformance/int_payload_verify.py int-payload-conformance
# The staged-delivery corpus's second implementation (staged-conformance/README): it
# replays every case from its stage-0 buffers through its own reading of the
# extension (refines, WIR1, the sink's steps, holds, batches, conflicts, deadlines,
# tiers, stage hashes), decodes the WIV1 keyframe-0, PNG and FLAC bases, explodes the
# WAI2 files, and replays the schedule. Standard library only.
- name: staged_verify.py
working-directory: wai
shell: bash
run: python3 staged-conformance/staged_verify.py staged-conformance
- name: claim_verify.py, differential.py, jwp_verify.py, signer_verify.py
working-directory: wai
shell: bash

View file

@ -33,6 +33,8 @@ on:
- 'wai/wai-rs/src/int_entropy.rs'
- 'wai/wai-rs/src/int_transform.rs'
- 'wai/wai-rs/src/wai_video_policy.rs'
- 'wai/wai-rs/src/staged/predict.rs'
- 'wai/wai-rs/src/staged/wir1_arith.rs'
# Not verified by any harness, but #[path]-included because int_transform's
# IGDN dispatches to it, so it must still compile under the model checker
# (its cfg(kani) branches are compiled nowhere else).
@ -47,6 +49,8 @@ on:
- 'wai/wai-rs/src/int_entropy.rs'
- 'wai/wai-rs/src/int_transform.rs'
- 'wai/wai-rs/src/wai_video_policy.rs'
- 'wai/wai-rs/src/staged/predict.rs'
- 'wai/wai-rs/src/staged/wir1_arith.rs'
- 'wai/wai-rs/src/int_kernels.rs'
- '.github/workflows/wai-formal-verification.yml'

View file

@ -11,7 +11,8 @@ name: wai-web wasm32
# capability, none is a candidate (SPEC §5), and the wasm build's own
# registry agrees with the export on every candidate;
# - demo/verify_pack.mjs: the browser writers `pack` and `packMulti` refuse
# every candidate the export lists, in every place an envelope can name one;
# every candidate the export lists, in every place an envelope can name one,
# and a manifest that names a member twice in one object;
# - a byte comparison of the demo's staged int_synth copies with the corpus;
# - the crate's wasm_tests under wasm-bindgen-test-runner, and its native unit
# tests on the host.
@ -90,7 +91,7 @@ jobs:
# bindings, which wasm_tests does not run. They decode the committed integer
# payloads to their sidecars' SHA-256 (int_payload::tests) and check that the
# writers `pack` and `packMulti` refuse a payload that is not the format SPEC §5
# pins its integer capability to (tests). The count check turns a test that
# pins its integer capability to, and a manifest that names a member twice (tests). The count check turns a test that
# stopped being compiled into a failure instead of a silent "0 passed".
- name: wai-web native unit tests
shell: bash
@ -98,7 +99,7 @@ jobs:
run: |
set -euo pipefail
cargo test --locked --lib 2>&1 | tee "$RUNNER_TEMP/wai-web-native.log"
grep -q "test result: ok. 8 passed; 0 failed" "$RUNNER_TEMP/wai-web-native.log"
grep -q "test result: ok. 9 passed; 0 failed" "$RUNNER_TEMP/wai-web-native.log"
- name: wasm32 int_synth decode equals the frozen native corpus
shell: bash
working-directory: wai/wai-web

View file

@ -6,6 +6,107 @@ wire format may change and such changes are recorded here.
## v0.4.0 — current
### Staged delivery: refinement layers, base admission, and WAI2 refinement components
- **The extension** [staged-delivery](extensions/staged-delivery.md): a stage set is a
base and layers, each layer its own `WAI1` envelope naming, by content hash, the
base and the producer each unit it covers is expected to have (`refines`: `base`,
`prev` as one producer or runs, `layer`, `span`). A sink holds per unit a stage, a
producer and a tier, and applies a layer per unit by one algorithm with a closed
list of reasons (§4.1, §4.2): every envelope-scoped step (well-formed `refines`, a
refinement capability with no fallback, the base present, not through a fallback,
admitted, attested, a well-formed payload within the sink's cost limit and its chain
budget) before the unit steps (conflict, readiness, geometry, deadline). Layers a unit is not ready for are held
to a declared bound and released when its stage advances; layers released together
form a batch, so two conflicting layers released together are both refused and the
unit frozen, whatever their order. A layer that differs from one that already passed
for the same unit freezes it at its stage. A unit's tier is the weakest of its base
and layers, `entropy-consistency` does not pass through a layer, and a stage hash is
stated only at `decode-equivalence`. Deferral, live deadlines (a sink never delays a
unit for a layer, and counts the units presented below the stage their layers would
have reached on time), attestation (a receipt verified without the layer's bytes
never authorizes an application) and byte counting (envelope bytes; receipts,
framing and parameter sets separately; never JSON or base64) are stated.
- **Resource bounds** (§4.5, §14, A.5): a sink declares a chain budget per base, over
its units' output, 32 bytes per stage, and the payload and declared working bytes of
every layer it retains with one unit's output and 32 bytes for each unit it covers
and has not been applied to; a layer that would pass it is refused
(`chain-over-limit`) before any stream is decoded, and a layer no unit is held for is
dropped. The declared working bytes count the stream index. A sink's work per layer
is linear in its payload and declared symbols up to a logarithmic factor in its
units, and §14 states how. A sink that drops a base's chain discards the layers held
for it (`base-absent`) and keeps each unit's record that is not empty (its
producers, a pending producer, its frozen flag), within a declared record budget
whose oldest bases are forgotten first; the base decoded again advances only along
that record, and a frozen unit replays only its own record, in order.
Decoding a base again keeps its chain, and a receipt verified for the base, before or
after it was decoded, makes it attested from then on, across dropped chains; a layer held for its base and offered
again keeps the strongest receipt evidence, and over an attested base counts as
arriving when its receipt was verified; a set split across bases shares one live
clock (`first_unit`).
- **The residual payload `WIR1`** (Appendix A): one rANS stream per unit;
`clamp(pred + r·q)` with the identity, up2 (the half-pel arithmetic, odd sizes
included) and rate (linear interpolation, `rdiv`'s halves away from zero, channels
interleaved) predictors. It follows the integer payloads' rules: a parse in a
stated order with the closed list of their codes, caps, a declared cost a sink reads
before decoding, refusal at the first symbol a stream runs out on, canonical stream
ends; and it reads no parameter set.
- **Refinement capabilities** (SPEC §5, *Refinement capabilities*):
`wai.image.int_refine`, `wai.video.int_refine`, `wai.audio.int_refine` and
`wai.splat.int_refine`, each refinement-only, royalty-free, `StandardDefined` and
exact given the base it refines. SPEC §8 adds the refinement-only role; SPEC §4 never
dispatches one, and a sink that does not implement the extension finds it
unsupported. The registry gains the `refinement` kind and role, and the export is
regenerated. *Envelopes this makes non-conforming* (they still parse): a `WAI1`
carrying a refinement capability without `refines`, with a fallback, or as a
fallback; `refines` on any other capability; a refinement capability as a `WAI2`
rendition or companion; a companion bound to one.
- **Base admission is one table** (SPEC §5, *Base admission*;
`codecs::BASE_ADMISSION`): the bases of each refinement and of the LCEVC enhancement
layer, whose bases are unchanged. `enhancement_bases`, `companion_applies_to` and
`admits` read it.
- **WAI2 refinement components** (SPEC §7.1), on the component identity (`id`,
`sha256`, `prior`; no other digest is defined): an entry with
`role: "refinement"` carries `refines` naming entries by `id`, follows every
selectable entry, is never selected, and is checked by `check_component_roles` in a
stated order. *Exploding a component* writes its `WAI1` envelope, from
`envelope_manifest` verbatim or from the `WAI2` manifest's members as written, with
ids replaced by the content hashes of the named entries' exploded envelopes, so a
component and the layer carried alone are the same object; `WaiMulti::pack` packs
`WAI1` envelopes with their manifests verbatim, and they explode back to the same
bytes; it refuses an envelope it could not give back (bytes around a manifest's JSON
value or after a payload, or a manifest that inside a `WAI2` passes the depth limit)
and checks its output before returning it. Each entry explodes on its own, so one
that cannot leaves the others intact. A refinement's `envelope_manifest` names no
fallback. A malformed `refines` or a mismatched `envelope_manifest` does not make a
manifest unreadable.
- **SPEC §2**: member names are unique within each object of a manifest, at any depth,
and an integer member is written as an integer (`-0`, `1.0` and `1e0` are not); both
readers refuse a manifest that breaks either. `span: null` is `span` absent.
- **Reference implementation**: `staged::{StageChain, StageSink, wir1, predict,
wir1_arith, tier, schedule}` (feature `staged`); `container::{Refines, Prev}`;
`WaiMulti::{explode, explode_each, explode_all, pack, check_envelope_manifests,
refinements_of}`; `container::check_unique_members`; `wai stage
refine|apply|inspect|pack|explode` (`refine --out-dims` gives a layer's shape);
`StageSink::{remove_base, forget_base, mark_attested}`; `wai wrap` refuses a refinement
capability, and `wai inspect` shows `refines`. `RansEncoder` writes the bypass
escape, and `int_entropy::hist_to_cdf` builds a table from a histogram in integer
arithmetic. In `ternary::rans_encode_trits`, the encode call sat inside
`debug_assert!`, so a release build coded no symbol; it now runs in every build.
- **Conformance**: the corpus [staged-conformance](staged-conformance/) (image, video,
audio and splat sets; cases for every reason of §4.2 and every `WIR1` refusal code,
in the order the steps check them, and for §3's rules, holds and their bound,
batches, frozen units, the chain budget, a base decoded again, receipt evidence and
live deadlines, one clock across bases included; `WAI2` cases for each refinement
rule of SPEC §7.1, for exploding entry by entry and for what a packer refuses; the
live schedule), written and verified by `wai_staged_vectors` and verified
independently by `staged_verify.py`, which shares no code with `wai-rs`; the pure-
Python BLAKE3 moves to `claim-conformance/_blake3.py`, shared by both Python
verifiers. Cross-architecture goldens pin every stage of an image, a video and an
audio set; Kani proves, over bounded windows, the arithmetic step, the up2 bounds,
`rdiv` and the rate indices. `rdiv` and the rate indices are computed in checked
64-bit arithmetic.
### The integer codecs' payloads pinned in place: `WIV1`, `WIH1`, `WIA1`, `WIS1`
- **Pinned in place** (SPEC §5, *Payloads of the WAI-native integer codecs*, and the

View file

@ -27,6 +27,13 @@ Every registered string has one kind.
- **companion** — a companion-only capability (SPEC §5, §7.1): its payload is
applied with a base rendition and never on its own, so it is only ever a `WAI2`
companion.
- **refinement** — a refinement-only capability (SPEC §5, *Refinement
capabilities*): its payload is applied to the output of the stage below it,
bound to that output's producer by content hash, and never decoded on its own.
It is a `WAI1` `capability` with `refines`, or a `WAI2` component with
`role: "refinement"` ([staged-delivery](extensions/staged-delivery.md)). The
bases each one applies over are SPEC §5's *Base admission* table, which also
holds the bases of the enhancement layer `wai.video.lcevc`.
- **derivation** — an operation of ISO/IEC 23001-16 (`wai.derive.*`,
[derived-tracks](extensions/derived-tracks.md)). It acts on samples another
capability decoded and names no payload format.
@ -36,7 +43,8 @@ Every registered string has one kind.
A derivation or record string is not a payload capability, so it is not
dispatchable (SPEC §4): dispatch never takes an envelope's capability that names
one, and step 5 may still take a usable fallback.
one, and step 5 may still take a usable fallback. A refinement is not dispatchable
either; staged-delivery §4 processes it.
Two further tables hold strings that look like capabilities and are not:
@ -64,7 +72,8 @@ Two further tables hold strings that look like capabilities and are not:
Every dispatch and selection function uses one predicate,
`codecs::is_dispatchable(cap)`, SPEC §4's *dispatchable*: false for a
companion-only capability, a candidate, a record and a derivation; true for a
companion-only capability, a refinement-only capability, a candidate, a record and
a derivation; true for a
registered payload capability that is not a candidate, and for a string this
revision does not register, which a later MINOR revision may register (SPEC §8)
and which a sink decodes only if it advertises it. A new dispatch or selection
@ -84,7 +93,7 @@ then carries that date).
## Licence classes
Every payload and companion capability carries a licence class:
Every payload, companion and refinement capability carries a licence class:
`royalty-free`, `patent-pool`, `proprietary` or `non-commercial`
(`codecs::capability_license`). It is a property of the capability, not a
per-file claim. The classification has no default: a capability registered
@ -100,8 +109,8 @@ gives it; a record carries none.
## How to register a string
1. Add the capability constant to `wai-rs/src/codecs/mod.rs` and, for a payload or
companion capability, list it in `known_capabilities()` and give it an arm in
1. Add the capability constant to `wai-rs/src/codecs/mod.rs` and, for a payload,
companion or refinement capability, list it in `known_capabilities()` and give it an arm in
`capability_tier`, `capability_license` and `capability_replicate_class` (each
function has no default, and the tests reject a registered capability without
one). A record goes in `RECORDS`, a derivation in `codecs::derivation`.
@ -133,6 +142,7 @@ and a role are fixed once registered.
| `wai.audio.flac` | payload | registered | audio | standalone | royalty-free | standard-defined | floor | §5 Mandatory floor |
| `wai.audio.iamf` | payload | registered | audio | standalone | royalty-free | standard-tolerance | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.audio.int_codec` | payload | registered | audio | standalone | royalty-free | neural-int-exact | — | §5 Interactive, temporal & computed content |
| `wai.audio.int_refine` | refinement | registered | audio | refinement | royalty-free | standard-defined | — | §5 Refinement capabilities (staged delivery) |
| `wai.audio.ivas` | payload | registered | audio | standalone | patent-pool | standard-tolerance | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.audio.mpegh` | payload | registered | audio | standalone | patent-pool | standard-unclassified | — | §5 Broadcast and streaming codecs |
| `wai.audio.opus` | payload | registered | audio | standalone | royalty-free | standard-tolerance | recommended | §5 Recommended modern set |
@ -156,6 +166,7 @@ and a role are fixed once registered.
| `wai.haptic.mihs` | payload | registered | haptic | standalone | patent-pool | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.haptic.signal` | payload | registered | haptic | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.image.avif` | payload | registered | image | standalone | royalty-free | standard-tolerance | recommended | §5 Recommended modern set |
| `wai.image.int_refine` | refinement | registered | image | refinement | royalty-free | standard-defined | — | §5 Refinement capabilities (staged delivery) |
| `wai.image.jp2` | payload | registered | image | standalone | royalty-free | standard-tolerance | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.image.jpeg` | payload | registered | image | standalone | royalty-free | standard-tolerance | recommended | §5 Recommended modern set |
| `wai.image.jpegai` | payload | registered | image | standalone | royalty-free | neural-entropy-exact | — | §5 Neural capabilities |
@ -194,6 +205,7 @@ and a role are fixed once registered.
| `wai.semantic.perco2` | payload | registered | image | standalone | non-commercial | behavioral | — | §5 Neural capabilities |
| `wai.splat.4d` | payload | registered | volumetric | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.splat.int_codec` | payload | registered | volumetric | standalone | royalty-free | neural-int-exact | — | §5 Interactive, temporal & computed content |
| `wai.splat.int_refine` | refinement | registered | volumetric | refinement | royalty-free | standard-defined | — | §5 Refinement capabilities (staged delivery) |
| `wai.splat.sog` | payload | candidate | volumetric | standalone | patent-pool | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.splat.spz` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Interactive, temporal & computed content |
| `wai.tensor.nnc` | payload | candidate | binary | standalone | patent-pool | standard-unclassified | — | §5 Prior artifacts, general tensors and derivation operations |
@ -211,6 +223,7 @@ and a role are fixed once registered.
| `wai.video.hevc` | payload | registered | video | standalone | patent-pool | standard-defined | — | §5 Broadcast and streaming codecs |
| `wai.video.int_hyper` | payload | registered | video | standalone | royalty-free | neural-int-exact | — | §5 Neural capabilities |
| `wai.video.int_motion` | payload | registered | video | standalone | royalty-free | standard-defined | — | §5 Neural capabilities |
| `wai.video.int_refine` | refinement | registered | video | refinement | royalty-free | standard-defined | — | §5 Refinement capabilities (staged delivery) |
| `wai.video.j2k` | payload | registered | video | standalone | royalty-free | standard-tolerance | — | §5 Immersive audio, cinema, volumetric, haptics, HDR |
| `wai.video.keys` | record | registered | — | — | — | — | — | §5 Neural capabilities |
| `wai.video.lcevc` | companion | registered | video | enhancement | patent-pool | standard-unclassified | — | §5 Broadcast and streaming codecs |

View file

@ -69,6 +69,16 @@ OPTIONAL; §5 says which are RECOMMENDED.
whitespace, preserving key insertion order. Readers MUST NOT depend
on key order for *semantics*; encoders SHOULD preserve order so files
round-trip byte-identically.
- Member names are unique within each object of a manifest, at any
depth: a manifest that names a member twice in one object is malformed,
and a reader rejects it as it rejects any manifest that does not parse.
Names compare after their escapes are read.
- An integer member of a manifest, or of any JSON this specification or
its extensions define, is a JSON number written as an integer: digits,
with a minus sign only before a non-zero value, and no fraction or
exponent. `-0`, `1.0` and `1e0` are not integers, whatever their value,
and a member that must be an integer and is written so has the wrong
type.
- The payload is opaque codec bytes whose interpretation is fully
determined by the manifest's `model_requirement.capability` and, for a
capability that decodes against a parameter set, by that set, which the
@ -90,6 +100,7 @@ All WAI multi-byte integers are little-endian unless stated otherwise.
"fallback": "<capability-string>" | null },
"conditioning": { "kind": "<codec-id>", "prior": { ... } },
"security": { "encryption": "<scheme>" | "none", "kid": <u64> },
"refines": { ... },
"target": { ... }
}
```
@ -143,6 +154,10 @@ All WAI multi-byte integers are little-endian unless stated otherwise.
payload is plaintext (the default). Otherwise the payload is encrypted
and MUST be recovered before dispatch; see §6. The capability, media,
and conditioning fields always describe the **plaintext** codec.
- `refines` — OPTIONAL. Carried exactly when `model_requirement.capability` is
refinement-only (§5, *Refinement capabilities*): what the payload refines, by
content hash ([staged-delivery](extensions/staged-delivery.md) §3). A manifest
that carries it has a `null` `fallback`.
- `target` — codec-specific reconstruction parameters (dimensions,
sample rate, duration, frame count). Informational; the payload is
self-describing per the codec's own format.
@ -390,8 +405,9 @@ pinned rendition per set in a `WAI2` envelope (§7.1).
A capability is **dispatchable** unless this revision registers it as something
a sink does not decode on its own: a candidate (§5, *Candidate capabilities*), a
companion-only capability (§5, *Companion-only capabilities*), a record or a
derivation (§5, *Kinds of registered string*). A sink MUST NOT take step 3 or
companion-only capability (§5, *Companion-only capabilities*), a refinement-only
capability (§5, *Refinement capabilities*), a record or a derivation (§5, *Kinds
of registered string*). A sink MUST NOT take step 3 or
step 5 with a capability that is not dispatchable, whatever it advertises. A
string this revision does not register is dispatchable: a later MINOR revision
may register it (§8), and a sink that has a codec for it says so by advertising
@ -401,6 +417,13 @@ payload is companion data, so step 5 is not taken either (§5).
A WAI **payload always corresponds to exactly one capability**. v1.0
does not support multi-codec multiplexed payloads.
A sink never takes step 3 or step 5 with a capability §5 registers as
**refinement-only**, and a `WAI1` whose `cap` is refinement-only takes neither:
its payload refines the output of a base, and
[staged-delivery](extensions/staged-delivery.md) §4 processes it. A sink that does
not implement that extension finds the capability unsupported, and the envelope is
inert.
If the manifest declares `security.encryption` other than `"none"`
(§6), the sink MUST recover the plaintext payload before step 3 and run
this algorithm on the plaintext; see §6.4.
@ -475,6 +498,9 @@ kind:
rendition names the codec its payload is decoded with;
- a **companion** capability: companion-only (*Companion-only capabilities*,
below), carried only as a `WAI2` companion;
- a **refinement** capability: refinement-only (*Refinement capabilities*,
below), applied to the output of the stage below it and never decoded on its
own;
- a **derivation** operation (`wai.derive.*`): an operation on samples another
capability decoded, which names no payload format;
- a **record**: a signed record a WAI tool emits and verifies (a receipt kind —
@ -482,8 +508,8 @@ kind:
delivery records `wai.video.manifest`, `wai.video.ssai`, `wai.video.keys`,
`wai.video.package` and `wai.video.channel`), which names no payload format.
Only payload and companion capabilities have a media class, a fidelity tier, a
replicate class and a role. A derivation or record string is not a payload
Only payload, companion and refinement capabilities have a media class, a
fidelity tier, a replicate class and a role. A derivation or record string is not a payload
capability and is not dispatchable (§4): step 3 does not take an envelope's
`capability` that names one, and step 5 may still take a usable fallback. A row of the tables below that
registers a record says what the record attests, not a payload format. Named
@ -801,6 +827,45 @@ capability `codecs::is_dispatchable` accepts (§4's dispatchable). Its `wai wrap
envelope packers (`wai_envelope_pack`, `wai_envelope_pack_multi`) and its browser
writers (`pack`, `packMulti`) refuse to write one.
### Refinement capabilities (staged delivery)
| capability | staged form | payload | registry class |
|---|---|---|---|
| `wai.image.int_refine` | residual | `WIR1` ([staged-delivery](extensions/staged-delivery.md) Appendix A.1), units RGB8 | StandardDefined |
| `wai.video.int_refine` | residual | `WIR1`, units RGB8 frames | StandardDefined |
| `wai.audio.int_refine` | residual | `WIR1`, units `i16` PCM | StandardDefined |
| `wai.splat.int_refine` | residual | `WIR1`, units attribute tensors | StandardDefined |
Each is **refinement-only** (§8): its payload is applied, in a declared order, to
the output of the stage below it, bound to that output's producer by content hash,
and never decoded on its own. It is carried only as a `WAI1` with `refines` (§3),
or as a `WAI2` component with `role: "refinement"` (§7.1). It is never a
`capability` or `fallback` that §4 dispatches, a selectable rendition or a
companion. Each is royalty-free and WAI-native, its payload format is pinned by
this registration, it reads no parameter set, and its tier is `Lossy`: its residual
is quantised. Its next stage is exact given the stage below, so its class is
StandardDefined and its output is as exact as the base it refines
([staged-delivery](extensions/staged-delivery.md) §5).
### Base admission
A capability applied to the output of a base — a refinement-only capability, or an
enhancement layer — applies only over the bases listed for it here. A later
revision MAY add a base, which widens the capability (§8).
| capability | admitted bases |
|---|---|
| `wai.image.int_refine` | `wai.neural.int_hyper`, `wai.neural.int_mlicpp`, `wai.neural.int_synth`, `wai.image.png` |
| `wai.video.int_refine` | `wai.video.int_motion`, `wai.video.int_hyper` |
| `wai.audio.int_refine` | `wai.audio.int_codec`, `wai.audio.flac` |
| `wai.splat.int_refine` | `wai.splat.int_codec` |
| `wai.video.lcevc` | `wai.video.avc`, `wai.video.hevc`, `wai.video.vvc`, `wai.video.evc`, `wai.video.evc.baseline`, `wai.video.vp9`, `wai.video.av1`, `wai.video.av1.lossless` (*Enhancement layers (LCEVC)*, below) |
A refinement is admitted over a base when its `refines.base` names an envelope that
a sink decoded through one of these capabilities. The reference implementation
holds this table once (`codecs::BASE_ADMISSION`), and every admission check reads
it.
### Broadcast and streaming codecs (registered, sink-supplied)
The elementary video and audio bitstreams that terrestrial and satellite
@ -1625,6 +1690,38 @@ by which capability happens to be installed.
`companion_of_id` is not a string (`null` is the same as absent) makes the
manifest malformed, as a mistyped pin member does (§3.1), and the reader rejects
the envelope.
- **Exploding a component.** The exploded envelope of entry *i* is the `WAI1`
envelope (§2) whose payload is entry *i*'s rendition bytes. Its manifest is the
entry's `envelope_manifest` when it carries one, written exactly as it is in the
`WAI2` manifest; otherwise it is
`{"wai":W,"media":M,"intent":I,"model_requirement":{"capability":C,"fallback":null},"conditioning":{"kind":K[,"prior":P]}[,"security":S][,"refines":R][,"target":T]}`,
with no other bytes, where `W`, `M`, `I`, `S` and `T` are the `WAI2` manifest's
`wai`, `media`, `intent`, `security` and `target`, and `C`, `K` and `P` the entry's
`capability`, `kind` and `prior`, each written exactly as it is in the `WAI2`
manifest; `R` is the entry's `refines` (*Refinement components*, below) with each
component id replaced by the content hash of that entry's exploded envelope, written
as [staged-delivery](extensions/staged-delivery.md) §3 orders its members (`base`,
`prev`, `layer`, `span`; a run's `producer`, then `count`) with no whitespace. A
bracketed part is present exactly when its member is present and not `null`. A
component and its exploded
envelope are the same object for every rule that names an object by content hash
([jwp-receipts](extensions/jwp-receipts.md) §2.1). An entry MAY carry
`envelope_manifest`, a JSON object: the exact manifest of the entry as a `WAI1`
envelope. Its `model_requirement.capability`, `conditioning.kind` and
`conditioning.prior` MUST equal the entry's, its `refines` MUST be the entry's
with each id replaced as above, or both absent, and, where the entry's capability is
refinement-only, its `model_requirement.fallback` MUST be `null`
(`component-manifest-mismatch`). A `WAI1` envelope packed into a `WAI2` with its
manifest copied verbatim into `envelope_manifest` explodes back to the same bytes,
and so keeps its content hash, when its manifest has no bytes before or after its
JSON value (whitespace around a member's value is not part of it, so an explode
cannot write it back) and nothing follows its payload; a packer refuses any other
envelope, and refuses an output that does not explode back to its sources (one
whose manifest, nested in the `WAI2` manifest, passes a reader's depth limit). Entry
*i*'s exploded envelope is defined by entry *i* and the entries its `refines` names,
so an entry that cannot be exploded leaves every entry that does not name it intact.
A tool that re-serialises a `WAI2` manifest may change these bytes, and with them
the content hashes of the exploded envelopes.
- Rendition table: `u16 n_renditions | n × (u32 offset, u32 length)`,
offsets relative to the start of the payloads block. The table's
i-th entry corresponds to `renditions[i]` in the manifest.
@ -1738,6 +1835,37 @@ does not recognise; a companion that breaks rule 3 binds to nothing, or, for an
enhancement layer, is handled as §5 states. The sink MAY still present the
rendition it picked.
### Refinement components
A component with `role: "refinement"` is a layer of a stage set
([staged-delivery](extensions/staged-delivery.md)). It carries `refines` (§3), whose
`base` and producers are the `id`s of entries in the same envelope (§7.1, *Component
identity*); its exploded envelope carries the same `refines` with those ids replaced
by the content hashes of the named entries' exploded envelopes (*Exploding a
component*, above), so it is the same object as the layer carried on its own.
- **Placement.** A refinement component MUST follow every selectable entry in
`renditions`.
- **Selection.** Selection never picks one (step 2: it is not selectable). A sink
picks a rendition as above, then offers to staged-delivery §4, in `renditions`
order, the exploded envelopes of the refinements whose `refines.base` is the picked
entry's `id`, up to the stage its deployer policy chooses. A refinement whose
payload does not match its `sha256` is not offered.
- **Conformance.** A refinement component conforms only if, in this order: its
capability is refinement-only (§5); it carries `id` and `sha256`; its `refines`
is well formed (staged-delivery §3, with ids in place of hashes); `refines.base`
names a selectable entry, which carries `id` and `sha256`; its capability admits
that entry's (§5, *Base admission*); every producer in `prev` names a selectable
entry or a refinement before it, each carrying `id` and `sha256`; and no selectable
entry follows it. No other component carries `refines`, and a refinement-only
capability is carried with no other role. The reference
`WaiMulti::check_component_roles` reports the first break.
A sink of an earlier revision does not advertise a refinement-only capability, so it
never picks a refinement by capability; and since refinements follow every selectable
entry, a sink that picks the first entry it can decode picks a base. If it picks one
by another policy, it finds the capability unsupported and the component inert.
### v1.0 compatibility
v1.0 envelopes (`WAI1`) remain valid and their format is unchanged, except that
@ -1828,6 +1956,13 @@ envelope that uses any string a later revision registers.
then, does not parse now; §3.1 lists it. Nothing in the envelope signals the
change: its `wai` value is the same, so a reader of this revision rejects the
whole envelope where an earlier reader ignored the member.
- This revision also defines the manifest's `refines` (§3) and a rendition entry's
`refines` and `envelope_manifest` (§7.1) as OPTIONAL members under the MINOR rule
above; envelopes that use them keep their `wai` value. The exception does not cover
them: an envelope whose `refines` is malformed still parses, and
[staged-delivery](extensions/staged-delivery.md) §4 reports it
(`refines-malformed`); one whose `envelope_manifest` does not match its entry still
parses, and §7.1 reports it (`component-manifest-mismatch`).
- New capabilities (§5) MAY be added in any MINOR revision. Existing
capabilities MUST NOT be redefined — once a capability string is
registered for a codec, its payload format is fixed forever; for a registration
@ -1864,6 +1999,18 @@ envelope that uses any string a later revision registers.
envelope stops conforming, and a reader of an earlier revision that reports
the new binding as not conforming does not apply that companion and can
still present its base.
- This revision adds a third role, **refinement-only**: a payload applied, in a
declared order, to the output of the stage below it, bound to that output's
producer by content hash ([staged-delivery](extensions/staged-delivery.md)), and
never decoded on its own. It differs from companion-only, which is unordered,
names its base by capability and travels only inside a `WAI2`: a refinement is
ordered, names its base by content and travels as its own object. Changing a
capability into or out of either role redefines it; admitting another base (§5,
*Base admission*) widens it. The manifest member `refines` (§3) is an OPTIONAL
member defined under the rule above for MINOR revisions: an envelope that does
not carry it keeps its bytes and its meaning. A reader of an earlier revision
does not advertise a refinement-only capability, so it finds such an envelope's
capability unsupported and the envelope inert.
- A registration of a capability that decodes against a parameter set also fixes
that set's shape (§5, §3.1). Changing one file to several narrows it and
requires a new MAJOR; several to one widens it, which a MINOR revision MAY do.
@ -1897,7 +2044,10 @@ envelope that uses any string a later revision registers.
a `WAI1` `capability` or `fallback` or as a selectable rendition, that bound
it to a base or a number of bases its registration does not admit, or that
bound another companion to it (no companion applies to a companion-only
capability). Such envelopes still parse.
capability); registering a refinement-only capability makes non-conforming an
envelope that carried it as a `WAI1` `capability` without `refines`, as a
`fallback`, or as a selectable rendition or a companion, and one that bound a
companion to it. Such envelopes still parse.
---

View file

@ -75,9 +75,16 @@ pub mod int_mlicpp;
#[path = "../../wai-rs/src/int_payload/wire.rs"]
pub mod int_payload_wire;
// The staged-delivery residual (`WIR1`, extensions/staged-delivery.md Appendix A): its
// parser, predictors and arithmetic step. Self-contained beside the rANS coder and the
// histogram table already included here; the encoder is not used by the goldens.
#[allow(dead_code)]
pub mod staged;
mod golden;
mod int_payload_golden;
mod int_video_golden;
mod neural_keyframe_golden;
mod jpegai_golden;
mod int_mlicpp_golden;
mod staged_golden;

View file

@ -0,0 +1,9 @@
//! The staged-delivery residual's sources, `#[path]`-included from wai-rs as siblings,
//! so `wir1.rs` finds `super::predict` and `super::wir1_arith` here as it does there.
#[path = "../../wai-rs/src/staged/predict.rs"]
pub mod predict;
#[path = "../../wai-rs/src/staged/wir1_arith.rs"]
pub mod wir1_arith;
#[path = "../../wai-rs/src/staged/wir1.rs"]
pub mod wir1;

View file

@ -0,0 +1,166 @@
//! Cross-architecture byte-equality for staged delivery
//! (`extensions/staged-delivery.md`): the `WIR1` residual layers of three sets of the
//! corpus (`staged-conformance/`), decoded with the parser, predictors and arithmetic
//! step a sink runs (`staged/{wir1,predict,wir1_arith}.rs`, `#[path]`-included).
//!
//! - video: a `wai.video.int_motion` GOP (`WIV1`, decoded here by `int_video.rs`), a
//! layer 1 per frame, then a layer 2 over the GOP;
//! - image: the pinned 16×16 integer image's stage 0, up2 to 31×31, then up2 to 61×61
//! (odd sizes, clamped neighbours);
//! - audio: a stereo stage 0 at 8 kHz, the rate predictor to 16 kHz, then to 48 kHz
//! (`rdiv`'s halves).
//!
//! Each stage's SHA-256 (the clip digest over its units, SPEC §7 *Digests*) is pinned
//! below, and the last stage's must also be the clip hash the case states.
#![cfg(test)]
use std::path::PathBuf;
use sha2::{Digest, Sha256};
use crate::int_payload_wire::parse_wiv1;
use crate::int_video::{decode_typed, VideoStream};
use crate::staged::wir1::{apply_unit, parse, Below, Next, UnitKind};
const VIDEO_STAGES: [&str; 3] = [
"877fda1b49177f47d55298f28a280560555d8cace1dc6e9e6d370f2ce834b471",
"63ec8c064fcb36c3ab6e73854da46eace11eabf1aa010c0990b36d911ee408a4",
"4423cde72c6a314df503f5698532daa9917673ab871867b0ab5aa07c6d933694",
];
const IMAGE_STAGES: [&str; 3] = [
"4a501b0ee2468e4db07eb5f20e3408330604a231a1cd375a794adc5309197463",
"4695991ba30ab7d1129726f2c2cf743e4d892013b173a21c80fd4d67165e0239",
"64dba25135e5965fd511247477f911b85aa5a9b2fae263b64e791b72c9c43397",
];
const AUDIO_STAGES: [&str; 3] = [
"aab0d06a5d8fc29f47bd107940bd88dfd7d588980bbb72df54d5b8e9a3222006",
"e36b0ab5ed1f874edf0670cffd961133e7d9602cbc610fc2edf766a0d620c877",
"0408de38e23d42bd6af8064e109c73ab90582eaad588c68fbcf8b25fe9cf4c29",
];
fn case_dir(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../staged-conformance/cases").join(name)
}
fn read(name: &str, file: &str) -> Vec<u8> {
let p = case_dir(name).join(file);
std::fs::read(&p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()))
}
/// A `WAI1` envelope's payload.
fn payload(env: &[u8]) -> Vec<u8> {
let ml = u32::from_le_bytes(env[4..8].try_into().unwrap()) as usize;
let at = 8 + ml;
let pl = u32::from_le_bytes(env[at..at + 4].try_into().unwrap()) as usize;
env[at + 4..at + 4 + pl].to_vec()
}
fn hex(b: &[u8]) -> String {
b.iter().map(|x| format!("{x:02x}")).collect()
}
#[derive(Clone)]
enum Buf {
U8(Vec<u8>),
I16(Vec<i16>),
}
impl Buf {
fn bytes(&self) -> Vec<u8> {
match self {
Buf::U8(v) => v.clone(),
Buf::I16(v) => v.iter().flat_map(|s| s.to_le_bytes()).collect(),
}
}
fn below(&self) -> Below<'_> {
match self {
Buf::U8(v) => Below::U8(v),
Buf::I16(v) => Below::I16(v),
}
}
}
/// The clip digest of `units`: SHA-256 of their SHA-256 digests in order.
fn clip(units: &[Buf]) -> String {
let mut all = Vec::new();
for u in units {
all.extend_from_slice(&Sha256::digest(u.bytes()));
}
hex(&Sha256::digest(&all))
}
/// Apply `file` (a `WIR1` layer of `kind`) to `units[from..]`, unit by unit.
fn apply(name: &str, file: &str, kind: UnitKind, units: &mut [Buf], shapes: &mut [(u32, u32, u32)], from: usize) {
let p = payload(&read(name, file));
let w = parse(&p, kind).unwrap_or_else(|e| panic!("{file}: {e}"));
for i in 0..w.n_units as usize {
let next = apply_unit(&w, &p, i as u32, units[from + i].below(), shapes[from + i]).unwrap_or_else(|e| panic!("{file} unit {i}: {e}"));
units[from + i] = match next {
Next::U8(v) => Buf::U8(v),
Next::I16(v) => Buf::I16(v),
};
shapes[from + i] = (w.d0, w.d1, w.d2);
}
}
fn case_clip(name: &str, base: usize) -> String {
let c: serde_json::Value = serde_json::from_slice(&read(name, "case.json")).unwrap();
c["expect"]["bases"][base]["clip_sha256"].as_str().unwrap().to_string()
}
#[test]
fn staged_video_gop_is_byte_exact() {
let name = "video_int_motion_gop_perframe";
let base = payload(&read(name, "base_0.wai"));
let v = parse_wiv1(&base, Some(0)).expect("WIV1");
let s = VideoStream {
n_frames: v.n_frames as usize, h: v.h as usize, w: v.w as usize, block: v.block as usize,
q: v.q as i64, offset: v.offset, mv_precision: v.mv_precision, cdf: &v.cdf, mvs: &v.mvs, rans: v.rans,
};
let mut units: Vec<Buf> = decode_typed(&s).expect("decode").frames.into_iter().map(Buf::U8).collect();
let mut shapes = vec![(v.h, v.w, 3); units.len()];
let mut got = vec![clip(&units)];
for f in 0..4 {
apply(name, &format!("g0_L1_f{f}.wai"), UnitKind::Rgb8, &mut units, &mut shapes, f);
}
got.push(clip(&units));
apply(name, "g0_L2.wai", UnitKind::Rgb8, &mut units, &mut shapes, 0);
got.push(clip(&units));
println!("video stages {got:?}");
assert_eq!(got[2], case_clip(name, 0), "the final stage is the case's");
assert_eq!(got, VIDEO_STAGES, "a stage of the video set diverged");
}
#[test]
fn staged_image_up2_odd_is_byte_exact() {
let name = "image_up2_odd";
let mut units = vec![Buf::U8(read(name, "stage0.bin"))];
let mut shapes = vec![(16, 16, 3)];
let mut got = vec![clip(&units)];
apply(name, "L1.wai", UnitKind::Rgb8, &mut units, &mut shapes, 0);
got.push(clip(&units));
apply(name, "L2.wai", UnitKind::Rgb8, &mut units, &mut shapes, 0);
got.push(clip(&units));
println!("image stages {got:?}");
assert_eq!(shapes[0], (61, 61, 3));
assert_eq!(got[2], case_clip(name, 0), "the final stage is the case's");
assert_eq!(got, IMAGE_STAGES, "a stage of the image set diverged");
}
#[test]
fn staged_audio_rate_ladder_is_byte_exact() {
let name = "audio_flac_rate_ladder";
let s0 = read(name, "stage0.bin");
let mut units = vec![Buf::I16(s0.chunks_exact(2).map(|c| i16::from_le_bytes([c[0], c[1]])).collect())];
let mut shapes = vec![(400, 1, 2)];
let mut got = vec![clip(&units)];
apply(name, "L1.wai", UnitKind::Pcm, &mut units, &mut shapes, 0);
got.push(clip(&units));
apply(name, "L2.wai", UnitKind::Pcm, &mut units, &mut shapes, 0);
got.push(clip(&units));
println!("audio stages {got:?}");
assert_eq!(shapes[0], (2400, 1, 2));
assert_eq!(got[2], case_clip(name, 0), "the final stage is the case's");
assert_eq!(got, AUDIO_STAGES, "a stage of the audio set diverged");
}

View file

@ -0,0 +1,75 @@
"""BLAKE3 in hash mode, written from its specification in pure Python.
Shared by the claim-conformance verifier (`claim_verify.py`) and the staged-delivery
verifier (`../staged-conformance/staged_verify.py`), which import `blake3` from here. It
shares no code with wai-rs, which computes the same hashes with the `blake3` crate.
"""
_IV = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]
_PERM = [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8]
_CHUNK_START, _CHUNK_END, _PARENT, _ROOT = 1, 2, 4, 8
_M32 = 0xFFFFFFFF
def _rotr(x, n):
return ((x >> n) | (x << (32 - n))) & _M32
def _g(s, a, b, c, d, x, y):
s[a] = (s[a] + s[b] + x) & _M32
s[d] = _rotr(s[d] ^ s[a], 16)
s[c] = (s[c] + s[d]) & _M32
s[b] = _rotr(s[b] ^ s[c], 12)
s[a] = (s[a] + s[b] + y) & _M32
s[d] = _rotr(s[d] ^ s[a], 8)
s[c] = (s[c] + s[d]) & _M32
s[b] = _rotr(s[b] ^ s[c], 7)
def _compress(cv, m, counter, blen, flags):
s = list(cv) + _IV[:4] + [counter & _M32, (counter >> 32) & _M32, blen, flags]
m = list(m)
for r in range(7):
_g(s, 0, 4, 8, 12, m[0], m[1]); _g(s, 1, 5, 9, 13, m[2], m[3])
_g(s, 2, 6, 10, 14, m[4], m[5]); _g(s, 3, 7, 11, 15, m[6], m[7])
_g(s, 0, 5, 10, 15, m[8], m[9]); _g(s, 1, 6, 11, 12, m[10], m[11])
_g(s, 2, 7, 8, 13, m[12], m[13]); _g(s, 3, 4, 9, 14, m[14], m[15])
if r < 6:
m = [m[i] for i in _PERM]
return [s[i] ^ s[i + 8] for i in range(8)] + [s[i + 8] ^ cv[i] for i in range(8)]
def _words(block):
block = block + b"\0" * (64 - len(block))
return [int.from_bytes(block[i:i + 4], "little") for i in range(0, 64, 4)]
def _chunk_output(chunk, counter):
blocks = [chunk[i:i + 64] for i in range(0, len(chunk), 64)] or [b""]
cv = _IV
for j, b in enumerate(blocks[:-1]):
cv = _compress(cv, _words(b), counter, 64, _CHUNK_START if j == 0 else 0)[:8]
last = blocks[-1]
return (cv, _words(last), counter, len(last), _CHUNK_END | (_CHUNK_START if len(blocks) == 1 else 0))
def _cv(out):
cv, w, c, bl, f = out
return _compress(cv, w, c, bl, f)[:8]
def blake3(data: bytes) -> bytes:
chunks = [data[i:i + 1024] for i in range(0, len(data), 1024)] or [b""]
stack = []
for idx, ch in enumerate(chunks[:-1]):
cv = _cv(_chunk_output(ch, idx))
total = idx + 1
while total & 1 == 0:
cv = _cv((_IV, stack.pop() + cv, 0, 64, _PARENT))
total >>= 1
stack.append(cv)
out = _chunk_output(chunks[-1], len(chunks) - 1)
while stack:
out = (_IV, stack.pop() + _cv(out), 0, 64, _PARENT)
cv, w, _, bl, f = out
return b"".join(x.to_bytes(4, "little") for x in _compress(cv, w, 0, bl, f | _ROOT)[:8])

View file

@ -36,6 +36,7 @@ from decimal import localcontext
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(HERE, "..", "oer-conformance"))
import oer2_verify as OER # noqa: E402 (the OER reference verifier: grades + receipt checks)
sys.path.insert(0, HERE)
from cryptography.exceptions import InvalidSignature # noqa: E402
from cryptography.hazmat.primitives import serialization # noqa: E402
@ -43,74 +44,7 @@ from cryptography.hazmat.primitives.asymmetric import ed25519 # noqa: E402
# ---------------------------------------------------------------- BLAKE3 (hash mode)
_IV = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]
_PERM = [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8]
_CHUNK_START, _CHUNK_END, _PARENT, _ROOT = 1, 2, 4, 8
_M32 = 0xFFFFFFFF
def _rotr(x, n):
return ((x >> n) | (x << (32 - n))) & _M32
def _g(s, a, b, c, d, x, y):
s[a] = (s[a] + s[b] + x) & _M32
s[d] = _rotr(s[d] ^ s[a], 16)
s[c] = (s[c] + s[d]) & _M32
s[b] = _rotr(s[b] ^ s[c], 12)
s[a] = (s[a] + s[b] + y) & _M32
s[d] = _rotr(s[d] ^ s[a], 8)
s[c] = (s[c] + s[d]) & _M32
s[b] = _rotr(s[b] ^ s[c], 7)
def _compress(cv, m, counter, blen, flags):
s = list(cv) + _IV[:4] + [counter & _M32, (counter >> 32) & _M32, blen, flags]
m = list(m)
for r in range(7):
_g(s, 0, 4, 8, 12, m[0], m[1]); _g(s, 1, 5, 9, 13, m[2], m[3])
_g(s, 2, 6, 10, 14, m[4], m[5]); _g(s, 3, 7, 11, 15, m[6], m[7])
_g(s, 0, 5, 10, 15, m[8], m[9]); _g(s, 1, 6, 11, 12, m[10], m[11])
_g(s, 2, 7, 8, 13, m[12], m[13]); _g(s, 3, 4, 9, 14, m[14], m[15])
if r < 6:
m = [m[i] for i in _PERM]
return [s[i] ^ s[i + 8] for i in range(8)] + [s[i + 8] ^ cv[i] for i in range(8)]
def _words(block):
block = block + b"\0" * (64 - len(block))
return [int.from_bytes(block[i:i + 4], "little") for i in range(0, 64, 4)]
def _chunk_output(chunk, counter):
blocks = [chunk[i:i + 64] for i in range(0, len(chunk), 64)] or [b""]
cv = _IV
for j, b in enumerate(blocks[:-1]):
cv = _compress(cv, _words(b), counter, 64, _CHUNK_START if j == 0 else 0)[:8]
last = blocks[-1]
return (cv, _words(last), counter, len(last), _CHUNK_END | (_CHUNK_START if len(blocks) == 1 else 0))
def _cv(out):
cv, w, c, bl, f = out
return _compress(cv, w, c, bl, f)[:8]
def blake3(data: bytes) -> bytes:
chunks = [data[i:i + 1024] for i in range(0, len(data), 1024)] or [b""]
stack = []
for idx, ch in enumerate(chunks[:-1]):
cv = _cv(_chunk_output(ch, idx))
total = idx + 1
while total & 1 == 0:
cv = _cv((_IV, stack.pop() + cv, 0, 64, _PARENT))
total >>= 1
stack.append(cv)
out = _chunk_output(chunks[-1], len(chunks) - 1)
while stack:
out = (_IV, stack.pop() + _cv(out), 0, 64, _PARENT)
cv, w, _, bl, f = out
return b"".join(x.to_bytes(4, "little") for x in _compress(cv, w, 0, bl, f | _ROOT)[:8])
from _blake3 import blake3 # noqa: E402 (written from its specification; shared with staged_verify.py)
# ------------------------------------------------ Ed25519 (RFC 8032), §3.1 step 3's rule

View file

@ -329,6 +329,9 @@ thing.
binding over `wai.image.jpegai` as a binding over its exact decoder's pinned
reconstruction; that binding is checkable only by that decoder under the
conditions in §5–§6.
- **Staged delivery.** A unit refined in stages holds the weakest tier of its base
and every layer applied to it, and `entropy-consistency` does not pass through a
layer ([staged-delivery](staged-delivery.md) §5).
## 4. Framing

View file

@ -0,0 +1,553 @@
# WAI Extension: Staged Delivery
> Status: Draft. A base first, refinements after, each its own object, bound to what
> it refines by content hash. Every stage is presentable, every prefix of a stage set
> states its determinism tier, and a refinement that never arrives leaves the stages
> below it intact. Reference impl: `wai-rs` — `staged::{StageChain, StageSink}`,
> `staged::{wir1, predict, wir1_arith, tier, schedule}`, `container::Refines`,
> `codecs::BASE_ADMISSION`; the `wai stage` tool; the corpus
> [`staged-conformance/`](../staged-conformance/). Keywords **MUST**, **MUST NOT**,
> **SHOULD**, **MAY** are RFC 2119/8174.
## 1. Scope and model
A **stage set** is a **base** and **layers**. The base is any envelope a sink decodes
under SPEC §4 or §7.1. A layer is its own `WAI1` envelope whose capability is
**refinement-only** (SPEC §5, *Refinement capabilities*) and which names, by content
hash, the base and the envelopes it refines.
A sink holds, for every **unit** of the base's output, a **stage** (0 after the base
decodes) and a **producer**: the content hash of the envelope that produced the
unit's current output, the base at stage 0. Layers apply per unit, and every stage is
presentable. A base never names its layers, so a layer MAY be produced after its
base, by the base's publisher or by a party the sink accepts (§10).
## 2. Terms
- **Content hash**: [jwp-receipts](jwp-receipts.md) §2.1,
`BLAKE3("moq-jwp:object\x01" ‖ envelope_bytes)` over the envelope bytes exactly as
received, written as 64 lowercase hexadecimal digits.
- **Unit**: the smallest presentable piece of a base's output, fixed by the base's
capability: one frame of video; the whole picture of an image; the whole clip of
audio; the whole attribute tensor of a splat cloud.
- **Span**: a contiguous run of a base's units.
- **Producer**: for a unit, the content hash of the envelope that produced its current
output.
- **Refinement-only capability**: a capability registered with that role (SPEC §5,
§8).
## 3. The `refines` member
A `WAI1` manifest whose `model_requirement.capability` is refinement-only **MUST**
carry `refines`, and its `model_requirement.fallback` **MUST** be `null`. A manifest
whose capability is not refinement-only **MUST NOT** carry it.
```json
"refines": { "base": "<64 hex>",
"prev": "<64 hex>" | [ {"producer": "<64 hex>", "count": 4}, ... ],
"layer": 2,
"span": { "from": 0, "count": 4 } }
```
| member | presence | meaning |
|---|---|---|
| `base` | REQUIRED | Content hash of the stage set's base. |
| `prev` | REQUIRED | The producer each unit the layer covers is expected to have. A string means every such unit. An array of runs gives, in unit order, `count` consecutive units whose producer is `producer`. |
| `layer` | REQUIRED | Integer 1–255: the stage this layer brings each unit to. |
| `span` | OPTIONAL | `from` (integer ≥ 0) and `count` (integer ≥ 1): the units the layer covers. Absent, or `null` (which is the same as absent, as SPEC §3.1 reads an OPTIONAL member): every unit of the base. |
Rules:
- Hashes **MUST** be 64 lowercase hexadecimal digits (in a `WAI2` entry they are
component ids; SPEC §7.1, *Refinement components*).
- When `layer` is 1, every producer `prev` names **MUST** be `base`.
- A run array **MUST NOT** contain two adjacent runs with the same producer. A layer
whose units have one producer **MUST** write `prev` as a string, so an array of one
run is malformed.
- With a `span`, the run counts **MUST** sum to its `count`. The span **MUST** lie
within the base's units, and with no span the run counts **MUST** sum to the base's
unit count; a sink checks these once it holds the base (§4.1 step 2).
- `from + count` **MUST** fit in 32 bits, and so **MUST** each `count`.
Any other JSON type (an integer is written as SPEC §2 defines one), or a value outside
these rules, makes `refines` malformed (`refines-malformed`); the envelope still
parses. A member of `refines` this
revision does not define is ignored (SPEC §8).
## 4. Applying layers
### 4.1 Algorithm
A sink that implements this extension **MUST** process each received envelope *R*
whose capability is refinement-only as follows. Steps 1–6 decide for the whole
envelope; steps 7–10 decide for each unit *u* the layer covers. The first step that
fails is the reason for the envelope (1–6) or for the unit (7–10).
1. `refines` is present and well formed (§3) (`refines-malformed`). *R*'s capability
is refinement-only, and its `model_requirement.fallback` is `null`
(`capability-not-refinement`).
2. The sink has decoded a base whose content hash is `refines.base`. Otherwise it
**MAY** hold *R* until its bound (§4.3), and then discards it (`base-absent`).
With the base, `refines` is checked against the base's unit count (§3)
(`refines-malformed`).
3. The base was decoded through its manifest's `model_requirement.capability`, or
through the `WAI2` component whose exploded envelope (SPEC §7.1) has the content
hash `refines.base`, and not through a fallback (`base-via-fallback`).
4. The capability the base was decoded through is admitted by *R*'s capability (SPEC
§5, *Base admission*) (`base-not-admitted`).
5. Where the sink verified a delivery receipt for the base, it has verified one for
*R* as §10 requires (`refinement-unattested`).
6. The payload is well formed for *R*'s capability, in this order: it parses
(Appendix A) (`payload-malformed`); its unit count is the number of units the
layer covers (`payload-malformed`); its declared cost (Appendix A.5) is within the
limit the sink applies, if it applies one (`cost-over-limit`); retaining *R* keeps
the chain within its budget (§4.5) (`chain-over-limit`); and every unit's stream
decodes to its last symbol and ends canonically (`payload-malformed`). A payload
malformed for one unit is malformed for all. No unit's shape is read before step
9.
7. Let *P(u)* be the producer `prev` gives for *u*. *u* is **conflicted** when it is
frozen, or when an envelope with different content, the same `base` and the same
`layer`, whose producer for *u* is also *P(u)*, has passed step 8 for *u*, earlier
(before the base's chain was dropped included, §4.4) or in the same batch (§4.4)
(`layer-conflict`). A conflicted unit is **frozen**:
the sink **MUST** apply no further layer to it, except the replay of its own record
after its base's chain is dropped and the base decoded again (§4.4); it keeps the
output it had (a layer applied to it before the conflict stays applied), and the
sink **MUST** report the conflict.
8. *u* is **ready** when its stage is `layer − 1` and its producer is *P(u)*. A unit
whose stage is below `layer − 1` keeps *R* held for it, and is evaluated again when
its stage advances; at the bound *R* is discarded for that unit (`layer-gap`). Any
other unit is not ready (`prev-mismatch`).
9. *R*'s payload reads *u*'s current output in the shape its staged form needs
(`geometry-mismatch`).
10. Under a live schedule, *R* arrived at least `lead_ms` before *u*'s presentation
time (§8) (`deadline-missed`).
The sink then computes, for every unit that passed, the next stage by *R*'s staged
form (§6), and sets the unit's stage to `layer` and its producer to *R*'s content
hash. Application to one unit is atomic. A sink **MUST NOT** present a unit's output
from a layer that failed for that unit, and **MUST NOT** present a partly applied
unit.
### 4.2 Reasons
| step | reason | scope | effect |
|---|---|---|---|
| 1 | `refines-malformed`, `capability-not-refinement` | envelope | discarded |
| 2 | `base-absent` | envelope | held, then discarded |
| 2 | `refines-malformed` | envelope | discarded |
| 3 | `base-via-fallback` | envelope | discarded |
| 4 | `base-not-admitted` | envelope | discarded |
| 5 | `refinement-unattested` | envelope | discarded |
| 6 | `payload-malformed`, `cost-over-limit`, `chain-over-limit` | envelope | discarded |
| 7 | `layer-conflict` | unit | not applied; the unit is frozen |
| 8 | `prev-mismatch` | unit | not applied to the unit |
| 8 | `layer-gap` | unit | held for the unit, then not applied |
| 9 | `geometry-mismatch` | unit | not applied to the unit |
| 10 | `deadline-missed` | unit | not applied to the unit |
The list is closed. Two conforming sinks that receive the same envelopes in the same
order, at the same times, with the same receipts, hold bound, cost limit, chain budget
and schedule, report the same reasons per envelope and per unit and reach the same
stages and producers. The order of arrival changes the outcome only through the chain
budget at step 6 (§4.5), step 7, the hold bound at step 8 (§4.3: what is refused on
arrival and what expires) and step 10.
### 4.3 Holding
A sink **MUST** declare the bound to which it holds envelopes it cannot yet apply, as
a count of envelopes and a duration from arrival. An envelope held past the duration
is discarded with its hold reason (`base-absent`, or `layer-gap` for each unit it is
held for). An envelope that would exceed the count is discarded on arrival with the
reason it would have been held for. A unit refined by a held envelope that is
released within the bound, and that the chain budget admits, reaches the same output
as one refined in order.
An envelope held for its base and received again is held once. If it comes with
stronger evidence of its delivery receipt (§10: a receipt verified over its bytes is
stronger than one verified by inclusion alone, which is stronger than none), the sink
keeps the stronger evidence for steps 5 and 10; its hold still runs from its first
arrival.
### 4.4 Batches
When the base an envelope names is decoded, the envelopes held for it are released
together; when a unit's stage advances, the envelopes held for that unit are released
together. Each envelope released, or offered on arrival, passes steps 1–6, and for
each unit step 7 against the envelopes that passed step 8 earlier and step 8, alone.
The (envelope, unit) pairs that are ready then form one **batch**: step 7 compares
every pair of the batch with the others, and only then do steps 9 and 10 and
application run. So two conflicting layers released together are both refused and
the unit frozen, whichever arrived first; a layer that conflicts with one that passed
step 8 earlier is refused, and the unit frozen at the stage it has. When a unit is
frozen, every envelope held for it is refused for it (`layer-conflict`). Applying a
batch can release another, which is evaluated the same way.
A sink that decodes again a base whose chain it holds keeps the chain: re-decoding a
base does not reset its units' stages, producers or frozen state, and releases and
reports nothing. If the sink has verified the base's delivery receipt since, the base
is attested from then on (§10). Attestation belongs to the base's content hash: a base
once attested stays attested, held or dropped, and a decode that carries no receipt
does not undo it; a receipt the sink verifies before it decodes the base makes the base
attested when it is decoded. Only forgetting the base (§14) ends it. A sink **MAY** drop a base's chain when it no longer presents the
base. Every envelope held for the chain's units is then discarded (`base-absent`,
reported once for each), and an envelope for that base is held as for any base the
sink has not decoded. The sink keeps each unit's **record**: the producers of the
stages it reached, the envelope that passed step 8 at its last stage without being
applied, and whether it is frozen. A record is empty when the unit reached no stage,
nothing passed step 8 for it and it is not frozen; the sink keeps only the others, and
nothing of a base all of whose records are empty and that is not attested. When it
decodes the base again, each unit
starts at stage 0 with its record. Step 7 compares a layer with the recorded
producers, so a unit advances again only along them: a layer whose key a recorded
stage holds with other content conflicts, and the unit freezes. A frozen unit stays
frozen: it may replay its own recorded producers, in order, up to its recorded stage
and never past it, and every other layer is refused for it (`layer-conflict`). So it
presents its base's output or the output of one of its recorded producers, never any
other.
A sink **MUST** declare a **record budget**, in bytes, for what it keeps of the bases it
does not hold: their records, and the attestation of a base dropped while attested or
attested before it was decoded (§10). A kept base counts 32 bytes, and each record it
keeps 8 bytes, 32 for each recorded stage and 32 for an envelope that passed step 8
without being applied. When what it keeps passes the budget, the sink forgets whole
bases, the one whose record or attestation it wrote longest ago first, until it is
within it. A forgotten base is as one the sink never decoded and never attested
(§14).
These counts are the interoperable measure: every conforming sink counts the same
bytes, so two sinks with the same record budget keep and forget the same bases. What an
implementation allocates for each counted byte is its own, and it states that ratio
beside its record budget.
### 4.5 Chain budget
A sink **MUST** declare a budget, in bytes, for the chain of each base it decodes. The
chain's **state** is the sum of:
- for every unit, the bytes of its current output (1 per u8 element, 2 per i16
sample), and 32 bytes for each stage its record holds (the producers step 7
compares: its stages above 0, or, for a base decoded again, the stages it reached
before, §4.4);
- for every layer the chain **retains**, its payload's bytes and its declared working
bytes (Appendix A.5), and, for each unit it covers and has not been applied to, one
unit's output (its declared output over its units) and 32 bytes (the stage it would
add).
A chain retains a layer from the moment it passes step 6 to the end of the offer,
release or expiry after which no unit is held for it; the sink then drops it. At step
6, after the cost limit, a layer whose payload, declared output and working bytes and
32 bytes for each unit it covers, added to the state, pass the budget is refused
(`chain-over-limit`) before any stream is decoded. An envelope the chain still
retains, received again, adds nothing. Applying a layer to a unit replaces its output
with one, and adds a stage, that the layer's retention counted, and that unit's share
leaves the layer's: an application lowers the state by the unit's old output (and by
32 bytes more where it replays a recorded stage). The
state rises only when a layer is admitted, so it never passes the budget, and the
bytes a chain holds never pass the state.
## 5. The tier of a stage, and the stage hash
- **The base step**: `decode-equivalence` when the capability the base was decoded
through has the registry class `StandardDefined`, or `NeuralIntegerExact` with a pin
that resolved (SPEC §3.1) and declares `decode-equivalence`;
`entropy-consistency` when the class is `NeuralEntropyExact`; otherwise none.
- **A layer step**: the tier its registration gives (§6); `decode-equivalence` for the
residual form.
A unit's tier is the weakest step of its chain, composed as
[derived-tracks](derived-tracks.md) §3 rule 1. A layer acts on reconstructed output,
so `entropy-consistency` does not pass through it (derived-tracks §3 rule 2): a unit
over such a base holds no tier once a layer applies.
The **stage hash** of a unit is the SHA-256 of its output in the canonical buffer of
SPEC §7 *Digests*: RGB8 for a picture or a frame; the samples as signed 16-bit
little-endian integers, channels interleaved, for audio; the attribute tensor's bytes,
plane after plane, for a splat. The stage hash of several units is the SHA-256 of
their 32-byte stage hashes concatenated in unit order, as that section defines a clip
digest. A stage hash **MUST NOT** be published, compared as a conformance value, or
sealed in a receipt unless every unit it covers holds `decode-equivalence`.
## 6. Staged forms
A refinement-only capability's registration fixes its staged form, payload format,
admitted bases (SPEC §5, *Base admission*), tier and truncation points.
### 6.1 Residual (`WIR1`)
`wai.image.int_refine`, `wai.video.int_refine`, `wai.audio.int_refine` and
`wai.splat.int_refine` carry a `WIR1` payload (Appendix A): one rANS stream per
unit. For each element of a unit, the next stage is `clamp(pred + r · q)`. `pred` is
the payload's predictor applied to the unit's current output; `r` is the decoded
residual; `q` is the payload's step; and the clamp is to the element type's range.
Every operation is on integers of at most 64 bits.
| capability | unit | element | predictors |
|---|---|---|---|
| `wai.image.int_refine` | the picture, RGB8 | u8 | identity, up2 |
| `wai.video.int_refine` | one frame, RGB8 | u8 | identity, up2 |
| `wai.audio.int_refine` | the clip, `i16` PCM, channels interleaved | i16 | identity, rate |
| `wai.splat.int_refine` | the attribute tensor | u8 | identity |
A residual layer reads no parameter set: everything its decode reads is in its
payload and in the unit's current output. The base's parameter set was checked when
the base was decoded (SPEC §3.1, check 5 among them), and nothing a layer reads needs
the check again. Tier: `decode-equivalence`. Every layer boundary is a truncation
point.
### 6.2 Other staged forms
This revision registers the residual form only. A refinement-only capability of
another staged form (the continuation of a world's state, an enhancement layer
carried as its own object, a byte prefix of a progressive codestream, the further
codebooks of a residual-vector-quantised code) is registered by a revision that fixes
its form, payload, admitted bases, tier and truncation points. Where the form decodes
a prefix of a base codec's own codestream, that revision cites the clause of the
codec's standard that defines the decode of such a prefix, and its reference sink
decodes one.
### 6.3 Truncation points
A refinement capability declares truncation points only where its staged form defines
the decode of a prefix. For the residual form that is every layer boundary.
## 7. Deferral
A layer **MAY** be published after its base, served only on request, or never. A sink
**MUST** present the current stage of a unit without waiting for a layer it has not
been told to expect. A later revision of a refinement is a new chain from the same
`base`, distinguished by `prev` from layer 2 on. Every layer 1 names the base as its
producer, so `prev` cannot distinguish two revisions of layer 1: they are two
envelopes of the same `base`, `layer` and producer, and conflict (§4.1 step 7).
## 8. Live deadlines
Under a live schedule, every unit has a presentation time, given by the base's timing
and the target latency the sink applies, and every layer has a lead, `lead_ms`: the
time before a unit's presentation by which the layer must have arrived, and been
verified under §10, to be applied to it. A sink **MUST NOT** delay presenting a unit's
current stage to wait for any layer. A layer that arrived less than `lead_ms` before a
unit's presentation time is not applied to that unit (`deadline-missed`). It **MAY**
be applied to units of its span that are not yet due. A still image **MAY** be
refined after it is presented. A sink **MUST** count every unit presented below the
stage its expected layers would have reached on time. Verifying a layer's receipt
(§10) adds the time to receive and verify that receipt to the layer's arrival, which
sets the least `lead_ms` that can be met: over a base whose receipt the sink verified,
a layer counts as arrived when the sink verified its receipt (§4.3).
A stage set split across bases (a base for each group of frames) has one clock: a base
whose units are the set's units from position `k` on presents its unit `i` at the
set's position `k + i`, and a sink gives each base its first position.
## 9. Carriage
A layer is a `WAI1` envelope, carried and stored as any envelope is, or a `WAI2`
component with `role: "refinement"` (SPEC §7.1, *Refinement components*). A component
and its exploded envelope (SPEC §7.1) are the same object for every rule that names
an object by content hash, so a layer reaches the same stages whichever way it
travelled. This revision binds no other carriage.
## 10. Attestation of layers
Each layer is an object under [jwp-receipts](jwp-receipts.md). A sink that verified a
delivery receipt for a base **MUST NOT** apply a layer unless it has verified a
delivery receipt for the layer, through that extension's §3 step 6, over the layer's
envelope bytes as received. That receipt must be signed by the base's signer, or by a
key the sink holds with the authority `delivery` under the same origin
(jwp-receipts §7.5). A receipt verified without the layer's envelope bytes (§3 steps 1,
2, 3 and 5, step 4 not run) shows that a publisher signed an object with that content
hash; it never authorizes an application. A content hash in `refines` binds a layer
to a base, not to its publisher. A sink that verifies a base's delivery receipt after
it decoded the base applies step 5 to every envelope that arrives after it; envelopes
it admitted before keep the decision they had. The verification belongs to the base's
content hash and holds across the base's chain being dropped and the base decoded
again (§4.4).
## 11. Counting bytes
A figure of delivered bytes for a stage set:
- **MUST** count the bytes of the `WAI1` and `WAI2` envelopes as delivered (SPEC §2:
magic, length prefixes, manifest and payload);
- **MUST** state separately the receipt, index and transport framing bytes, and the
parameter-set bytes a sink fetched;
- **MUST NOT** count a text re-encoding of a payload (JSON, base64) in place of the
payload's registered binary format.
A figure over a payload in any other form is not a staged-delivery byte figure.
## 12. Conformance
A conforming sink of this extension implements §4, §5, §8 and §10, and every staged
form whose capabilities it advertises. The corpus
[`staged-conformance/`](../staged-conformance/) holds the cases: for each, a
conforming sink reports the stated reason per envelope and unit, and reaches the
stated stage, producer, tier and stage hash per unit. Its `README.md` states the
cases, what each base's stage 0 is checked against, and the independent verifier
`staged_verify.py`.
## 13. Earlier layered carriage
A prototype MoQ binding in this repository carries a layer index in an object
header (`mrl_layer`, with `mrl_total_layers` and a subscriber's `max_mrl_layer`). For
an object that is a `WAI1` envelope with `refines`, a sink reads the layer from
`refines.layer`, which sits inside the envelope and so inside its content hash, and
ignores the header.
## 14. Security considerations
- A layer is not authenticated by its `refines`; §10 authenticates it.
- Deferral lets anyone mint a chain for a public base hash. §10 and §4.1 step 7 bound
what a sink presents. A conflict between two attested chains is evidence that an
authorized signer signed both, and the sink reports it.
- A hold bound (§4.3), a cost limit (Appendix A.5) and a chain budget (§4.5) are
resource limits. A layer's header declares its output, its symbols and its working
bytes before any symbol is decoded, so a sink refuses a layer past its limit or its
budget without decoding it. A sink's own work for a layer is linear in the
layer's payload bytes and declared symbols, up to a factor logarithmic in its
units: it parses the payload once, at step 6; decides each unit the layer covers
once for each offer or release of the layer; finds a unit's producer in `prev` by
bisection over its runs; and compares a unit's key at step 7 with the producers of
that unit's stages. Beyond the chain's state, it keeps a fixed amount per unit of
the base and per unit held.
- An encrypted layer ([confidentiality](confidentiality.md)) binds to the content hash
of its base's envelope as delivered, ciphertext included, and is decrypted before
§4.1 step 6.
- A sink keeps the record of a base whose chain it dropped (§4.4), so a base decoded
again cannot be refined along other producers than it had; the record counts in the
chain's state when the base is decoded again (§4.5), and, while the base is not
held, in the sink's record budget (§4.4). A sink that forgets a base, by
`StageSink::forget_base` in the reference or because its record budget is full,
treats it as never decoded and never attested: a layer that conflicted with the
forgotten history can apply, and step 5 no longer requires a receipt for it. A sink
sizes its record budget for the bases it may decode again.
- Where the base is attested (§10), a frozen unit presents only its base's output or
the output of one of the producers it recorded, replayed in order (§4.4): a party
that can sign conflicting layers can stop a unit's refinement, and cannot make it
present anything else. Over a base whose receipt the sink did not verify, anyone who learns the
base's hash can mint a layer, and the first one ready for a unit applies to it.
## Appendix A. `WIR1`
### A.1 Layout
Every multi-byte field is little-endian; offsets are in bytes.
| off | size | field | rule |
|---|---|---|---|
| 0 | 4 | magic `WIR1` | |
| 4 | 1 | version | `1` |
| 5 | 1 | `elem` | `1` = u8, `2` = i16 |
| 6 | 1 | `predictor` | `0` identity, `1` up2, `2` rate |
| 7 | 1 | `table_mode` | `0` one table for every unit, `1` one per unit |
| 8 | 4 | `n_units` | ≥ 1 |
| 12 | 4 | `d0` | ≥ 1: rows (picture), samples per channel (audio), planes (splat) |
| 16 | 4 | `d1` | ≥ 1: columns, `1`, the planes' width |
| 20 | 4 | `d2` | ≥ 1: channels (`3` for RGB8), channels, the planes' height |
| 24 | 4 | `rate_num` | predictor 2: the output rate, ≥ 1; otherwise `0` |
| 28 | 4 | `rate_den` | predictor 2: the rate of the stage below, ≥ 1; otherwise `0` |
| 32 | 4 | `q` | 1..=65535 |
| 36 | 4 | `offset` | `i32`: the symbol offset of every table |
| 40 | 2 | `cdf_len` | 3..=4097 |
| 42 | 2 | reserved | `0` |
| 44 | T·`cdf_len`·4 | the tables | T = 1 or `n_units`; each a table of [integer-payloads](integer-payloads.md) §2 |
| … | `n_units`·4 | stream lengths | `u32` each, a multiple of 4, ≥ 8 |
| … | Σ | the streams | one per unit, in unit order; nothing follows |
Each stream is decoded as [integer-payloads](integer-payloads.md) §2 decodes a rANS
stream (precision 16, the bypass escape of 4-bit groups), against the unit's table at
`offset`.
### A.2 The unit kind
A capability fixes what its units hold (§6.1), and so the fields a payload may carry:
- RGB8 (`wai.image.int_refine`, `wai.video.int_refine`): `elem` 1, `predictor` 0 or
1, `d2` = 3;
- PCM (`wai.audio.int_refine`): `elem` 2, `predictor` 0 or 2, `d1` = 1;
- attribute tensor (`wai.splat.int_refine`): `elem` 1, `predictor` 0.
### A.3 Order of the checks
A parser checks, in this order, and refuses with the first that fails:
1. the magic (`bad_magic`);
2. the version byte: present (`stream_length`), and 1 (`version`);
3. the 44-byte header: present (`stream_length`);
4. the reserved field (`reserved_nonzero`);
5. the header's fields, in the order `elem`, `predictor`, `table_mode`, `n_units`,
`d0`/`d1`/`d2`, the rate fields, `q`, `cdf_len`; then the unit kind's rules
(A.2) (`field_range`);
6. the caps, in this order (`too_large`): a unit's `d0·d1·d2 ≤ 2^26`;
`n_units ≤ 2^20`; `n_units·d0·d1·d2 ≤ 2^30`;
7. the tables, one at a time, each present (`stream_length`) then checked
(`cdf_malformed`); the stream lengths, present (`stream_length`), each a multiple
of 4 and at least 8 (`stream_length`); the streams, present (`stream_length`);
8. nothing after the last stream (`trailing`).
Every size is formed in 64-bit arithmetic with overflow checked, and a size past 64
bits is past the caps, so a 32-bit sink refuses exactly what a 64-bit one does. A
parser reads tables and lengths from the bytes the payload holds and allocates
nothing a payload's bytes do not justify.
### A.4 Decode
For each unit *u* the layer is applied to, with the unit's current output of shape
`(e0, e1, e2)`:
1. The shape must be the one the predictor reads (`geometry_mismatch`), before any
symbol is decoded: `(d0, d1, d2)` for identity; `(⌈d0/2⌉, ⌈d1/2⌉, d2)` for up2;
`(n′, 1, d2)` with `⌊n′·rate_num/rate_den⌋ = d0` for rate.
2. For element *i* in raster order (`i = (a·d1 + b)·d2 + c`), decode the residual `r`
from *u*'s stream. A stream that runs out during a symbol's decode is refused at
that symbol (`stream_exhausted`), and nothing after it is decoded. The element is
`clamp(pred(i) + r·q)`, to `[0, 255]` for u8 and `[−32768, 32767]` for i16. `r` lies
in `[−2^31, 2^31 − 1]` and `|r·q| < 2^47`, so every step fits `i64`.
3. After the unit's last element, the stream ends canonically
([integer-payloads](integer-payloads.md) §2) (`stream_noncanonical`).
**Predictors**, with `prev` the unit's current output:
- **identity**: `pred(i) = prev(i)`.
- **up2**: `prev` is `h′ × w′ × c` with `h′ = ⌈d0/2⌉`, `w′ = ⌈d1/2⌉` and `c = d2`,
so odd sizes are allowed. For output `(y, x, ch)`: `iy = y >> 1`, `fy = y & 1`,
`ix = x >> 1`, `fx = x & 1`, and `p(Y, X) = prev[min(Y, h′ − 1), min(X, w′ − 1), ch]`.
The prediction is `p(iy, ix)` when both are 0;
`(p(iy, ix) + p(iy, ix + 1) + 1) >> 1` when only `fx` is 1;
`(p(iy, ix) + p(iy + 1, ix) + 1) >> 1` when only `fy` is 1; and
`(p(iy, ix) + p(iy, ix + 1) + p(iy + 1, ix) + p(iy + 1, ix + 1) + 2) >> 2` when
both are. This is the half-pel arithmetic of [integer-payloads](integer-payloads.md)
§3.
- **rate**: `prev` holds `n′` samples of `c = d2` interleaved channels. For output
sample *i* and channel *ch*: `s = i·rate_den`, `lo = s div rate_num`,
`ρ = s mod rate_num`, `hi = min(lo + 1, n′ − 1)`, `a = prev[lo·c + ch]`,
`b = prev[hi·c + ch]`, and the prediction is `rdiv(a·rate_num + (b − a)·ρ, rate_num)`,
where `rdiv(n, d) = sign(n)·⌊(2|n| + d) / 2d⌋` rounds half away from zero. This is
`a + (b − a)·ρ/rate_num` rounded half away from zero, the linear interpolation at
source position `i·rate_den/rate_num`, in exact integer arithmetic.
### A.5 Declared cost
A payload's header declares, before any symbol is decoded: its output,
`n_units·d0·d1·d2` elements of 1 byte (u8) or 2 bytes (i16); its symbols,
`n_units·d0·d1·d2`, one entropy-decode step each; and the most bytes its decode holds
at once beyond the payload and the stages below, its parsed tables (`4·T·cdf_len`),
the index of its streams (`8·n_units`) and one unit's output while it is built. It
runs no network. A sink that applies a limit compares this cost with it after the
parse and before any stream is decoded (§4.1 step 6, `cost-over-limit`), and counts
it in the chain's state while it retains the layer (§4.5).
### A.6 Refusal codes
The list is closed, and its codes are those [integer-payloads](integer-payloads.md) §8
uses for the same faults: `bad_magic`, `version`, `reserved_nonzero`, `field_range`,
`too_large`, `cdf_malformed`, `stream_length`, `trailing`, `stream_exhausted`,
`stream_noncanonical` and `geometry_mismatch`. A parser reports the first that
applies, in the order of A.3. §4.1 runs A.4 in two parts: step 6 decodes every unit's
stream to its end (A.4 steps 2 and 3, which read no prediction), so
`stream_exhausted` and `stream_noncanonical` are the envelope's `payload-malformed`,
reported before any unit's shape is read; step 9 then checks each unit's shape (A.4
step 1), so `geometry_mismatch` is that unit's `geometry-mismatch`. A payload whose
`n_units` is not the number of units the layer covers is the envelope's
`payload-malformed` with the code `field_range`. Every other code is the envelope's
`payload-malformed`.

View file

@ -101,6 +101,20 @@
"edition": null,
"registered": "2026-06-27"
},
{
"capability": "wai.audio.int_refine",
"kind": "refinement",
"status": "registered",
"media": "audio",
"role": "refinement",
"tier": "lossy",
"licence": "royalty-free",
"replicate": "standard-defined",
"sets": [],
"spec_section": "§5 Refinement capabilities (staged delivery)",
"edition": null,
"registered": "2026-10-01"
},
{
"capability": "wai.audio.ivas",
"kind": "payload",
@ -427,6 +441,20 @@
"edition": null,
"registered": "2026-06-12"
},
{
"capability": "wai.image.int_refine",
"kind": "refinement",
"status": "registered",
"media": "image",
"role": "refinement",
"tier": "lossy",
"licence": "royalty-free",
"replicate": "standard-defined",
"sets": [],
"spec_section": "§5 Refinement capabilities (staged delivery)",
"edition": null,
"registered": "2026-10-01"
},
{
"capability": "wai.image.jp2",
"kind": "payload",
@ -965,6 +993,20 @@
"edition": null,
"registered": "2026-06-28"
},
{
"capability": "wai.splat.int_refine",
"kind": "refinement",
"status": "registered",
"media": "volumetric",
"role": "refinement",
"tier": "lossy",
"licence": "royalty-free",
"replicate": "standard-defined",
"sets": [],
"spec_section": "§5 Refinement capabilities (staged delivery)",
"edition": null,
"registered": "2026-10-01"
},
{
"capability": "wai.splat.sog",
"kind": "payload",
@ -1211,6 +1253,20 @@
"edition": null,
"registered": "2026-06-27"
},
{
"capability": "wai.video.int_refine",
"kind": "refinement",
"status": "registered",
"media": "video",
"role": "refinement",
"tier": "lossy",
"licence": "royalty-free",
"replicate": "standard-defined",
"sets": [],
"spec_section": "§5 Refinement capabilities (staged delivery)",
"edition": null,
"registered": "2026-10-01"
},
{
"capability": "wai.video.j2k",
"kind": "payload",

View file

@ -43,6 +43,7 @@
"enum": [
"payload",
"companion",
"refinement",
"derivation",
"record"
]
@ -72,6 +73,7 @@
"standalone",
"companion",
"enhancement",
"refinement",
null
]
},

2
wai/staged-conformance/.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Hashed files: a line-ending conversion on checkout would change every digest.
* -text

View file

@ -0,0 +1,93 @@
# staged-conformance — staged delivery
The corpus of [`extensions/staged-delivery.md`](../extensions/staged-delivery.md) §12:
stage sets of a base and refinement layers, and the steps a sink takes with them.
**Stage-equivalence.** For each case, a conforming sink that offers its layers, decodes
its bases and expires its holds in the order and at the times `case.json` states
reports, at every step, the reasons the case states per envelope and per unit, and
ends with every unit at the stated stage, producer, frozen flag, tier, shape and stage
hash (SHA-256 of the unit's canonical buffer, SPEC §7 *Digests*; stated only where the
unit holds `decode-equivalence`). The reasons are §4.2's; a `payload-malformed`
report names the `WIR1` code (Appendix A.6), and a `cost-over-limit` report the figure
past the limit (`output bytes`, `symbols` or `working bytes`). A step reports once per
envelope it decided: what was refused for the whole envelope, or per unit what was
applied, held and refused (a unit held and decided within the same step is reported by
its decision); `held_for_base` marks an envelope held for a base the sink has not
decoded. The order of a step's reports is not part of the outcome.
**Evidence.** Each offer states what the sink verified of the layer's delivery receipt
(§10), as a token: `delivered-verified`, a receipt verified through jwp-receipts §3
step 6 over the envelope's bytes as received; `inclusion-verified`, a receipt verified
without those bytes (§3 steps 1, 2, 3 and 5), which never authorizes an application;
`none`, no receipt verified. A base's `attested` states whether the sink verified a
receipt for it, so that step 5 requires `delivered-verified` of its layers.
- `cases/<name>/` — one case: `case.json`, each base's envelope (`base*.wai`) and its
stage-0 output (`stage0*.bin`: the units' canonical buffers concatenated, in unit
order), and the layers (`*.wai`). `case.json` states each base's capability it was
decoded through, whether through a fallback, whether the sink verified a delivery
receipt for it, whether its pin resolved, its tier, its units and the live clock
position of its first unit (`first_unit`, §8); the sink's hold bound, cost limit,
chain budget (§4.5), record budget (§4.4) and live schedule; the steps (offer, decode
a base, expire, drop a base's chain, attest a base); and what the sink reports and
holds.
- `wai2/` — `WAI2` envelopes with refinement components (SPEC §7.1) and
`index.json`, which states for each what `check_component_roles` reports, whether
each `envelope_manifest` matches its entry, the content hash of each component's
exploded envelope (`null` for an entry that cannot be exploded, the others exploded
all the same), and entry 0's refinements: a live-style chain packed with its
manifests verbatim, which explodes back to its sources (`*.src<i>.wai`) byte for
byte; an envelope written with ids and no `envelope_manifest`; a refinement whose
payload does not match its `sha256`; an `envelope_manifest` that does not match its
entry, and one that names a fallback; each refinement rule of SPEC §7.1 broken once.
Its `packs` list gives `WAI1` envelopes and whether a packer packs them: bytes before
or after a manifest's JSON value, bytes after a payload, and a manifest that inside a
`WAI2` entry passes the JSON depth limit are refused.
- `schedule.json` — arrival traces, and the unit-by-unit presentation and stage a
sink gives each (§8), with the count of units presented below the stage their
layers would have reached on time.
- `index.json` — the cases and their final clip hashes.
**The content is synthetic**: pictures, frames and PCM computed by integer functions in
the generator. The bases of the integer codecs are the committed vectors under
[`../wai-rs/tests/vectors/`](../wai-rs/tests/vectors/), decoded against their
parameter sets with their pins; the `wai.video.int_motion` bases are coded by a
keyframe-0 encoder in the generator (zero motion, one block per frame), and the PNG
and FLAC bases are written by small writers in the generator (stored deflate with
the five row filters; VERBATIM subframes).
**What checks each base's stage 0.**
| base | checked by |
|---|---|
| `wai.video.int_motion` (`WIV1`, keyframe 0) | `wai_staged_vectors verify` (the reference decode) and `staged_verify.py` (an independent decode) |
| `wai.image.png` | `staged_verify.py` (zlib and the row filters); a fixture to `wai_staged_vectors`, which builds without `codecs` |
| `wai.audio.flac` | `staged_verify.py` (VERBATIM subframes, both CRCs); a fixture to `wai_staged_vectors` |
| `wai.neural.int_hyper`, `wai.video.int_hyper` (keyframe 1), `wai.audio.int_codec`, `wai.splat.int_codec` | `wai_staged_vectors verify` (the reference decode, pinned). Each base's payload is a committed vector's bitstream under [`../wai-rs/tests/vectors/`](../wai-rs/tests/vectors/), and `staged_verify.py`, which has no decoder for these, checks `stage0.bin` against the decoded output that vector's `sha256.json` states (`int_hyper/tiny`, `int_video/video_nk` frame by frame, `int_audio/audio`, `int_splat/splat`); `int_kernels_vectors` checks those sidecars against the decoders. The cross-architecture goldens of [`../byte-exact-conformance/`](../byte-exact-conformance/) also hold the `int_hyper` image's stage 0 |
Every layer application, in every case, is checked by both.
**Verifiers.**
- `wai_staged_vectors verify .` (from `../wai-rs`, features
`staged,video_int,audio_int,splat_int`): regenerates every file and requires it
byte for byte, replays every case through `staged::StageSink`, decodes the bases it
can and checks their tiers, and replays the schedule. `wai_staged_vectors gen .`
writes the corpus.
- `staged_verify.py .`: pure Python with the standard library, sharing no code with
`wai-rs`. It reimplements, from the extension and SPEC: a strict reader of envelope
JSON (UTF-8 with no byte-order mark, no member named twice, no NaN or Infinity, no
number past the float range, no lone surrogate, the depth limit, `-0`, a fraction or
an exponent as no integer) with the members SPEC §3 and §7.1 require; the content
hash; `refines`; `WIR1` (its parse in order, its cost, its streams, the three
predictors and `rdiv`); the sink as §4 states it, each envelope through §4.1's
numbered steps in turn, batches as §4.4 forms them, holds and their bound, frozen
units, the chain budget, live deadlines on one saturating clock across bases, and
receipt evidence; tiers and stage hashes; the PNG and FLAC decodes; the schedule;
exploding a `WAI2` component (reading the manifest's members as the text they are)
with the refinement role rules; and what a packer refuses. It takes BLAKE3 from
[`../claim-conformance/_blake3.py`](../claim-conformance/_blake3.py) and the rANS
decoder and the `WIV1` keyframe-0 decode from
[`../int-payload-conformance/int_payload_verify.py`](../int-payload-conformance/int_payload_verify.py),
both written from their specifications.

View file

@ -0,0 +1,235 @@
{
"format": "wai-staged-case/1",
"name": "attested_across_drop",
"about": "an attested base's layer 1 applies with its receipt; the chain is dropped and the base decoded again by a decode that carries no receipt: it is still attested, so layer 1 with no receipt is refinement-unattested, and with its receipt it replays",
"bases": [
{
"file": "base_0.wai",
"object": "6fd89fffe05e4ef6defa6726fd1bcac8a578e85210a15cdae65b4654d5fe7e6b",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": true,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0_0.bin",
"stage0_sha256": "84a4afb831e2d2c98b261aaa08b1f7c1e49a7df9c3a1f7327bf87ec140cda4ae",
"decode": {
"kind": "int",
"set": {}
}
},
{
"file": "base_1.wai",
"object": "6fd89fffe05e4ef6defa6726fd1bcac8a578e85210a15cdae65b4654d5fe7e6b",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0_1.bin",
"stage0_sha256": "84a4afb831e2d2c98b261aaa08b1f7c1e49a7df9c3a1f7327bf87ec140cda4ae",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"bytes": 583
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "delivered-verified"
},
{
"op": "remove",
"index": 0,
"at_ms": 2
},
{
"op": "base",
"index": 1,
"at_ms": 3
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 4,
"evidence": "none"
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 5,
"evidence": "delivered-verified"
}
],
"expect": {
"reports": [
[],
[
{
"object": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
],
[],
[],
[
{
"object": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"envelope": "refinement-unattested",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
],
[
{
"object": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "20c254f70a8d4de095e3064f92bc01bd93cbd7fbb2a3266bcec7e9a8902b1bc2"
},
{
"stage": 1,
"producer": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "2724b6f993f4946ecfaa99aa18dffcb0ba2125592be2bb146a8b754fe74fefab"
}
],
"clip_sha256": "7990406f958ddaefc5e91f8e0cd9ca1d265cd3c81a681eec4bb7dbb9ba04c92e",
"n_units": 2
},
{
"units": [
{
"stage": 1,
"producer": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "20c254f70a8d4de095e3064f92bc01bd93cbd7fbb2a3266bcec7e9a8902b1bc2"
},
{
"stage": 1,
"producer": "0ccfe9af9e31cf9014699a20610168f81692920e29adebd6ea6d277da3e8ca3e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "2724b6f993f4946ecfaa99aa18dffcb0ba2125592be2bb146a8b754fe74fefab"
}
],
"clip_sha256": "7990406f958ddaefc5e91f8e0cd9ca1d265cd3c81a681eec4bb7dbb9ba04c92e",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1,255 @@
{
"format": "wai-staged-case/1",
"name": "attested_after_decode",
"about": "a base decoded before its receipt is verified: frame 0's layer with no receipt applies; the base decoded again with its receipt verified is attested from then on, so frame 1's layer with no receipt is refinement-unattested; decoding it again without the receipt leaves it attested; delivered-verified, the layer applies",
"bases": [
{
"file": "base_0.wai",
"object": "ca89ed081688f3f5370fc6d96e471d085b7606850f9d3e55c2a876f3bcbc6545",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0_0.bin",
"stage0_sha256": "f6a56010bb71a9e7848c764e499e81f834664224e35ec9c978f794ff0e3c8848",
"decode": {
"kind": "int",
"set": {}
}
},
{
"file": "base_1.wai",
"object": "ca89ed081688f3f5370fc6d96e471d085b7606850f9d3e55c2a876f3bcbc6545",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": true,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0_1.bin",
"stage0_sha256": "f6a56010bb71a9e7848c764e499e81f834664224e35ec9c978f794ff0e3c8848",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1_f0.wai",
"object": "25eac95b83d649a906696dae8e163fd4ac24570371602c10cbb3e2a8e1c54d2a",
"bytes": 535
},
{
"file": "L1_f1.wai",
"object": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"bytes": 527
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1_f0.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "base",
"index": 1,
"at_ms": 2
},
{
"op": "offer",
"file": "L1_f1.wai",
"at_ms": 3,
"evidence": "none"
},
{
"op": "base",
"index": 0,
"at_ms": 4
},
{
"op": "offer",
"file": "L1_f1.wai",
"at_ms": 5,
"evidence": "none"
},
{
"op": "offer",
"file": "L1_f1.wai",
"at_ms": 6,
"evidence": "delivered-verified"
}
],
"expect": {
"reports": [
[],
[
{
"object": "25eac95b83d649a906696dae8e163fd4ac24570371602c10cbb3e2a8e1c54d2a",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
}
],
[],
[
{
"object": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"envelope": "refinement-unattested",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
],
[],
[
{
"object": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"envelope": "refinement-unattested",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
],
[
{
"object": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "25eac95b83d649a906696dae8e163fd4ac24570371602c10cbb3e2a8e1c54d2a",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "c164503f2d738b8729252a24bf6e94300979aa7aa11427195f1221cfffd81e98"
},
{
"stage": 1,
"producer": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "f1029000aa1799224e89bc1b00021dad8cc869e9708b8b7bb94a7a63aea27d80"
}
],
"clip_sha256": "4008894e56d04cd74635889e6f4ac81b787bd0b35bf6d7681648457caa0ff177",
"n_units": 2
},
{
"units": [
{
"stage": 1,
"producer": "25eac95b83d649a906696dae8e163fd4ac24570371602c10cbb3e2a8e1c54d2a",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "c164503f2d738b8729252a24bf6e94300979aa7aa11427195f1221cfffd81e98"
},
{
"stage": 1,
"producer": "c0ab531af4d89041d976b16c74a5d7d2595f6d2972d91a065d4e4114699e3a02",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "f1029000aa1799224e89bc1b00021dad8cc869e9708b8b7bb94a7a63aea27d80"
}
],
"clip_sha256": "4008894e56d04cd74635889e6f4ac81b787bd0b35bf6d7681648457caa0ff177",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
(0@0@P8@P@PhPXhPhx`xˆxx<78>8HPHPhH`hXhp`xˆpxˆx€˜x<CB9C> H``P`p¨Ðøpxˆx<CB86><78>x<EFBFBD> ˆ˜¨˜¨°Xp€¸Øÿ¸àÿÈèÿˆ ¨<C2A0>¨¨˜¨À¨ÀÐÀàÿÀðÿÈøÿØÿÿèÿÿ¨¸È°ÈØÈÐØ<C390><C398>¨Øÿÿàÿÿèÿÿ¸ÀÐÀØàÈÐèÐàø˜°° °ÈøÿÿÀÀØÐààØàðØðøèÿÿ¨ÀȸÈàÈÐèÐØèàèÿèðÿðÿÿÿÿÿ(0@0@P8@P@PhPXhPhxhxˆxx<78>8HPHPhH`hXhp`x€pxˆx€˜x<CB9C> H``P`p`p€px€xˆ<78>x<EFBFBD> ˆ˜¨˜ °`p€px‡p€—€ˆŸÈÿÿ<C3BF>¨¨˜¨À¨ÀÐx€<78>x<EFBFBD>—€˜§Øÿÿèÿÿðÿÿ°ÀØÈÐØˆ<C398> <EFBFBD>§¯ØÿÿèÿÿÿÿÿÿÿÿÿÿÿÐØø˜°° ¨È°·ÏÿÿÿÿÿÿÿÿÿØðøèÿÿ¨ÀÀ¸ÈàÈÐèÐØàÿÿÿèðÿðÿÿÿÿÿ

View file

@ -0,0 +1 @@
(0@0@P8@P@PhPXhPhx`xˆxx<78>8HPHPhH`hXhp`xˆpxˆx€˜x<CB9C> H``P`p¨Ðøpxˆx<CB86><78>x<EFBFBD> ˆ˜¨˜¨°Xp€¸Øÿ¸àÿÈèÿˆ ¨<C2A0>¨¨˜¨À¨ÀÐÀàÿÀðÿÈøÿØÿÿèÿÿ¨¸È°ÈØÈÐØ<C390><C398>¨Øÿÿàÿÿèÿÿ¸ÀÐÀØàÈÐèÐàø˜°° °ÈøÿÿÀÀØÐààØàðØðøèÿÿ¨ÀȸÈàÈÐèÐØèàèÿèðÿðÿÿÿÿÿ(0@0@P8@P@PhPXhPhxhxˆxx<78>8HPHPhH`hXhp`x€pxˆx€˜x<CB9C> H``P`p`p€px€xˆ<78>x<EFBFBD> ˆ˜¨˜ °`p€px‡p€—€ˆŸÈÿÿ<C3BF>¨¨˜¨À¨ÀÐx€<78>x<EFBFBD>—€˜§Øÿÿèÿÿðÿÿ°ÀØÈÐØˆ<C398> <EFBFBD>§¯ØÿÿèÿÿÿÿÿÿÿÿÿÿÿÐØø˜°° ¨È°·ÏÿÿÿÿÿÿÿÿÿØðøèÿÿ¨ÀÀ¸ÈàÈÐèÐØàÿÿÿèðÿðÿÿÿÿÿ

View file

@ -0,0 +1,145 @@
{
"format": "wai-staged-case/1",
"name": "attested_before_decode",
"about": "the sink verifies the base's receipt before it decodes the base: the decode, which carries no receipt, gives an attested base, so layer 1 with no receipt is refinement-unattested and applies with its receipt",
"bases": [
{
"file": "base.wai",
"object": "21aef5d23168e3198c5abbbfef160382965005bb9099263ac5983f703fad2231",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "fd636a41da98bfdf266929ba483a8170e05dfe22b58d1b7fb787d12385dd2581",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "bd3510c59be44e8a4870496cb5dcc9e534f55f9e04d576572dc3b408146daa81",
"bytes": 587
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "attest",
"index": 0,
"at_ms": 0
},
{
"op": "base",
"index": 0,
"at_ms": 1
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 3,
"evidence": "delivered-verified"
}
],
"expect": {
"reports": [
[],
[],
[
{
"object": "bd3510c59be44e8a4870496cb5dcc9e534f55f9e04d576572dc3b408146daa81",
"envelope": "refinement-unattested",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
],
[
{
"object": "bd3510c59be44e8a4870496cb5dcc9e534f55f9e04d576572dc3b408146daa81",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "bd3510c59be44e8a4870496cb5dcc9e534f55f9e04d576572dc3b408146daa81",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "3b00f93323ba39d7eb422b204f9484f1c8a8dd53212d98bb59ae328e4a58d37f"
},
{
"stage": 1,
"producer": "bd3510c59be44e8a4870496cb5dcc9e534f55f9e04d576572dc3b408146daa81",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "3203699f5689e8c009dac0a47a17a433ed898e8b9ad830515870861dca58c02c"
}
],
"clip_sha256": "893d5537bffddf6524f550c8e283f52ae9db467d9da05c3f7cb2527ab2e49e22",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
  0 0000H0HX@H`HXpX`p0000@(@X@P`HX`Hhp`hxh<78><68>(@P@PX댆<58>Php`px`p늩<70><EB8AA9>닠HPh샓黍흖졤<ED9D96>p<EFBFBD><70>닠닔쮫㉧㉯帝<E389AF>겯<EFBFBD>잭<EFBFBD>힉<EFBFBD>맖컲같㉧픭p맱<70>흖<EFBFBD><ED9D96><EFBFBD>젴릅걋걷龜휸x맆닠겝<EB8BA0><EAB29D>졇릅읽읜瑾及矜<E58F8A>젾젴린맛맛瑾흖契薛曜燮<E69B9C>  8 0800H0HXHH`H`pX`p0000H(HX@P`HX`Phphhxh<78><68>(@P@PXHP`Php`px`p늩<70><EB8AA9>닠PPhP`h`hp`p눡<70><EB88A1>닠닔쮫<EB8B94>``x`x뇀<78>뤐<EFBFBD>흩<EFBFBD><ED9DA9><EFBFBD>삹감걋pp릔닓흖<EB8B93><ED9D96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>걷<EFBFBD>x맆닠컧윿<ECBBA7><EC9CBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>훵癬燮삝컿㉧갭으읽<EC9CBC><EC9DBD><EFBFBD>契薛星萌<E6989F>

View file

@ -0,0 +1,124 @@
{
"format": "wai-staged-case/1",
"name": "audio_flac_rate_ladder",
"about": "a stereo FLAC base at 8 kHz (a stage-0 fixture here), a rate layer to 16 kHz, then one to 48 kHz",
"bases": [
{
"file": "base.wai",
"object": "1eb764beb4a8a739054341df8b5b7d065e490032b187a93787be15f1478080a8",
"decoded_via": "wai.audio.flac",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
400,
1,
2
],
"elem": "i16"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "bfd17b4865c3c7a982f18a397c05e5d1df483bbb98bd29e2e9e2a672afe3063f",
"decode": {
"kind": "flac"
}
}
],
"files": [
{
"file": "L1.wai",
"object": "53a48057cb99b88fd235b9165799122df2d1b55a4b84245112a5a5ea948458ab",
"bytes": 12711
},
{
"file": "L2.wai",
"object": "753e8ac465d347547c688690eb51615f19118c0a4c17490499fbb31aefd5cd0c",
"bytes": 18367
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L2.wai",
"at_ms": 2,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "53a48057cb99b88fd235b9165799122df2d1b55a4b84245112a5a5ea948458ab",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
}
],
[
{
"object": "753e8ac465d347547c688690eb51615f19118c0a4c17490499fbb31aefd5cd0c",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 2,
"producer": "753e8ac465d347547c688690eb51615f19118c0a4c17490499fbb31aefd5cd0c",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
2400,
1,
2
],
"stage_sha256": "6280c4edf77a03b58c588aaa10646b083227bb56cd49c7966ce75a134ff4f7c1"
}
],
"clip_sha256": "0408de38e23d42bd6af8064e109c73ab90582eaad588c68fbcf8b25fe9cf4c29",
"n_units": 1
}
]
}
}

Binary file not shown.

View file

@ -0,0 +1,103 @@
{
"format": "wai-staged-case/1",
"name": "audio_int_codec_1l",
"about": "a pinned wai.audio.int_codec base, then an identity layer",
"bases": [
{
"file": "base.wai",
"object": "d45db2bc98dd38873553beb15fdb026a4e6b7fd7c8c7dbe4f4a0b6fcc0709a54",
"decoded_via": "wai.audio.int_codec",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": true,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8192,
1,
1
],
"elem": "i16"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "b8ff83a442c112661ec7a41d6e51cb32559510a699a0e9bb37fa301f8952978a",
"decode": {
"kind": "int",
"set": {
"model.wam": "wai-rs/tests/vectors/int_audio/audio_model.bin"
}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "e462824f3bf3827ec4d8861e1c93f64fabf2bec20303013347eee7a271f968a2",
"bytes": 19375
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "e462824f3bf3827ec4d8861e1c93f64fabf2bec20303013347eee7a271f968a2",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "e462824f3bf3827ec4d8861e1c93f64fabf2bec20303013347eee7a271f968a2",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8192,
1,
1
],
"stage_sha256": "b9ca33fc990f6a28c479c4a8193dca0bd9faa1d8dedf9cef9614513da4b1d0bd"
}
],
"clip_sha256": "ec7a4ad312d40a6ebdb33a5b55df02967415c3eb8f065c72e427d1a189b8810d",
"n_units": 1
}
]
}
}

Binary file not shown.

View file

@ -0,0 +1,119 @@
{
"format": "wai-staged-case/1",
"name": "base_not_admitted",
"about": "a wai.image.int_refine layer over a wai.video.int_motion base: base-not-admitted",
"bases": [
{
"file": "base.wai",
"object": "c7d8d9fe61ff4c4d71f082b5134fc15a12932c1b5305ec1a6a47b8b1f08c4948",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "7cc3b7cdbd202cf8705313c7ed5edf6e93bf2893246e6b799f23b6a237ea592d",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "ccfd9b3c75deb27f1af1a96c7fe9b5f3ed2555e8d5a07d7350d886dd3f166ba7",
"bytes": 415
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "ccfd9b3c75deb27f1af1a96c7fe9b5f3ed2555e8d5a07d7350d886dd3f166ba7",
"envelope": "base-not-admitted",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 0,
"producer": "c7d8d9fe61ff4c4d71f082b5134fc15a12932c1b5305ec1a6a47b8b1f08c4948",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "935d3f83da4f483b6fd7c956e90f3af287f53c44e9c74dc18d29e1384787ddde"
},
{
"stage": 0,
"producer": "c7d8d9fe61ff4c4d71f082b5134fc15a12932c1b5305ec1a6a47b8b1f08c4948",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "243d926cc424dffc093682b48e3b60dd0b1b83b023b076660aa1b6e45c98f248"
}
],
"clip_sha256": "e532573c38be3eeb5dddc8c5ce7c0af82beb3a5bfd71556f4581acdd7a47508c",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
 88@08H0HX8H`H`hXhpXxˆ(8@08XHP`PPhP`x`xxpp<70>p<EFBFBD>˜@PP@`h<>Àè`pxhx€pˆ˜x<CB9C> <EFBFBD> ¨X`h Ðè¨Ðø¸èÿxˆ <CB86>˜¨<CB9C> ¸¨°¸¨Øø°àÿÈðÿÐøÿØøÿ¨¨À ¸À¸ÈÐp<C390> ÐðÿÐÿÿØÿÿ ÀÀ°ÈÐÈÈàÐÐ舘   °èÿÿ°ÀÈÀÈØÈØØÈàøØèÿ¨°À¨¸Ð°ÀØÈÐàØØèØàøàøÿèÿÿ 8 8@08H0PX8HhH`hXhp`xˆ08H08XHPhPPhP`x`xxpx<70>p<EFBFBD>˜HPX@`hH`p`pxpx€pˆ˜x<CB9C> <EFBFBD> ¨X`hXpp`p€pˆ—Àèÿ<C3A8>˜¨<CB9C>˜¸¨¨¸`x€h€—€<E28094>—ÐøÿØøÿèÿÿ °À¸ÈÐp<C390>˜ˆ<CB9C>§ÐÿÿØÿÿèÿÿðÿÿÿÿÿÐÐàˆ˜   °¨¯ÇøÿÿÿÿÿÿÿÿÈàøØèÿ¨°À¨°Ð°ÀÐÈÐàÿÿÿØàøàøÿèÿÿ

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,185 @@
{
"format": "wai-staged-case/1",
"name": "base_readded",
"about": "layer 1a applies and 1b conflicts, freezing the units; the base decoded again keeps them as they are and reports nothing; 1b offered again is still refused",
"bases": [
{
"file": "base.wai",
"object": "9e8b544b5ba77b86d9986da2b8e6964b7a708e4e2aa200404e58ba749330003a",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "5f4d2ea2a606d3f3de14d288069926538e01a018e6f10ac019089824c6657ecc",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1a.wai",
"object": "ad1cfba24ca80c3fd7a1f85c2273de0fa6ec172adf96409cc0056bff48ef9136",
"bytes": 595
},
{
"file": "L1b.wai",
"object": "d0d98b05f3e4b5f81e27b9d8a022cb8b51bc817264bb0f71dbdc7b4da3e449bd",
"bytes": 587
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1a.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L1b.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "base",
"index": 0,
"at_ms": 3
},
{
"op": "offer",
"file": "L1b.wai",
"at_ms": 4,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "ad1cfba24ca80c3fd7a1f85c2273de0fa6ec172adf96409cc0056bff48ef9136",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
],
[
{
"object": "d0d98b05f3e4b5f81e27b9d8a022cb8b51bc817264bb0f71dbdc7b4da3e449bd",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
}
],
[],
[
{
"object": "d0d98b05f3e4b5f81e27b9d8a022cb8b51bc817264bb0f71dbdc7b4da3e449bd",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "ad1cfba24ca80c3fd7a1f85c2273de0fa6ec172adf96409cc0056bff48ef9136",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "e42e01c170f901fc31b7699ba7583378d4589db98ff8e1483eceaf553615ea16"
},
{
"stage": 1,
"producer": "ad1cfba24ca80c3fd7a1f85c2273de0fa6ec172adf96409cc0056bff48ef9136",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "6d64fbd60316861023b12fdda81b530bde59aa5d234fbeb428c4433f425d6820"
}
],
"clip_sha256": "11513b7b7c495cc504f4d6deb308d15c95c08aaca41e85479f2359764f49046d",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
 0 0@(8H0@H@XXHXhPpphh€(@H8@P8HP@XhX`xXpˆppˆpˆ˜8@P@``˜ÀàXh€hpˆxˆ˜x˜ ˆ˜ P`p Ðð°ØøÀàÿx<C3BF> €˜ ˆ¨¨ °¸ Ðø°Øÿ¸ðÿÐøÿØÿÿ ¨À¨°È¨ÈÐx<C390>˜ÈøÿÐøÿèÿÿ ¸À¨¸Ð¸ÐÐÐÐàˆ<C3A0>¨˜¨°ðÿÿ°¸È¸ÈØÈÈàÐØðØàø °È¨¸Ð°ÀظÐàÈàèÐèðàðÿðÿÿ 0 0H(8H0@H@XXHXhPpphh€(@H8HP8HP@XhX`xXpˆppˆpˆ˜8@X@``P`hXh€hp€x€˜€<CB9C> ˆ˜ P`pXpxhx€x€<78>Àðÿ€˜ ˆ¨¨ °¸`p€hx<68>x<EFBFBD>ŸÐðÿØÿÿàÿÿ¨°È¨ÈЀ<C390>˜ˆ˜ŸÐðÿèÿÿèÿÿðÿÿÿÿÿÐÐàˆ<C3A0> ˜¨°¨¯·øÿÿÿÿÿÿÿÿÐØðØàø °À¨¸Ð°ÀظÐàÿÿÿÐèðàðÿðÿÿ

Binary file not shown.

View file

@ -0,0 +1,119 @@
{
"format": "wai-staged-case/1",
"name": "base_via_fallback",
"about": "the base was decoded through its manifest's fallback: base-via-fallback",
"bases": [
{
"file": "base.wai",
"object": "d08b631ce29e9aa8957c8d8f43a84203cd84b66773410c0caad30fa49709a445",
"decoded_via": "wai.video.int_motion",
"via_fallback": true,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "b9b63b558d4832e2d5fe0c412887bd8b3c1ac9d50d2209b1bf4481df46ba205b",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "b0967e3138741cacbcff4a924f2e6e7e078e4af0098dbcc2d2cb05e92478b55e",
"bytes": 583
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "b0967e3138741cacbcff4a924f2e6e7e078e4af0098dbcc2d2cb05e92478b55e",
"envelope": "base-via-fallback",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 0,
"producer": "d08b631ce29e9aa8957c8d8f43a84203cd84b66773410c0caad30fa49709a445",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "7ea10b5f41e2d150acd0416764d4de09eadef3858499eeccd71191e88d402cef"
},
{
"stage": 0,
"producer": "d08b631ce29e9aa8957c8d8f43a84203cd84b66773410c0caad30fa49709a445",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "96ed06bef055c67736dfcf5e06c3025333b0413044c66b26efdcb3b75138f013"
}
],
"clip_sha256": "ceebade3184f55da1c234a64e00d29d7177669551c8f0a3691177790545a0ac5",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
(8H(HH@HP@XhX`hXhxhx€hˆ<68>8HP@XhX`hXp€h€€h€˜€<CB9C>˜ˆ˜ P`hX`x°Èøhx<68>x€ ˆ˜ ˜ °˜¨¸Xpx¨ØÿÀèÿÐðÿ˜˜°˜¨° ¸È°¸Ð¸àÿÐèÿÐøÿØÿÿèÿÿ°ÈÈÀÐØÀØà<C398>˜°Øÿÿðÿÿøÿÿ°ÀØÈØàØØðààø˜¨À°ÀÀøÿÿ¸ÐØÐØèØèøàðÿèðÿ¸ÀØÀÈàÀÐèØàðàøøèÿÿðÿÿøÿÿ(@H(HP@HX@XhX`h`hxhx€hˆ<68>@HP@XhX`h`p€h€€h€˜€<CB9C>˜ˆ˜ P`hX`xhh€hx<68>x€ ˆ˜ ˜ °˜¨°`px`x<>xˆŸˆ<C5B8>ŸØøÿ˜¨° ¸È°¸Ðp€<70>ˆˆŸˆ˜§ØÿÿèÿÿøÿÿÀÈØÀØà<C398>˜¨<CB9C>Ÿ¯èÿÿøÿÿøÿÿÿÿÿÿÿÿààø˜¨À°ÀÀ°ÇÇÿÿÿÿÿÿÿÿÿØðÿèðÿ¸ÀØÀÈàÀÐèØàðÿÿÿèÿÿèÿÿøÿÿ

View file

@ -0,0 +1,208 @@
{
"format": "wai-staged-case/1",
"name": "batch_conflict_release",
"about": "layers 2a and 2b, both over layer 1, held; layer 1 applies and releases them together: they conflict in the batch, and the units freeze at stage 1",
"bases": [
{
"file": "base.wai",
"object": "3e70bf638ce90438ec0558ed23229b6915a3e58736a897a3f45ad916a83c46c7",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "61cae63ae78b67bfe98aed1387a7781120f5a16f1aa3605633810b30a1710977",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L2a.wai",
"object": "eb051506ca9764570729f78c96cd5498cc53880f2e26566e8c3e6d9c185dcf1a",
"bytes": 943
},
{
"file": "L2b.wai",
"object": "9c361336e24cbbf8d7e91489226f285d63697c24f25078018ecaf2fc99e57aa1",
"bytes": 935
},
{
"file": "L1.wai",
"object": "7a44a78e33ad52aaec6319d45d579e387339f9c0ffae0301f0cded809d4bcb51",
"bytes": 587
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L2a.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L2b.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 3,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "eb051506ca9764570729f78c96cd5498cc53880f2e26566e8c3e6d9c185dcf1a",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [
0,
1
],
"refused": []
}
],
[
{
"object": "9c361336e24cbbf8d7e91489226f285d63697c24f25078018ecaf2fc99e57aa1",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [
0,
1
],
"refused": []
}
],
[
{
"object": "7a44a78e33ad52aaec6319d45d579e387339f9c0ffae0301f0cded809d4bcb51",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
},
{
"object": "eb051506ca9764570729f78c96cd5498cc53880f2e26566e8c3e6d9c185dcf1a",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
},
{
"object": "9c361336e24cbbf8d7e91489226f285d63697c24f25078018ecaf2fc99e57aa1",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "7a44a78e33ad52aaec6319d45d579e387339f9c0ffae0301f0cded809d4bcb51",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "3b34aea57788ede6bffae46cfc385087b3d88e2ca4343b6f1263c55588a0d053"
},
{
"stage": 1,
"producer": "7a44a78e33ad52aaec6319d45d579e387339f9c0ffae0301f0cded809d4bcb51",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "d88b339d03e35a326944a921552088c8072c6094bba4b96dfdd064f97f254010"
}
],
"clip_sha256": "6620d5f7e2d50dc37635c3881cd29a06cf6de2444320e0159a203fc600cc8aae",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1,182 @@
{
"format": "wai-staged-case/1",
"name": "budget_partly_applied",
"about": "layer 2 is applied to unit 1 and held for unit 0, so it stays retained; unit 1's share has left its reserve, which leaves room for layer 1x over unit 0 at a budget with no byte to spare; 1x applies and releases layer 2 for unit 0",
"bases": [
{
"file": "base.wai",
"object": "7a1f3fd3c178fd939c8ac0c1951ad378bb08da6a85c762394b69766ad71ef3a7",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "19ac5dd5c595b4def507ec3aa0238718fc3d8972d44bb44cc5f9195e93abfd47",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "831449088f97460da5d77cab959903425e529f8a0670b80fcc47046b7da41753",
"bytes": 535
},
{
"file": "L2.wai",
"object": "a2681570d66d8e136ff0f3d30c0d72b901a2920b2721b288136c32e9826da15b",
"bytes": 782
},
{
"file": "L1x.wai",
"object": "ca2ea0790270916c7eb67d32d997a191aeb9df827bd4b1fa4e8ddd38708ba750",
"bytes": 535
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1940,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L2.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "offer",
"file": "L1x.wai",
"at_ms": 3,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "831449088f97460da5d77cab959903425e529f8a0670b80fcc47046b7da41753",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
1
],
"held": [],
"refused": []
}
],
[
{
"object": "a2681570d66d8e136ff0f3d30c0d72b901a2920b2721b288136c32e9826da15b",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
1
],
"held": [
0
],
"refused": []
}
],
[
{
"object": "ca2ea0790270916c7eb67d32d997a191aeb9df827bd4b1fa4e8ddd38708ba750",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
},
{
"object": "a2681570d66d8e136ff0f3d30c0d72b901a2920b2721b288136c32e9826da15b",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 2,
"producer": "a2681570d66d8e136ff0f3d30c0d72b901a2920b2721b288136c32e9826da15b",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "ab8af1bca23c023336e602a6d5b5418792976b8033d33c6c99b6c42a5e9c6894"
},
{
"stage": 2,
"producer": "a2681570d66d8e136ff0f3d30c0d72b901a2920b2721b288136c32e9826da15b",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "1dde3ca447b566cc50731df85b84992f5ced961630c051adb80b5efb593145dd"
}
],
"clip_sha256": "b74036d5d3befc48255321629b144b058dd516a33adb48bd65762b789ccad475",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
08(0H8@H@X`P``X`xhpxhp<68>(@H8@`H``P`x`pxp<78><70>x<EFBFBD><78>x<EFBFBD> PX`H`p ашpx<70>p<EFBFBD><70>x<EFBFBD> <EFBFBD>  <C2A0> АXpxАијРиџР№џ<E28496><D19F> <EFBFBD> Ј ЈИ АаАшџРшџајџијџрџџ АШИРШИаи<D0B0><D0B8>Јајџиџџ№џџАРШИШаШарии№<D0B8> ИЈЈШјџџИРаРШрар№ашџрјџАИРИРаШаиаршиш№шјџ№џџџџџ 08(0H8@H@X`P`hX`xhpxpp<70>(@H8H`H``P`x`pxp<78><70>x<EFBFBD><78>x<EFBFBD> PX`H`pXpppx<70>x<EFBFBD><78>x<EFBFBD> <EFBFBD>  <C2A0> АXpxhx<68>xx<78>x<EFBFBD><78>ајџ<D198> Ј  И АШh<D0A8><68>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD>ијџрџџшџџИРШИаи<D0B0><D0B8>Ј<EFBFBD><D088>Џиџџ№џџ№џџџџџџџџии№<D0B8> ИЈЈШАЏЧџџџџџџџџџашџр№џАИРИРаШаиаршџџџшјџ№џџџџџ

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,122 @@
{
"format": "wai-staged-case/1",
"name": "bypass_extremes",
"about": "a table of one symbol at q = 1: nearly every residual takes the bypass escape, and the layer is exact",
"bases": [
{
"file": "base.wai",
"object": "5036fc6abafd20625a7555e28aec85b8a77fef3bef00c6be826ba489dc0fafe2",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "ba2f7ebb664ac685de2ae18af060e7fe0b4c767ae439ffb1ae6c533911f3dd65",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "25db4602b79c63dfb01cecddfdbca9ade2153d016cf96d108cc03b557d21d9de",
"bytes": 1807
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "25db4602b79c63dfb01cecddfdbca9ade2153d016cf96d108cc03b557d21d9de",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "25db4602b79c63dfb01cecddfdbca9ade2153d016cf96d108cc03b557d21d9de",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "66dee210c5c713e8c48b19e2745183dc5d37c24263ab8a6b3f633c9187ebded4"
},
{
"stage": 1,
"producer": "25db4602b79c63dfb01cecddfdbca9ade2153d016cf96d108cc03b557d21d9de",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "fb93a43aaba925b831b3dc60d8b91a511cab52f491ad52147ca3bb54806a946c"
}
],
"clip_sha256": "cb6d3b466bf10bb01752c1379a6ca1f6bcd9961eb27d0cb57542a901b71fc5c7",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
  8(8@(8@8HXHPhHXp`h€(0@08@0HXHH`P`hX`p`xˆhˆ<68>08X@PX<50>ÀèXhphpxh€<68>pˆ˜€˜ HPh ¸è Èð°àÿp€˜ˆ<CB9C>˜ˆ °˜ ¸¨Ðð¨ÐÿÀèÿÀðÿÐÿÿ˜¨°¨°À ¸Ðpˆ˜ÈèÿÈøÿàÿÿ˜¨À¨°Ð°ÈÐÀÐØˆ<C398> ˜˜°àÿÿ ¸À¸ÈÐÈÈàÈØèÐèð<C3A8>°°¨¸À°ÀÐ°ÈØÀØàÐèèàèøððÿ  8(8@(8H8HXHPhHXp`h€(0@08@0PXHP`P`h`hp`xˆh€<68>0@XHPXH`pXpphpxh€ˆpˆ˜€<CB9C> HXhXXpXhxh€‡¸àÿ€<C3BF>˜ˆ ¨˜ ¸`px`p‡xˆ<78>ÀðÿÐÿÿàÿÿ¨°À ¸Ðpˆ˜€ˆŸÈøÿàÿÿàÿÿðÿÿøÿÿÀÐØˆ<C398> ˜˜¨˜¯¯èÿÿÿÿÿÿÿÿÈØèÐèð<C3A8>¨°¨¸À°ÀÐ°ÈØÿÿÿÐàèàèøèðÿ

View file

@ -0,0 +1,119 @@
{
"format": "wai-staged-case/1",
"name": "capability_not_refinement",
"about": "refines on a wai.video.int_motion envelope: capability-not-refinement",
"bases": [
{
"file": "base.wai",
"object": "9386292a9a98f4a3fd014d0a4ff0361cbe18545b446c72fa52448e48b60663d6",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "f57d55aad6d85d3da43bcf0541b48c941af2cbd5ae9bceada4eb496b523fae95",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "7c39597cdccea374758b5447b67cf0ba019eee80a6b0b6bea97c5e435d6dc7cd",
"bytes": 583
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "7c39597cdccea374758b5447b67cf0ba019eee80a6b0b6bea97c5e435d6dc7cd",
"envelope": "capability-not-refinement",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 0,
"producer": "9386292a9a98f4a3fd014d0a4ff0361cbe18545b446c72fa52448e48b60663d6",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "4ad325b6f0ad682e84747c4797333c49a45a004f08830c3ef8053f19424872e5"
},
{
"stage": 0,
"producer": "9386292a9a98f4a3fd014d0a4ff0361cbe18545b446c72fa52448e48b60663d6",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "7e751833166e7a151347ba4a2e08e68e84fbd3ad0d8edaedb3a45e8be2047ea3"
}
],
"clip_sha256": "39d743f21b782cc4ea1d1bacb50e0244af72459a21746ef19e6571a9a712c3ad",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
(((@(@@88X@P`@XhPhhhxx 8@0@H8P`PX`P`x`h€p€ˆ€ˆ˜0P`@X`˜¸ð`p€pp€x€˜x˜ ˆ˜ H`p˜Ðè¨Øø¸àÿx<C3BF> €˜ ˆ¨¨ °¸ Øÿ¸àÿ¸ðÿÐøÿØÿÿ˜¨À¨°È¨ÈÐpˆ<70>ÈøÿÐøÿèÿÿ ¸À¨ÈиÈàÈØè€ °˜¨°èÿÿ°¸È¸ÀØÈØèÐàèØèð˜°À ¸Ð°ÀØ¸ÐØÈÐðØàøàèÿèøÿ(((@(@@8@X@Ph@XhPhphxx(8@8@P8P`PX`P`xhh€p€ˆ€€˜8P`@X`PXx`p€pp€x€˜x<CB9C> ˆ˜ P`pXpp`x€p€‡Àðÿ€˜ ˆ¨¨ °¸Xx‡x€‡p<E280A1>ŸÐðÿØÿÿàÿÿ¨°È¨ÈÐxˆ<78>ˆ˜ŸÐðÿèÿÿàÿÿðÿÿÿÿÿÈØà€ °˜¨° ¯·øÿÿÿÿÿÿÿÿÐØèØèð˜°À ¸Ð°ÀØ¸ÐØÿÿÿØàøàèÿèøÿ

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,119 @@
{
"format": "wai-staged-case/1",
"name": "cdf_malformed",
"about": "a table entry set to 0 in mid-table: payload-malformed (cdf_malformed)",
"bases": [
{
"file": "base.wai",
"object": "92b42e2c7a7db02e114f5cc92abe65af343c1806f4a2000923eb5124e408d455",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "e7c50678b697bf23050f7b9ddc7256e5da1c9f2e4ce7c3e3f4db8407583057a7",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "82b9092649e9b1386370377ba5e3a432488d773df2294148edcedc94300519ca",
"bytes": 583
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "82b9092649e9b1386370377ba5e3a432488d773df2294148edcedc94300519ca",
"envelope": "payload-malformed",
"detail": "cdf_malformed",
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 0,
"producer": "92b42e2c7a7db02e114f5cc92abe65af343c1806f4a2000923eb5124e408d455",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "cd22012ce1f60626fe6cc008e8783a28d80a043023d6b45178536560aa3aa1f5"
},
{
"stage": 0,
"producer": "92b42e2c7a7db02e114f5cc92abe65af343c1806f4a2000923eb5124e408d455",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "b5d83ed2343c5f54ae126fa8eebf3e1c4e96791c85a31adab9722b24d2b468f9"
}
],
"clip_sha256": "a691f382b2ad20d285b30a25c07273f155b5c0e73245c1ae76a4b4a7e86810ff",
"n_units": 2
}
]
}
}

Binary file not shown.

View file

@ -0,0 +1,188 @@
{
"format": "wai-staged-case/1",
"name": "chain_budget_retained",
"about": "a budget that holds the base and either layer, not both: layer 2, held, is retained, so layer 1 is chain-over-limit; once layer 2 expires and is dropped, layer 1 applies",
"bases": [
{
"file": "base.wai",
"object": "b6c319bdbec933d6d3d5e45cc65cb68763a31654badf025d2766364924e83759",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "ce62db24b33cea47d4432a269313e134a0e53e9cd65921744b01c7e90d3122f4",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "46a97b83c801e78f6a767184639c725ae354655354b260d4eeeb35836b586eaa",
"bytes": 587
},
{
"file": "L2.wai",
"object": "d9cd97ff18e6c9e88f5e779d1065c1584f6ff622543a1c5d082522a38872eb05",
"bytes": 795
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1884,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L2.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "expire",
"at_ms": 1002
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1003,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "d9cd97ff18e6c9e88f5e779d1065c1584f6ff622543a1c5d082522a38872eb05",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [
0,
1
],
"refused": []
}
],
[
{
"object": "46a97b83c801e78f6a767184639c725ae354655354b260d4eeeb35836b586eaa",
"envelope": "chain-over-limit",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
],
[
{
"object": "d9cd97ff18e6c9e88f5e779d1065c1584f6ff622543a1c5d082522a38872eb05",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-gap"
],
[
1,
"layer-gap"
]
]
}
],
[
{
"object": "46a97b83c801e78f6a767184639c725ae354655354b260d4eeeb35836b586eaa",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "46a97b83c801e78f6a767184639c725ae354655354b260d4eeeb35836b586eaa",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "c36a9da5e9305e9139804f6e3a834dbf31ecc41ed525bd0c6d901829ad4d8610"
},
{
"stage": 1,
"producer": "46a97b83c801e78f6a767184639c725ae354655354b260d4eeeb35836b586eaa",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "c5eb4afa4e6f2440122ab4361f4c23bb377ca8a9eb8374d3b2c7377e7499670e"
}
],
"clip_sha256": "9b359fd5c3a4e4212911fdd0c0cbec31d00d46474656b49a655b4ef122bbded2",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
0@08P@PXHP`Php`pxhp<68>x€<78>0HXHP`HXpPhxhx€x€˜x<CB9C>˜ˆ˜ HXp`hp¨Øðpx<70>p€ ˆ˜ ˆ ° °¸`pˆ¸ØÿÀèÿÐðÿˆ ° ¨¸ °È¸¸ÐÀàÿÈøÿÐøÿàÿÿèÿÿ¸¸ÐÀÐØÀÐè<C390>˜¨Øøÿèÿÿèÿÿ°ÈØÈÐØÐàèØðÿ˜¨À¨ÀÀøÿÿ¸ØàÈÐðÐàðèèøðøÿ¸ÀØÀÈØÈØðÐèøàèÿàøÿðÿÿÿÿÿ 0@0@P@PXHP`Phphpxhp<68>x€<78>0HXHP`PXpPh€hx€x€<78>x<EFBFBD>˜ˆ˜ HXp`hx`xxxx<78>p€˜ˆ<CB9C> ˆ ° °¸hpˆpx‡xˆŸˆ<C5B8>ŸÐøÿ ¨¸ °È¸¸Ðx€<78>ˆ˜Ÿˆ˜ŸàÿÿèÿÿøÿÿÀÐØÀÐè<C390>˜¨<CB9C>˜¯èÿÿèÿÿøÿÿÿÿÿÿÿÿØèÿ˜¨À¨ÀÀ¸·Ïÿÿÿÿÿÿÿÿÿèèøðøÿ°ÀÐÀÈØÈØðÐèøÿÿÿàøÿðÿÿÿÿÿ

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,119 @@
{
"format": "wai-staged-case/1",
"name": "chain_over_limit",
"about": "a chain budget one byte short of the base's units and the layer's payload, declared output and working bytes and 32 bytes a unit: chain-over-limit, before any stream is decoded",
"bases": [
{
"file": "base.wai",
"object": "513f379e56b8d49a34f8ab0819a564cac71647e3d9bc3d98191259f2b6e0587e",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "11e4e6d347666fbc7dbb346643bb35a1994a00c1234290673a42182c6a8dbfd0",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "9a1fc1dd33e5f1a866212143d9948054af1190d8d7ace19e89a07cd5c7fdf875",
"bytes": 583
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1335,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "9a1fc1dd33e5f1a866212143d9948054af1190d8d7ace19e89a07cd5c7fdf875",
"envelope": "chain-over-limit",
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 0,
"producer": "513f379e56b8d49a34f8ab0819a564cac71647e3d9bc3d98191259f2b6e0587e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "80d915b8092dc1a6b54b24de51abdc0dacc9a345452fe1babc399caef1a3f92e"
},
{
"stage": 0,
"producer": "513f379e56b8d49a34f8ab0819a564cac71647e3d9bc3d98191259f2b6e0587e",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "277434f91cd2e9c0028c9505e316200a9bd71e551044cb548dcea9b1da31269c"
}
],
"clip_sha256": "b139902d21228247e2a7901db2077ca0e346c6f34c398b62be71d4516a1dcdf5",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
((@0@P8HX@PXPXhXh€hp€hx˜8PXHX`HXhPhxhp€pˆˆpˆ €˜ HPhP`p°Ððp€ˆxˆ˜€˜ <CB9C>˜¨˜¨°`px°ÐÿÀàÿÀøÿ<C3B8>˜¨<CB9C>¨°˜¸¸°ÈȸàÿÈèÿÐðÿØøÿèÿÿ¨¸ÐÀÈØ¸Øà€<C3A0>°Ðÿÿèÿÿøÿÿ°ÈиØàÈØðØàð ¨À °ÈðÿÿÀÈØÈÐàØèðØøÿèÿÿ¨¸ÐÀÈØÀÐèÈàðàðøðøÿðÿÿøÿÿ((@0@X8HX@P`XXhXh€hp€h€˜8PXHX`PXhXpxhp€p€ˆpˆ˜€˜ HXhX`xhpxp€ˆ€ˆ˜€˜ <CB9C>˜¨˜¨°`pxhp<68>x€—x˜ŸØøÿ<C3B8>¨°˜¸¸°ÀÈp€—€ˆ—ˆ<E28094>§Øøÿèÿÿðÿÿ¸ÀظØà€<C3A0>°ˆŸ·èÿÿøÿÿøÿÿÿÿÿÿÿÿØàè ¨À °È°ÇÏÿÿÿÿÿÿÿÿÿØøÿèÿÿ¨¸ÐÀÈØÀÐèÈØðÿÿÿðøÿèÿÿøÿÿ

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,122 @@
{
"format": "wai-staged-case/1",
"name": "clamp_extremes",
"about": "targets at 0 and 255 with q = 200: residuals that overshoot are clamped to the u8 range",
"bases": [
{
"file": "base.wai",
"object": "32635ea9c6905a9799bfef51a0338de30f28baf2ae61eeffe061d704cc383a19",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "0bb1e1d33eb2ef6bc52e678534c42731500d60f8cf8da7ef4932196d81ddc57b",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1.wai",
"object": "a5aa99dad81129f4693a0762034ee951f1ac78b1a47f9e381a51358a76ca38fd",
"bytes": 495
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1.wai",
"at_ms": 1,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "a5aa99dad81129f4693a0762034ee951f1ac78b1a47f9e381a51358a76ca38fd",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "a5aa99dad81129f4693a0762034ee951f1ac78b1a47f9e381a51358a76ca38fd",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "e204e6503da0e0d2eb9b6865dc386fa6fcfa1e10835e467455fa7a3b6fb4a0b5"
},
{
"stage": 1,
"producer": "a5aa99dad81129f4693a0762034ee951f1ac78b1a47f9e381a51358a76ca38fd",
"frozen": false,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "ab1c1db33c19af7eb1e8aa25582bb165c18bd2790ab70b80cfee99287cc7ff77"
}
],
"clip_sha256": "bf3594e190c527a1126118071829dde7d08b149b4f1cd5e060ce6c770005af13",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
(08((8 8P8PP@P`HXh``x(0808H08X8P`PX`Xhphh€h€ˆ0HH8PX<50>¸ØP`h`h€`€ˆx€˜ˆ<CB9C>¨HXh˜Èð¨Ðð¸Øÿx€˜€<CB9C> <EFBFBD>˜°˜¨¨ Èð°Ðÿ¸ØÿÀðÿÐøÿ<C3B8>˜¸ ¨À°¸Àxx<78>ÈèÿÈøÿØøÿ¨°¸°¸È°ÀÐÀÈàˆ˜˜<CB9C> ¨àÿÿ °¸°ÈȸÐÐÀØèÈè𘨸˜¸È¨¸ÐÀÀØÈÐØØàèàðøðøÿ(08((@(8P8PP@P`HXh``x(0808H0@X8P`PX`Xhphh€h€€0HH8XXHX`Phh`h€`€€x€˜ˆ<CB9C>¨HXpPhp`pxpx‡¸àÿ€<C3BF> <EFBFBD>˜°˜¨¨Xhxhp<68>px‡ÀðÿÐøÿØøÿ ¨¸°¸Àxx<78>€ˆ<E282AC>ÈøÿØøÿèÿÿøÿÿðÿÿÀÈàˆ˜˜ˆ ¨˜§¯èÿÿøÿÿÿÿÿÀØèÈè𘨸˜°È¨¸ÐÀÀØÿÿÿÐàèàèøèøÿ

View file

@ -0,0 +1,184 @@
{
"format": "wai-staged-case/1",
"name": "conflict_after_apply",
"about": "layer 1a applies; a different layer 1b conflicts and freezes the units at stage 1; a layer 2 over 1a is then refused",
"bases": [
{
"file": "base.wai",
"object": "1d319df65b75012b3d2cff45bdd6589e70dece53e0be4efb463c17e8c271f0ad",
"decoded_via": "wai.video.int_motion",
"via_fallback": false,
"attested": false,
"first_unit": 0,
"pin_resolved": false,
"tier": "decode-equivalence",
"units": [
{
"shape": [
8,
8,
3
],
"elem": "u8"
},
{
"shape": [
8,
8,
3
],
"elem": "u8"
}
],
"stage0": "stage0.bin",
"stage0_sha256": "5f44ba0bb608d0e5b3edbbe7ac5d6199a23dce06f59aa79bddc324f7a18da6bf",
"decode": {
"kind": "int",
"set": {}
}
}
],
"files": [
{
"file": "L1a.wai",
"object": "ebc3e691e4396cb0639b7b6d8f00a0c06922dfe14198e1466668373b101c3db5",
"bytes": 587
},
{
"file": "L1b.wai",
"object": "511d1ebed578caa52a9eb4edbc5306dd65baeb1767a4d9b1b1e318e1a8b686c3",
"bytes": 591
},
{
"file": "L2.wai",
"object": "3532844b0c4ba684437fc6901f2ab5366bf120d00132355cd31600a119b5a617",
"bytes": 799
}
],
"config": {
"bound": {
"max_envelopes": 16,
"max_age_ms": 1000
},
"cost_limit": null,
"budget": 1073741824,
"record_budget": 1048576,
"live": null
},
"steps": [
{
"op": "base",
"index": 0,
"at_ms": 0
},
{
"op": "offer",
"file": "L1a.wai",
"at_ms": 1,
"evidence": "none"
},
{
"op": "offer",
"file": "L1b.wai",
"at_ms": 2,
"evidence": "none"
},
{
"op": "offer",
"file": "L2.wai",
"at_ms": 3,
"evidence": "none"
}
],
"expect": {
"reports": [
[],
[
{
"object": "ebc3e691e4396cb0639b7b6d8f00a0c06922dfe14198e1466668373b101c3db5",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [
0,
1
],
"held": [],
"refused": []
}
],
[
{
"object": "511d1ebed578caa52a9eb4edbc5306dd65baeb1767a4d9b1b1e318e1a8b686c3",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
}
],
[
{
"object": "3532844b0c4ba684437fc6901f2ab5366bf120d00132355cd31600a119b5a617",
"envelope": null,
"detail": null,
"held_for_base": false,
"applied": [],
"held": [],
"refused": [
[
0,
"layer-conflict"
],
[
1,
"layer-conflict"
]
]
}
]
],
"bases": [
{
"units": [
{
"stage": 1,
"producer": "ebc3e691e4396cb0639b7b6d8f00a0c06922dfe14198e1466668373b101c3db5",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "64869721cf6c98101a5dc9384c743251506554cdccc52f95eb85f944cf79561f"
},
{
"stage": 1,
"producer": "ebc3e691e4396cb0639b7b6d8f00a0c06922dfe14198e1466668373b101c3db5",
"frozen": true,
"tier": "decode-equivalence",
"shape": [
8,
8,
3
],
"stage_sha256": "27322b811fd94a706da3f59122e54f2b202eacfd59f7f84e8f024158ad8bc950"
}
],
"clip_sha256": "4a856cfc54c1f88820a2319f3e995165e3ae3821541149342e2b65d148c48a2b",
"n_units": 2
}
]
}
}

View file

@ -0,0 +1 @@
((@(8P8PP8P`P`pXppXp<58>p<EFBFBD><70>8HP8H`HXpXhp`h<>px<70>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD>HXhXhh<68><68><EFBFBD>`x<>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`hx<68><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD>؈<EFBFBD><D888><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𘨰<EFBFBD><F098A8B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>((@(8P8PP8P`P`pXpp`p<>p<EFBFBD><70>8HP8H`HXpXhp`h<>px<70>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD>HXhXhhXh<58>`x<>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`hx`x<>px<70><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><70>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؈<EFBFBD><D888><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𘨰<EFBFBD><F098A8B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

Some files were not shown because too many files have changed in this diff Show more