7 KiB
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) andentrants(each aprincipal, itsjoinorder, itsvideoas[width, height]ornull, whether it hasaudio, and itsattrsas[key, value]pairs) give theorder, thetilesand thevoicesof §5 and §6, or the refusalreason. A tile is itsprincipal, itsplace(grid,featuredorpip), itsz, itstilerectangle and itsdstandsrcrectangles (nullwhen its video is stopped), each[x, y, w, h]; a voice itsprincipal,gainandpan; - a mix case's
channels,framesandinputs(each itschannels,gain,panandpcm, signed 16-bit little-endian samples in hexadecimal) give the mixedpcm(§6), or the refusal; - a descriptor case's
bytesread (§3.3) to itsdigestandfields, or are refused; - a composition case's
room,descriptorandinstantsgive the descriptor'sdigestand a frame per instant (§9): itsparticipants(each itsprincipal, itsgrant, itsjoinorder, itsattrs, and itsvideoandaudiosources with their slot, media kind, profile, layers, composed layer, layering, dimensions andtracks), itsset_digest(§4.5), and itsorder,tilesandvoices; 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,descriptorandreceiptare accepted (§8.3) with the receipt'sdigestand theset_digestit names, or refused,atas 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 withnameandabout.rooms: by name, each adescriptorandgrants(hexadecimal),key_log_head(null: the room names no origin) andchains(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_0togrid_12; portrait, square and auto canvases;fill_fill,fill_cover,fill_contain,fill_defaultand 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 beforeeffective, an attribute that does not read, a lifecycle gap and a refused room; - receipts:
video,audioandpip_videoaccepted, 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.