| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks are pending
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (push) Waiting to run
joule-code conformance gate / joule-moq-relay, every target (push) Has started running
joule-code conformance gate / joule-moq-ingest, every target (push) Has started running
wai release binaries build on Windows / the seven release binaries · windows (push) Waiting to run
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has started running
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 29s
joule-moq-room room service / joule-moq-room, every target (push) Has started running
wai-sink-android native sink library / does this change touch it (push) Successful in 32s
wai-sink-swift native sink package / does this change touch it (push) Successful in 34s
wai-quantum for JavaScript / does this change touch it (push) Successful in 34s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Waiting to run
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Waiting to run
wai-fleet service / does this change touch it (push) Successful in 34s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Has started running
joule-code conformance gate / Build + round-trip C1-C4 vectors (push) Has started running
wai-fleet service / service · macos (push) Waiting to run
wai-app and Create / wai-app · does this change touch it (push) Successful in 1m29s
wai-quantum studio and desktop / does this change touch it (push) Successful in 1m18s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 1m30s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 1m31s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Waiting to run
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Waiting to run
wai-audit collector and player integration / does this change touch it (push) Successful in 1m20s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Waiting to run
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Waiting to run
wai-audit collector and player integration / collector · linux (push) Waiting to run
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Waiting to run
wai-quantum studio and desktop / studio · browser (push) Waiting to run
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Has started running
wai-quantum studio and desktop / desktop app · macos (push) Waiting to run
wai-quantum studio and desktop / desktop app · linux (push) Waiting to run
WAI operation catalogue / does this change touch it (push) Successful in 1m22s
wai-quantum studio and desktop / desktop app · windows (push) Waiting to run
wai-ledger service / does this change touch it (push) Successful in 1m22s
wai-ledger service / service · linux (push) Waiting to run
wai-ledger service / service · macos (push) Waiting to run
WAI operation catalogue / the catalogue and every door · linux (push) Waiting to run
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 13s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Waiting to run
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Waiting to run
wai-quantum for JavaScript / javascript · linux (push) Has started running
wai-fleet service / service · linux (push) Has started running
WAI Studio / does this change touch it (push) Successful in 2m19s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Waiting to run
WAI Studio / Studio in Chromium and Firefox · macos (push) Waiting to run
WAI Studio / Studio in WebKit · linux (push) Waiting to run
The deviations from MSF that draft-charlot-moq-wai-packaging-01 listed, and two more the
extended check found, fixed in every writer:
- version: each writer wrote MSF's root version as the number 1; MSF §5.1.1 requires a
string, "draft-01" for draft-ietf-moq-msf-01, which wai-pack, joule-moq-ingest,
joule-moq-remote, joule-moq-interop and joule-moq-web now write. No reader compared it.
The readers of a room's catalogs (the room page, catalogVersionKnown; the gateway's WHEP
session, catalog::version_known) now refuse a version they do not know (MSF §5.1.1),
reading "draft-01" and the number 1, which the room deployed at
wai.transaction.science/room/ (live since 2026-10-19) writes until it is deployed again;
the interop subscriber requires "draft-01", which its own publisher writes.
- the packager's cmaf floor tracks: isLive false and initRef (the floor name), with the
floor's initialization segment inline in initDataList (CMSF §3.1, the field name of
draft-ietf-moq-cmsf-01), after tracks (MSF §5.1.7): moq/catalog.json is RFC 8785
canonical but for that member, written last (packaging §8.4). FloorView carries the
init segment's bytes; pack_verify.py writes the same catalog independently;
catalogs/expected.json names each case's floor by its sequence header OBU and
timescale, from which both write the init segment.
- event timelines: the room page and the remote host wrote "mimetype" for MSF's mimeType,
and no depends (MSF §8.2); they write mimeType and depends [] (the events track is the
only track of its namespace, and MSF §5.2.14 names dependencies in the declaring
track's namespace). live-events §8.1 says so.
- wai-link: the contribution gateway's link track carries WLK1 link records, signed,
chained and verified by live_contribution_verify.py: neither envelopes ("wai") nor JSON
events ("eventtimeline"), and read by a subscriber that verifies a room's tracks. A real
interop surface, so it is defined rather than mapped: live-contribution §5.4 defines
it, moq-streaming-format §3 names it, the registry lists it as a catalog wire
identifier (export regenerated), and the -01 draft defines it in a new §9 (IANA table,
required fields, correspondence). The gateway writes it as before.
The corpus is regenerated by `wai-pack conformance regen` (pack-conformance/ and the
composed package of wai-web/compose); each other writer's test holds a committed sample
(joule-moq-ingest/tests/catalogs/{whip,contribution}.json,
joule-moq-remote/tests/catalogs/host.json, joule-moq-interop/tests/catalogs/wai-receipts.json,
joule-moq-web/e2e/catalogs/room.json), written by its JOULE_MOQ_*_WRITE_CATALOGS=1 run. The
room page's catalog moves into web/room/catalog.js, tested by catalog.test.mjs with the
page's other unit tests.
wai/ietf/catalog_check.py reads every writer's catalogs and, under --strict, holds MSF's
and CMSF's own rules: the version string, a name and isLive on every track, an MSF field
in another case, an event timeline's eventType, mimeType and depends, eventType elsewhere,
a cmaf track's initRef naming an inline initDataList entry that follows tracks; wai-link
tracks are held to the draft's §9. The repository checks run it with --strict. 23
catalogs of 6 writers pass with no note; the self-test plants 43 faults (a numeric
version, a cmaf track without isLive, mimetype and an undefined packaging value among
them) and catches each.
The draft stays -01 (the wire meaning of "wai" is unchanged): Implementation Status says
the deviations are fixed. xml2rfc 3.35.0 renders it with no warning; idnits 2.17.1: 0
errors, 0 flaws, 1 warning (no first-submission date on the datatracker).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
||
| .. | ||
| floor | ||
| mutations | ||
| package | ||
| sources | ||
| staged | ||
| compose.js | ||
| index.html | ||
| key.hex | ||
| package-lock.json | ||
| package.json | ||
| page.js | ||
| policy.toml | ||
| README.md | ||
| run.mjs | ||
The composing sink
index.html opens a WAI package of several components, dispatches each to a decoder this
device can run, checks everything it is about to present against the package's signed
receipt, and plays the components on one timeline (browser-sink §14).
| file | what it is |
|---|---|
compose.js |
the runtime: openPackage() and the Composition it returns |
index.html, page.js |
the reference page: the picture, the dispatch record and the checks |
policy.toml, sources/, floor/, key.hex |
the package's policy and inputs |
package/ |
the package it plays, written by wai-pack (packaging §5.8) |
staged/ |
the staged packages: fields and pictures with layers the page computes (browser-sink §14.5, §14.7) |
mutations/forged.receipt.json |
the package's receipt signed by another key |
run.mjs |
the gate: the page in browser engines, every outcome held to what it expects |
The package
One programme of seven seconds as five components under one version-2 package receipt, each cut at the lead's piece starts, each piece one object:
| component | capability | source | presented as |
|---|---|---|---|
v |
wai.video.int_motion bases and a wai.video.av1 floor for every piece |
the fixture compose-01, a test pattern of 320 × 180 at 25 frames a second |
the picture, and the clock |
g |
wai.graphics.vector |
vector-conformance/vectors/motion/stroke-titles.wvg1, a title card and a credit roll at 1280 × 720 |
an overlay rasterised in WebAssembly |
t |
wai.text.timed |
sources/t.vtt, three captions |
text, in the page's text layer |
s |
wai.audio.score of two channels at 48 kHz, each note voiced, and a wai.audio.flac floor of each piece's mixdown |
sources/s.wscr, score-conformance/vectors/scale48.wscr's notes up and down |
samples synthesised in the tab in two channels (or, without the score, the floor decoded from FLAC in WebAssembly), on Web Audio |
f |
wai.feed.state |
sources/f.wwld, a scoreboard of signed ops |
the state at the clock's tick |
Each entry with a decoded output states its digest, which the page holds what it decodes to: each video base's clip digest, each overlay piece's clip digest, each caption segment's SHA-256, each score piece's sample digest; each feed piece is sealed by the package's key.
wai-pack's corpus check (wai-pack conformance check ../pack-conformance, which
tests/conformance.rs runs) writes the sources under sources/, packs the package from
them and requires every file the same, verifies it, and writes the forged receipt again
(wai_pack::multi_fixture::compose_check; conformance regen writes them). By hand:
# from wai/wai-pack
cargo run --release --bin wai-pack -- fixture gen compose-01 -o ../wai-web/compose/src.y4m
cargo run --release --bin wai-pack -- pack --policy ../wai-web/compose/policy.toml \
--out <dir> --key ../wai-web/compose/key.hex
cargo run --release --bin wai-pack -- verify <dir>
The staged packages
staged/ holds four packages of one image component each, sealed with key.hex from objects of
the corpora, byte for byte, by src/compose_stage.rs's tests, which compute every prefix digest
natively and hold it to the corpus's own statement:
| package | pieces |
|---|---|
fields |
the orb of volumetric-conformance/fields/ (a base carrying two of its four levels, then its levels 2 and 3 as layers 1 and 2), mlp and edge |
fields-digest |
fields, the orb's layer 2 stating stage 1's digest |
cond |
cond_side_planes, cond_dual_gbuffer and cond_render of staged-conformance/cond/: a PNG base, its wai.image.int_cond_refine layer and its side objects as asset entries |
cond-not-exact |
cond_side_not_exact's layer over a plane the page decodes only through its fallback |
The page renders each field at its pinned view and each picture's base in WebAssembly, presents
them, then takes each layer as it arrives: a field's next level, or a picture's conditioned
layer with the side planes it names (a splat set's frame rendered in the page at its pinned
pose), each stage held to its signed digest before it is presented; a refused layer leaves the
stage below. The tests check, and WAI_COMPOSE_STAGED_WRITE=1 writes them again:
# from wai/wai-web
cargo test --lib --features compose compose_stage::
The AV1 floor floor/v.obu is supplied (packaging §7.3), made the way
pack-conformance/supplied_floor.py makes a golden's: wai-pack plan cuts the fixture
(two pieces, of 100 and 75 frames), each piece is coded alone by aomenc with that script's
settings, and the streams are concatenated. The policy pins the floor directory's listing.
Run the page
# from wai/wai-web: the compose bundle
cargo build --release --target wasm32-unknown-unknown --lib --features compose
wasm-bindgen --target web --out-dir compose/pkg --out-name wai_compose \
target/wasm32-unknown-unknown/release/wai_web.wasm
# serve wai/, which holds the outline set the overlay names
cd .. && python3 -m http.server 8741
# → http://localhost:8741/wai-web/compose/index.html
Query parameters: without=<capability>,… forces a device profile without those
capabilities; receipt=<url> reads another receipt; pkg=<dir>/ another package.
The gate
cd compose && npm ci
node run.mjs --engines chromium,webkit --pkg pkg
In each engine: the package opens with every check holding and every component presented,
and plays to its end; each score piece's samples, synthesised in the tab in the two channels
and at the rate its target states, have the digest its index entry states; every overlay
frame hashed in the page equals vector-conformance/'s, and each piece's clip digest its
entry's; each caption segment and each feed piece holds; without
the AV1 decoder each integer video base decodes to its signed clip digest; without the integer
rung and the still every video piece plays its AV1 floor and the page says so; without the
score every score piece plays its FLAC floor, decoded in WebAssembly to the samples the
score's signed base states for its mixdown, and the page says so; in
pack-conformance/multi/multi-opus-01, without FLAC, the sound track's Opus floor plays through
the engine's AudioDecoder where it takes Opus, each piece trimmed to exactly its samples (an
engine whose decoder refuses that golden's 64 × 36 picture refuses it at the lead); the forged
receipt is refused receipt-signature and an object with one byte flipped in delivery
object-hash, with nothing presented. Over the staged packages: each field renders at its
pinned view to the frame digest volumetric-conformance/fields/ states, read back from the
canvas; the orb's levels, each held back in delivery and released one at a time, present each
stage, its stage hash the corpus's, before the next level is asked for; a stage that is not its
signed digest is refused prefix-digest and a level with a byte flipped object-hash, the stage
below staying presented; each picture of cond presents the stage hash its case states; a side
object withheld, or the splat decoder left out of the profile, refuses its layer side-absent, a
plane held only through its fallback side-not-exact, and a side object with a byte flipped is
refused object-hash and never held, each with the base presented. --only staged runs these
cases alone, --only package the others. It exits 0 only when every check passes in every
engine, and 1 on any failure, a page error, an engine it cannot launch, fewer checks than it
makes, or an error of its own.