# live-conformance/recordings — live recording The corpus of [`extensions/live-recording.md`](../../extensions/live-recording.md) §10: recordings, each a package (its files by path: the signed `WRM1` recording manifest, the room's `WRD1` descriptor, `WRG1` grants and key-log head, each principal's `WEV1` chain, and each take's `WTM1` manifest, chunks, `WUR1` receipts and `WCN1` consents, with the `LISTING` of them all) and an evaluation instant; and clips, each a room descriptor, a signed `WCL1` clip record and, for each of its parts, the device's key, the take's `take_commit` events up to the head and the chunks' bytes; with the outcome a verifier gives each. **Recording equivalence.** For each recording, a conforming recording verifier given its `files` (path to bytes, in hexadecimal) and its `evaluated_at` (seconds since 1970) reaches the outcome the vector states (§4.5): - `refuse`: the `reason` and where, `at`: `["listing"]`, `["manifest"]`, `["signer", t]` with the first instant `t` of the span at which the signer does not hold the record power (§4.3), `["component", i]` for the manifest's component `i`, `["room", …]` with the room verifier's own place (live-rooms §9.1), or `["take", i, …]` with the take verifier's own place in component `i` (capture-binding §9.1); - `verdicts`: the `package` digest (SHA-256 of `LISTING`), the recording `manifest`'s digest, the `room` id, `complete`, `publishable` for each of `live`, `record`, `distribute` and `train` (each `holds` or the reason it fails), whether the manifest `stands`, and each take's id and verdicts (`single_take`, `aligned`, `complete`, `publishable`, `stands`). **Clip equivalence.** For each clip, a conforming clip verifier given its `descriptor`, its `record` and its `parts` (each a `device` key, its `commits` in order, and its chunks' `bytes`, each hexadecimal or `null` for absent) reaches the outcome the vector states (§5.4): - `refuse`: the `reason` and where, `at`: `["descriptor"]`, `["clip"]`, `["part", k]`, `["commit", k, j]` for commitment `j` of part `k`, or `["chunk", k, j]` for chunk `j` of part `k`; - `accept`: the record's digest `clip`, its `signer`, its `window`, its `bound_us` (§6.2), and the `facts` of each part: its `take`, `first`, `count`, the take's `offset`, its `span` on the room clock, its `device_window`, the length (`bytes`) and `sha256` of the bytes it presents, and its MoQ `fetch` address (§8). A verifier that reaches another outcome, reason, place, verdict, digest or fact does not conform. **Provenance.** Generated here: `wai_live_record_vectors gen` writes every file, record and byte from sessions authored in code, from fixed seeds, by capture binding's corpus rules: each key is SHA-256 of that corpus's fixed label and the principal's index (two principals it does not use, the accompanist and the accompanist's device, take indexes of their own), each chunk's bytes SHA-256 output under a fixed label and the chunk's index (they stand for an encoded master and encode nothing), every time is a constant (the room's `t0` is 2026-10-16T00:00:00Z), and Ed25519 signing is deterministic (RFC 8032), so the file is the same bytes on every machine. A take written from one of capture binding's plans is that corpus's take byte for byte; the generator asserts that each vector reaches the outcome it was written to have before it writes it. The key-log heads are sealed by the reference's key log under a fixed root. The origins are `.example` names (RFC 2606). No recorded data. ## Layout One file, `vectors.json`: - `principals`: the keys, by name (informative). - `recordings`: each with `name`, `about`, `files`, `evaluated_at`, `reuses` (the take components that are capture binding's takes: each `take` id and the `vector` of `../takes/vectors.json` it is), `outcome`, and as above `reason`, `at`, `package`, `manifest`, `room`, `complete`, `publishable`, `stands` and `takes`. - `clips`: each with `name`, `about`, `descriptor`, `record`, `parts` (each with `device`, `commits`, `bytes`, and `take_vector`, the vector of `../takes/vectors.json` whose records every commitment and chunk of the part are, or `null`), `outcome`, and as above `reason`, `at`, `clip`, `signer`, `window`, `bound_us` and `facts`. Every session is a lesson room as capture binding's corpus has it (a director with the record power, an audience, a recording policy of mode 1 with a two-second commit interval and 500 ms of jitter, pinned to DE and FR, a key log listing the room authority and the store), here with up to two takes: - `lesson_session`: the performer's take, capture binding's `lesson` take, and the accompanist's, eight chunks of 1.25 s on a device whose clock runs three seconds ahead, sealed by the room authority; `signed_by_director`, the same sealed by the director; `with_composite`, the same with a composite component, whose one file stands for a composed object and encodes nothing; `late_recorder_span`, a director that joins at 1 s sealing the span from 1 s; - the record power over the span (§4.3), each refused at the instant it lapses: `signer_power_late` (the same director sealing from 0), `signer_removed` (removed at 18 s), `signer_power_exchanged` (exchanged at 17 s to a grant without the power) and `signer_grant_expired` (its grant expires at 18 s); and `signer_grant_revoked`, whose grant the key log revokes, refused at the room; - recordings that fail a claim: `take_omitted`, `missing_chunk` (capture binding's `missing_chunk` take), `commit_gap` and `consent_missing`; - recordings refused: `listing_mismatch`, `component_digest_mismatch`, `composite_digest_mismatch`, `component_unlisted`, `component_invalid`, `recording_manifest_invalid`, `manifest_bad_signature`, `manifest_wrong_room`, `signer_not_permitted`, `outside_region`, `outside_span`, `take_refused` and `room_refused`; - good clips: `single_chunk`, `byte_range`, `whole_take`, `first_chunk`, `last_chunk`, `accompanist_span`, `live_head`, `two_takes_aligned` and `late_take_clean_span`; - clips refused, one defect each: `proof_not_reaching_head`, `range_past_size`, `missing_chunk`, `spliced_two_takes`, `reordered_chunk`, `altered_chunk`, `extra_chunk`, `uncommitted_head`, `commit_gap`, `commit_malformed`, `take_mismatch`, `device_mismatch`, `clip_wrong_room`, `clip_bad_signature`, `clip_record_invalid`, `window_not_covered`, `trimmed_window`, `clip_truncated`, and spans of capture binding's defective takes: `commit_late`, `commit_early`, `root_not_extending`, `clock_unstable`, `capture_discontinuous`, `chunk_too_long` and `commit_chain_broken`. ## Running ``` cd ../../wai-rs cargo run --no-default-features --features live_record --bin wai_live_record_vectors -- verify ../live-conformance/recordings cargo run --no-default-features --features live_record --bin wai_live_record_vectors -- gen ../live-conformance/recordings # regenerate cargo test --no-default-features --features live_record --test live_record cd ../live-conformance python3 live_record_verify.py recordings ``` `wai_live_record_vectors verify` and `tests/live_record.rs` require the file to regenerate byte for byte and `wai-rs` to give every vector its outcome; the test also requires every reason of §9 to appear, the good recordings to stand and the good clips to be accepted, §9 to list exactly the reasons the reference reports, and every take the corpus says it reuses to be capture binding's, byte for byte, against `../takes/vectors.json`. `live_record_verify.py` is the second implementation, written from the extension's text and sharing no code with `wai-rs`: it checks range proofs by the extension's recursion and, for a run of one chunk, by RFC 9162 §2.1.3.2's algorithm, verifies each take with `capture_take_verify.py` (which verifies the room with `live_rooms_verify.py`), gives every vector the same outcome, requires the same coverage and reuse, and then mutates copies of the corpus, one defect each, each of which must fail. Pass = an exit status of 0 from each.