open-standards/wai/live-conformance/recordings
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science b9f27de9ad age assurance: the minors' profile over grants, live-recording refuses a room never recorded, the relay keeps no DVR window of a minors' room, the second implementation, registry and CI
The independent verifier's reading of the text found that a grant may narrow a
publishing role to publish nothing and keep its chat: §8.1 gains rule 4 over
grants, held at the first record that puts a minor's publishing grant into
effect. §2, §3.4, §3.6, §5.2, §6.2, §7.3 and §9.1 now pin the reading orders
and the attribution of claims, and the corpus covers the rules it did not
reach.

live-recording §4.4 step 5 refuses a package of a room whose recording policy
has mode 0 (recording_not_permitted); its corpus gains room_never_recorded and
live_record_verify.py the check. joule-moq's grant head reads the minor
attribute, and joule-moq-relay's DVR store keeps nothing of a room once a
session proves a minor's publishing grant of it, as it does for a sealed room,
across a restart; tests/dvr.rs shows it.

live-conformance/age_assurance_verify.py is the second implementation, written
from the text: it shares no code with wai-rs, verifies every RSASSA-PSS in its
own arithmetic, and catches every mutated copy and each of its own dropped
checks. The registry export, SPEC §5, the CHANGELOG, the corpus exclusion
reason and the wai-conformance step follow.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 15:29:49 -04:00
..
README.md wai: a recording's signer holds the record power at every instant of its span 2026-10-17 10:52:17 -04:00
vectors.json age assurance: the minors' profile over grants, live-recording refuses a room never recorded, the relay keeps no DVR window of a minors' room, the second implementation, registry and CI 2026-10-21 15:29:49 -04:00

live-conformance/recordings — live recording

The corpus of 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.