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

111 lines
7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# live-conformance/compose — live composition
The corpus of [`extensions/live-compose.md`](../../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.