open-standards/wai/live-conformance/compose/README.md
2026-10-17 09:42:53 -04:00

7 KiB
Raw Permalink Blame History

live-conformance/compose — live composition

The corpus of extensions/live-compose.md §11: the layout function and the mixer on their own, WCD1 composition descriptors, and rooms (a signed WRD1 descriptor, its WRG1 grants and its principals' WEV1 chains) composed at a list of instants, with WCR1 composition receipts checked against them.

Composition equivalence. A conforming implementation reaches, for every case, the outcome the case states, rectangle for rectangle and sample for sample:

  • a layout case's params (the descriptor's fields, §3.1) and entrants (each a principal, its join order, its video as [width, height] or null, whether it has audio, and its attrs as [key, value] pairs) give the order, the tiles and the voices of §5 and §6, or the refusal reason. A tile is its principal, its place (grid, featured or pip), its z, its tile rectangle and its dst and src rectangles (null when its video is stopped), each [x, y, w, h]; a voice its principal, gain and pan;
  • a mix case's channels, frames and inputs (each its channels, gain, pan and pcm, signed 16-bit little-endian samples in hexadecimal) give the mixed pcm (§6), or the refusal;
  • a descriptor case's bytes read (§3.3) to its digest and fields, or are refused;
  • a composition case's room, descriptor and instants give the descriptor's digest and a frame per instant (§9): its participants (each its principal, its grant, its join order, its attrs, and its video and audio sources with their slot, media kind, profile, layers, composed layer, layering, dimensions and tracks), its set_digest (§4.5), and its order, tiles and voices; or a refusal and where, at: ["room"], ["room", …] with the room verifier's own place (live-rooms §9.1), ["descriptor"] or ["set", t];
  • a receipt case's room, descriptor and receipt are accepted (§8.3) with the receipt's digest and the set_digest it names, or refused, at as above or ["receipt"].

A verifier that reaches another outcome, reason, place, rectangle, sample or digest does not conform.

Provenance. Generated here: wai_live_compose_vectors gen writes every case, room, descriptor, record and receipt from scenes authored in code, from fixed seeds. Each key is SHA-256 of a fixed label and the principal's index, each pure layout case's participant a SHA-256 of a fixed label and an index (a name, not a key), each block of PCM SHA-256 output under a fixed label (it stands for decoded audio and is no recording), each object digest of a receipt SHA-256 of a fixed label (it stands for an object and hashes none), every time is a constant (the room's t0 is 2026-10-17T00:00:00Z), and Ed25519 signing is deterministic (RFC 8032), so the file is the same bytes on every machine. The generator asserts that each case reaches the outcome it was written to have before it writes it. No recorded data.

Layout

One file, vectors.json:

  • principals: the room's keys, by name (informative).
  • layouts, mixes, descriptors: the cases above, each with name and about.
  • rooms: by name, each a descriptor and grants (hexadecimal), key_log_head (null: the room names no origin) and chains (lists of records in hexadecimal).
  • compositions, receipts: the cases above, each naming its room.

The studio room has a director (its role has the direct and compose powers), a performer (camera and music, featured, order 1, gain 5120), a guest (speech only at first, order 3, then exchanged at 5 s for a grant of order 0, gain 2048 and pan −2048, then video at 7 s), a screen-sharing device, an encoder live in the slot main under a staged profile of the room's own, a mixer (the compose power; it publishes the composed tracks), and a viewer. The director's video stops at 6 s and the performer leaves at 8 s. Its variants: studio_bad_order (the guest's order is third), studio_lifecycle_gap (the relay's record at 6 s not delivered), studio_viewer_gap (the viewer's first chat not delivered) and studio_refused (the viewer sends a control it may not).

Cases:

  • layouts: grid_0 to grid_12; portrait, square and auto canvases; fill_fill, fill_cover, fill_contain, fill_default and extreme aspects; the featured participant alone, of four, on a portrait canvas, kept past the tile limit, first of two, absent, and unread; order by attribute and ties broken by key; stopped video shown and omitted; the tile limit and the voice limit; picture in picture in each corner, static and dynamic, alone, with derived sizes, with stopped video, first of two, and over a featured tile; and attributes that do not read;
  • mixes: passing through, both widths into both, saturation, pans, gains, ties, silence and five refusals;
  • descriptors: the room's three and canvases at their limits, and each refusal a descriptor alone can have;
  • compositions: grid_session (every second from 1 s to 9 s), pip_session, participant_gap, signer_with_power, and a refusal for a signer without the power, one not in the room, another room, a bad signature, an instant before effective, an attribute that does not read, a lifecycle gap and a refused room;
  • receipts: video, audio and pip_video accepted, and one refused for each reason a receipt can have.

Running

cd ../../wai-rs
cargo run --no-default-features --features live_compose --bin wai_live_compose_vectors -- verify ../live-conformance/compose
cargo run --no-default-features --features live_compose --bin wai_live_compose_vectors -- gen    ../live-conformance/compose   # regenerate
cargo test --no-default-features --features live_compose --test live_compose
cd ../live-conformance
python3 live_compose_verify.py compose

wai_live_compose_vectors verify and tests/live_compose.rs require the file to regenerate byte for byte and wai-rs to give every case its outcome; the test also requires every reason of §10 to refuse a case, the cases above to be there, the grid session to change its order at the guest's exchange, and §10 to list exactly the reasons the reference reports. live_compose_verify.py is the second implementation, written from the extension's text and sharing no code with wai-rs: it verifies each room with live_rooms_verify.py and steps through its lifecycle replay to take the room at each instant, gives every case the same outcome, requires the same coverage of reasons, and then mutates copies of the corpus, one defect each (a tile moved, tiles swapped, the PiP window's z, a source or destination rectangle, the order, an entrant's attribute, a parameter, a stated reason, a voice, a mixed or input sample, a pan, a descriptor's byte or digest, a frame's tile, set digest, join order or tracks, an instant, a lifecycle record not delivered, a grant's byte, a receipt's byte or digest, and a stated outcome), each of which must fail. Pass = an exit status of 0 from each.