wai: wai.live.recording — a room session as one package, and provable clips (L7a) #299

Closed
dcharlot wants to merge 0 commits from wai/live-record into main
Owner

Slice L7a: room recording and provable clips. A finished room session becomes one WAI package. Any span cut from a recorded take carries a proof that it is exactly those bytes of that take, unedited, and that proof is checkable without the take. This PR holds the spec, the reference implementation, the conformance corpus and an independent verifier. It depends on nothing unmerged.

What is in it

  • wai/extensions/live-recording.md: registers the record wai.live.recording.
    • §3, the package. A recording is a directory of files plus its LISTING (SPEC §3.1), the same model as a packaging §11 package. Its components are:

      • the room: descriptor, grants and key-log head;
      • the events: each principal's chain whole, the form live-events §8.6 already gives a recording;
      • one component per participant take: its WTM1, the chunks the store holds, its WUR1 receipts and WCN1 consents;
      • optionally, the composite: its composition receipts, each named by its digest.

      A component is named as SPEC §7.1 names one: an id, and a sha256 that is the SHA-256 of the listing of its files. No new container and no new per-component digest.

    • §4, the recording manifest WRM1. It carries the signer, the room id, the session span on the room clock, the claims (complete) and purposes, the region the package is kept in, and each component's kind, id and digest.

      • It is signed by the room authority, or by a principal that holds the L2 record power at every instant of the span (§4.3, decided in review; see choice 5).
      • Verification runs in this order: the listing, the manifest, the component digests, the room (L2 verifier), the signer and the region pin, then each take (L4 verifier, plus the take lying within the span).
      • complete: no gap in the events; every take the room's events open within the span (a record_start its device answered with a take_commit) has a component; and every take is complete, with its commitments unbroken from open to close.
      • publishable{p}: every take is publishable{p}.
    • §5, clips. The clip record WCL1 has 1 to 16 parts. Each part is a span of one take: device, take, head (the digest of a take_commit event, plus its size and root), the covered chunks' descriptors, trims, and one range proof. The clip verifier is given the clip bytes, the record, the take's commitments from opening to head, the device key and the room descriptor. It is never given the take manifest, other chunks or other events. It checks single-take over the span:

      • chain, gap and extension of the commitments up to the head;
      • clock stability;
      • tiling and chunk length;
      • early and late commitment of each covered chunk;
      • each chunk's bytes.

      It reports the record's digest, the window, the bound, and for each part its span, its device-clock window, the digest of the presented bytes and its FETCH address.

    • §6, across takes. An aligned clip covers one room-clock window. In part p, room instant t is device instant t − o_p. Two parts correspond by d_q = d_p + o_p − o_q. The outcome states bound_us: J for one take, 2J between two.

    • §7, HLS / LL-CMAF (mapping only). For a CMAF master as capture-binding §4.1 cuts it:

      • one Media Playlist per take, EXT-X-VERSION ≥ 6;
      • EXT-X-MAP with a BYTERANGE into chunk 0, and chunk 0's segment by EXT-X-BYTERANGE;
      • VOD or EVENT, EXT-X-PROGRAM-DATE-TIME from the room clock, and EXT-X-DATERANGE events per live-events §8.3;
      • LL parts as EXT-X-PART byte ranges, each verifiable once its whole chunk is committed.

      Cited by identifier: RFC 8216 and draft-pantos-hls-rfc8216bis-22.

    • §8, DVR over MoQ FETCH (addressing only). Track Namespace [room, device, "take"], Track Name the take id; group g is chunk g, with one object. A clip part is a FETCH whose LOCATION_FILTER has StartGroup first, StartObject 0, EndGroupDelta count − 1 and no EndObject (draft-ietf-moq-transport-22 §3.2, §9.11, §9.20.9).

    • §9, reasons.

      • New: listing_mismatch, recording_manifest_invalid, component_invalid, component_digest_mismatch (SPEC §7.1's code), component_unlisted, recording_signer_not_permitted, outside_span, take_omitted, clip_record_invalid, clip_device_mismatch, clip_take_mismatch, tree_head_not_committed, clip_out_of_range, clip_not_included, clip_window_invalid, clip_chunk_missing.
      • Reused from L4 with the same meaning: the single-take codes and store_outside_region.
  • wai/wai-rs/src/output_tree.rs (additive only): audit_path, range_proof and verify_range.
  • wai/wai-rs/src/live_record.rs, with live_record/corpus.rs, feature live_record = ["capture_take"], cbindgen:ignore, no new dependency. It covers:
    • recording-manifest build (seal) and verify (verify_recording);
    • clip cut by chunks, by bytes (resolve_bytes) or by window (resolve_window), via cut_part and cut_clip;
    • clip verify (verify_clip) and FETCH addressing (fetch_range);
    • unit tests.
  • wai/live-conformance/recordings/: vectors.json from fixed seeds, plus a README with the provenance line. The corpus binary is wai_live_record_vectors; the test is tests/live_record.rs (required-features = ["live_record"]).
  • wai/live-conformance/live_record_verify.py: standard library only, sharing _ed25519.py.
    • It verifies takes through capture_take_verify.py (and so the room through live_rooms_verify.py).
    • It reimplements the range recursion from the spec text and RFC 9162 §2.1.3.2's inclusion check from the RFC's steps, and requires both to agree on single-chunk runs.
    • It mutates copies of the corpus and requires every copy to fail.
  • CI and registry.
    • A new step in independent-verifiers; the spec added to both path lists.
    • SPEC §5: the records list, plus a paragraph.
    • REGISTRY.md and codecs/registry.rs: the record, WRM1 (§4.1) and WCL1 (§5.1).
    • wai registry export rerun (capabilities.json, vocab/v2.ttl), and a CHANGELOG entry.
    • int_kernels_vectors' live-conformance exclusion reason now names recordings and clips.
  • Cross-links. live-events §8.6, live-rooms §3.7 and capture-binding §1 now point at the extension. L2 §3.7 had promised that "the recording extension checks it against the pin"; WRM1.region is that check.

Reuse of L4, byte for byte

The corpus writes takes from L4's own plans, with L4's key and chunk labels (L4's corpus helpers became pub(crate); nothing else in L4 changed). The performer's take in lesson_session is L4's lesson take: the same manifest, parts, receipts, consent and commitments. missing_chunk reuses L4's missing_chunk take in the same way. The negative clips use spans of L4's late_commit, commit_early, root_not_extending, clock_unstable, capture_discontinuous, chunk_too_long and commit_chain_broken takes.

Each recording states reuses and each clip part a take_vector. Both tests/live_record.rs and the Python verifier check them against the committed takes/vectors.json. L4's corpus still regenerates byte for byte, checked by tests/capture_take.rs and wai_capture_take_vectors verify.

The accompanist's second take is new: eight chunks of 1.25 s, on a device clock 3 s ahead. It exists so the aligned two-take clip has takes with different chunk boundaries and offsets.

Design choices a reviewer should check

  1. One range proof per part, not one audit path per chunk. RANGE(a, b, D[n]) is RFC 6962's PATH recursion taken over a run of leaves. For one leaf it is PATH, node for node. It has at most 2⌈log₂ n⌉ nodes (cap 128). Every node is a node of some covered leaf's audit path.
    • Tests check, for every run of trees up to 33 leaves, that the single-leaf case equals the audit path, and that its verdict equals RFC 9162 §2.1.3.2's verify_proof under every tested mutation.
    • Soundness rests on the size coming from the device-signed commitment, never from the cutter. The as8 case in output_tree's tests shows why: one proof can reach one root under two sizes.
  2. Partial chunks are allowed: the whole boundary chunk is carried and trim_in/trim_out are stated.
    • Why: a leaf commits to the whole chunk's hash, so a partial chunk can never be proven alone. Refusing would leave a byte-range request unprovable unless it happened to fall on chunk boundaries.
    • Trims are bytes and have no committed time, so they are allowed only in a single-take clip, whose window must then be its chunks' span.
    • Privacy consequence (spec §11): the trimmed bytes travel with the clip.
  3. The clip verifier also takes the room descriptor, beyond clip bytes, record, commitments and device key. It is needed for the room id and for I and J, which the timing rules use. It is small and signed by the authority, and it is not the take.
  4. "single-take over the span" means the L4 single-take rules that a span can carry: 1–3, 6, 7–8, 9–10 per chunk, and 11.
    • Rule 4 (closed) is dropped, so a clip can be cut against a running commitment (live_head).
    • Rule 5 (manifest) is replaced by inclusion.
    • Rule 9's start/stop clauses are dropped, since those events are not inputs.
    • So a take that fails single-take only outside a span still yields clips of that span (late_take_clean_span). Please check that this is the semantics wanted.
  5. Package model. I followed packaging's directory plus LISTING and SPEC §7.1's id/sha256 identity, with a multi-file component's sha256 taken as the SHA-256 of its listing (the wai.prior.set construct).
    • WAI2 was not usable: its entries are selectable renditions; records cannot be components (record-or-derivation-as-component); and its u32 offsets cap a payload block at 4 GiB.
  6. Signer power (choice 5 in the hand-off report; decided in review, implemented in 99029a6d). A signer other than the room authority must hold the record power at every instant of the span, from to to inclusive.
    • "Holds at t" means: in the room state replayed to t (every join, grant_exchange and leave of the signer that the room verifier accepted with t ≤ t), the signer is present under a grant that has the record power, is not revoked, and covers t.
    • So the grant took effect at or before from, and no leave, no exchange to a grant without the power, and no expiry takes the power away before to.
    • One shared code, recording_signer_not_permitted, with the instant stated at ["signer", t]: the first instant of the span without the power. That is from if no such grant was in effect at the start; otherwise the t of the leave or exchange, or the first instant past the grant's exp.
    • Why one code: the power over the span is one property. Each way it lapses is already a room record (a lifecycle event, or the grant window) that the instant points at. The instant is what a recorder needs to choose a span it can sign. Separate codes would duplicate L2's lifecycle vocabulary and need a precedence order for spans that fail several ways.
    • Key-log revocation is timeless in L2 §5 ("refuses every use of the grant ... not bounded by a time"). So a head that revokes the signer's grant makes the room verifier refuse the signer's join, and the recording is refused at the room with grant_revoked, before the signer rule. The signer_grant_revoked vector shows this. Inside a session, L2 removes a power with leave (removed), grant_exchange or expiry, and each of those has a vector.
    • New vectors: late_recorder_span stands (director joins at 1 s and seals [1 s, 20 s]); signer_power_late is refused at ["signer", 0] (the same director sealing from 0); signer_removed at 18 s; signer_power_exchanged at 17 s; signer_grant_expired at 18 s; signer_grant_revoked is refused at the room. The Python verifier states the same instants on its own, and two new mutations change a stated instant and must fail.
    • A consequence of the decision that I changed, please confirm. A recording holds the room's chains whole: L1 treats a chain that starts past seq 0 as a gap, and L2 can't replay a principal whose join isn't held. Under my earlier step 6 (every held record lies inside the span), the corollary "a recorder that gained the power partway signs a span that starts at its grant" could never verify, because earlier context records always exist. So step 6 now binds the takes the package holds: each take's record_start must be at or after from and its last held commitment at or before to, otherwise outside_span at that component. Records outside the span are context the manifest states nothing of. complete 2 counts the session's takes whose record_start lies within the span. The existing outside_span vector is now refused at its take component, ["component", 2].
  7. complete 2, the session's takes. These are the take ids of accepted record_start events, within the span, whose target device answered with a take_commit naming that take. A start no device answered is not an omitted take.
  8. Region. WRM1.region is checked against the room's pin and reuses L4's store_outside_region.
  9. Composite. Referenced by component digest. Each WCR1 receipt is named receipt-<digest>.wcr by its live-compose §8.1 digest. The verifier checks the digest only, so nothing depends on #296. The corpus composite file is a placeholder that "stands for a composed object and encodes nothing", like the chunk bytes.
  10. The task brief's "chunk missing in L4's resumed-upload case". L4's resumed_upload vector misses no chunk: chunk 3 is sent twice and the upload is sealed. The chunk that is actually missing is in L4's missing_chunk take (chunk 6 never uploaded), so that take is the one used, for both the recording and the clip negative.

Implemented and specified only

  • Implemented:
    • the package and its components;
    • WRM1 and recording verification with the complete and publishable verdicts;
    • WCL1, range proofs, cutting by chunks, bytes or window, and clip verification;
    • the time correspondence and its bound;
    • FETCH addressing (stated per part in every accepted clip, and checked by Python).
  • Specified, not implemented: the §7 HLS/LL-CMAF mapping. The corpus masters are not CMAF. The repo has no muxer for a device's master: wai-pack's CMAF writer writes AV1 floors and lives in a crate wai-rs does not depend on. No playlist is written.

Verification

Every cargo run went through ~/kani-logs/remote/rb on the build host, under memguard, with output written to a log there and grepped. origin/main had not moved (bea79dc6), so no merge was needed.

Earlier runs, on 7e620720 and before, all exited 0:

run exit
rb <wt> -- 'cargo test --no-default-features --features capture_take --no-run' (warm-up) 0
rb --pull <wt> -- 'cargo run … --bin wai_live_record_vectors -- gen ../live-conformance/recordings' (each regeneration) 0
rb --pull <wt> -- 'cargo run --no-default-features --bin wai -- registry export && … --check' 0

The same set, rerun on the head 99029a6d:

run exit
rb --pull <wt> -- 'gen && cargo test --no-default-features --features live_record --lib -- live_record:: capture_take:: output_tree:: && cargo test … --test live_record --test capture_take && wai_live_record_vectors verify' 0
rb <wt> -- 'touch cbindgen.toml; cargo build --no-default-features --features live_record --lib; git diff --exit-code -- include/wai.h' 0 (header unchanged)
rb <wt> -- 'cargo clippy --no-default-features --features live_record --all-targets' 0, with no finding in the new code
rb <wt> -- 'cargo run --no-default-features --bin wai -- registry export --check && cargo test --no-default-features --lib -- codecs::registry::' 0
rb <wt> -- 'cargo test --features live_record --lib -- live_record:: capture_take:: output_tree:: && cargo test --features live_record --test live_record --test capture_take && wai_live_record_vectors verify && wai_capture_take_vectors verify' 0
rb <wt> -- 'cargo test --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate,score,staged,stage_measure,legacy_int --test int_kernels_vectors' (the cargo-class corpora step's exact features) 0
  • Python (local, standard library): python3 -I live-conformance/live_record_verify.py live-conformance/recordings exits 0 on 26 recordings and 34 clips.
    • The Ed25519 and range-proof self-tests pass.
    • Every vector matches what the Rust reference states, the signer instants included.
    • Reason coverage, good vectors and reuse all pass.
    • Every mutated copy fails.
    • The verifiers for events, rooms and takes also exit 0.
  • Repo checks: check-tests-in-ci.py, check-spec-refs.py, check-wai-section-refs.py, check-no-vanity-metrics.sh, check-comparative-prose.sh and check-orphan-sources.py all exit 0. check-public-names.sh exits 2 because WAI_NAME_DENYLIST is not set locally; I grepped the new text by hand for third-party names and found none.

Deferred to L7b

  • DVR over FETCH on the relay: keeping a recording, its DVR window and storage, answering a FETCH by §8's addressing, and receipts for fetched groups.
  • A CMAF muxer for a device master that is not already CMAF, and writing the §7 playlists (VOD/EVENT, LL parts) with a player e2e.
  • Verifying the composite's WCR1 receipts inside a recording, once live-compose (#296) lands.

Notes

  • #296 (L3) touches the same files: registry.rs, SPEC, REGISTRY, CHANGELOG, capabilities.json, v2.ttl, the workflow and int_kernels_vectors. Whichever merges second needs a rebase of adjacent insertions, then wai registry export.
  • Not merged.

🤖 Generated with Claude Code


Closed: landed in main through #303 (wai/timed-text), which contains this branch's head 4ece5962 unchanged; 99029a6d was green on its own (55), and #303 was green with both (55).

Slice L7a: room recording and provable clips. A finished room session becomes one WAI package. Any span cut from a recorded take carries a proof that it is exactly those bytes of that take, unedited, and that proof is checkable without the take. This PR holds the spec, the reference implementation, the conformance corpus and an independent verifier. It depends on nothing unmerged. ## What is in it - **`wai/extensions/live-recording.md`**: registers the record `wai.live.recording`. - **§3, the package.** A recording is a directory of files plus its `LISTING` (SPEC §3.1), the same model as a packaging §11 package. Its components are: - the room: descriptor, grants and key-log head; - the events: each principal's chain whole, the form live-events §8.6 already gives a recording; - one component per participant take: its `WTM1`, the chunks the store holds, its `WUR1` receipts and `WCN1` consents; - optionally, the composite: its composition receipts, each named by its digest. A component is named as SPEC §7.1 names one: an `id`, and a `sha256` that is the SHA-256 of the listing of its files. No new container and no new per-component digest. - **§4, the recording manifest `WRM1`.** It carries the signer, the room id, the session span on the room clock, the claims (`complete`) and purposes, the region the package is kept in, and each component's kind, id and digest. - It is signed by the room authority, or by a principal that holds the L2 **record** power at every instant of the span (§4.3, decided in review; see choice 5). - Verification runs in this order: the listing, the manifest, the component digests, the room (L2 verifier), the signer and the region pin, then each take (L4 verifier, plus the take lying within the span). - **`complete`**: no gap in the events; every take the room's events open within the span (a `record_start` its device answered with a `take_commit`) has a component; and every take is `complete`, with its commitments unbroken from open to close. - **`publishable{p}`**: every take is `publishable{p}`. - **§5, clips.** The clip record `WCL1` has 1 to 16 parts. Each part is a span of one take: device, take, head (the digest of a `take_commit` event, plus its size and root), the covered chunks' descriptors, trims, and one **range proof**. The clip verifier is given the clip bytes, the record, the take's commitments from opening to head, the device key and the room descriptor. It is never given the take manifest, other chunks or other events. It checks `single-take` over the span: - chain, gap and extension of the commitments up to the head; - clock stability; - tiling and chunk length; - early and late commitment of each covered chunk; - each chunk's bytes. It reports the record's digest, the window, the bound, and for each part its span, its device-clock window, the digest of the presented bytes and its FETCH address. - **§6, across takes.** An aligned clip covers one room-clock window. In part *p*, room instant *t* is device instant *t* − *o_p*. Two parts correspond by *d_q* = *d_p* + *o_p* − *o_q*. The outcome states `bound_us`: *J* for one take, 2*J* between two. - **§7, HLS / LL-CMAF (mapping only).** For a CMAF master as capture-binding §4.1 cuts it: - one Media Playlist per take, `EXT-X-VERSION` ≥ 6; - `EXT-X-MAP` with a `BYTERANGE` into chunk 0, and chunk 0's segment by `EXT-X-BYTERANGE`; - VOD or EVENT, `EXT-X-PROGRAM-DATE-TIME` from the room clock, and `EXT-X-DATERANGE` events per live-events §8.3; - LL parts as `EXT-X-PART` byte ranges, each verifiable once its whole chunk is committed. Cited by identifier: RFC 8216 and `draft-pantos-hls-rfc8216bis-22`. - **§8, DVR over MoQ FETCH (addressing only).** Track Namespace `[room, device, "take"]`, Track Name the take id; group *g* is chunk *g*, with one object. A clip part is a FETCH whose `LOCATION_FILTER` has StartGroup `first`, StartObject 0, EndGroupDelta `count` − 1 and no EndObject (`draft-ietf-moq-transport-22` §3.2, §9.11, §9.20.9). - **§9, reasons.** - New: `listing_mismatch`, `recording_manifest_invalid`, `component_invalid`, `component_digest_mismatch` (SPEC §7.1's code), `component_unlisted`, `recording_signer_not_permitted`, `outside_span`, `take_omitted`, `clip_record_invalid`, `clip_device_mismatch`, `clip_take_mismatch`, `tree_head_not_committed`, `clip_out_of_range`, `clip_not_included`, `clip_window_invalid`, `clip_chunk_missing`. - Reused from L4 with the same meaning: the `single-take` codes and `store_outside_region`. - **`wai/wai-rs/src/output_tree.rs`** (additive only): `audit_path`, `range_proof` and `verify_range`. - **`wai/wai-rs/src/live_record.rs`**, with `live_record/corpus.rs`, feature `live_record = ["capture_take"]`, `cbindgen:ignore`, no new dependency. It covers: - recording-manifest build (`seal`) and verify (`verify_recording`); - clip cut by chunks, by bytes (`resolve_bytes`) or by window (`resolve_window`), via `cut_part` and `cut_clip`; - clip verify (`verify_clip`) and FETCH addressing (`fetch_range`); - unit tests. - **`wai/live-conformance/recordings/`**: `vectors.json` from fixed seeds, plus a README with the provenance line. The corpus binary is `wai_live_record_vectors`; the test is `tests/live_record.rs` (`required-features = ["live_record"]`). - **`wai/live-conformance/live_record_verify.py`**: standard library only, sharing `_ed25519.py`. - It verifies takes through `capture_take_verify.py` (and so the room through `live_rooms_verify.py`). - It reimplements the range recursion from the spec text and RFC 9162 §2.1.3.2's inclusion check from the RFC's steps, and requires both to agree on single-chunk runs. - It mutates copies of the corpus and requires every copy to fail. - **CI and registry.** - A new step in `independent-verifiers`; the spec added to both path lists. - SPEC §5: the records list, plus a paragraph. - REGISTRY.md and `codecs/registry.rs`: the record, `WRM1` (§4.1) and `WCL1` (§5.1). - `wai registry export` rerun (`capabilities.json`, `vocab/v2.ttl`), and a CHANGELOG entry. - `int_kernels_vectors`' `live-conformance` exclusion reason now names recordings and clips. - **Cross-links.** live-events §8.6, live-rooms §3.7 and capture-binding §1 now point at the extension. L2 §3.7 had promised that "the recording extension checks it against the pin"; `WRM1.region` is that check. ## Reuse of L4, byte for byte The corpus writes takes from L4's own plans, with L4's key and chunk labels (L4's corpus helpers became `pub(crate)`; nothing else in L4 changed). The performer's take in `lesson_session` *is* L4's `lesson` take: the same manifest, parts, receipts, consent and commitments. `missing_chunk` reuses L4's `missing_chunk` take in the same way. The negative clips use spans of L4's `late_commit`, `commit_early`, `root_not_extending`, `clock_unstable`, `capture_discontinuous`, `chunk_too_long` and `commit_chain_broken` takes. Each recording states `reuses` and each clip part a `take_vector`. Both `tests/live_record.rs` and the Python verifier check them against the committed `takes/vectors.json`. L4's corpus still regenerates byte for byte, checked by `tests/capture_take.rs` and `wai_capture_take_vectors verify`. The accompanist's second take is new: eight chunks of 1.25 s, on a device clock 3 s ahead. It exists so the aligned two-take clip has takes with different chunk boundaries and offsets. ## Design choices a reviewer should check 1. **One range proof per part, not one audit path per chunk.** `RANGE(a, b, D[n])` is RFC 6962's `PATH` recursion taken over a run of leaves. For one leaf it *is* `PATH`, node for node. It has at most 2⌈log₂ n⌉ nodes (cap 128). Every node is a node of some covered leaf's audit path. - Tests check, for every run of trees up to 33 leaves, that the single-leaf case equals the audit path, and that its verdict equals RFC 9162 §2.1.3.2's `verify_proof` under every tested mutation. - Soundness rests on the size coming from the device-signed commitment, never from the cutter. The `as8` case in `output_tree`'s tests shows why: one proof can reach one root under two sizes. 2. **Partial chunks are allowed**: the whole boundary chunk is carried and `trim_in`/`trim_out` are stated. - Why: a leaf commits to the whole chunk's hash, so a partial chunk can never be proven alone. Refusing would leave a byte-range request unprovable unless it happened to fall on chunk boundaries. - Trims are bytes and have no committed time, so they are allowed only in a single-take clip, whose window must then be its chunks' span. - Privacy consequence (spec §11): the trimmed bytes travel with the clip. 3. **The clip verifier also takes the room descriptor**, beyond clip bytes, record, commitments and device key. It is needed for the room id and for *I* and *J*, which the timing rules use. It is small and signed by the authority, and it is not the take. 4. **"`single-take` over the span"** means the L4 `single-take` rules that a span can carry: 1–3, 6, 7–8, 9–10 per chunk, and 11. - Rule 4 (closed) is dropped, so a clip can be cut against a running commitment (`live_head`). - Rule 5 (manifest) is replaced by inclusion. - Rule 9's start/stop clauses are dropped, since those events are not inputs. - So a take that fails `single-take` only outside a span still yields clips of that span (`late_take_clean_span`). Please check that this is the semantics wanted. 5. **Package model.** I followed packaging's directory plus `LISTING` and SPEC §7.1's `id`/`sha256` identity, with a multi-file component's `sha256` taken as the SHA-256 of its listing (the `wai.prior.set` construct). - `WAI2` was not usable: its entries are selectable renditions; records cannot be components (`record-or-derivation-as-component`); and its u32 offsets cap a payload block at 4 GiB. 6. **Signer power (choice 5 in the hand-off report; decided in review, implemented in `99029a6d`).** A signer other than the room authority must hold the record power at **every instant of the span**, `from` to `to` inclusive. - "Holds at *t*" means: in the room state replayed to *t* (every `join`, `grant_exchange` and `leave` of the signer that the room verifier accepted with `t` ≤ *t*), the signer is present under a grant that has the record power, is not revoked, and covers *t*. - So the grant took effect at or before `from`, and no `leave`, no exchange to a grant without the power, and no expiry takes the power away before `to`. - **One shared code, `recording_signer_not_permitted`, with the instant stated** at `["signer", t]`: the first instant of the span without the power. That is `from` if no such grant was in effect at the start; otherwise the `t` of the `leave` or exchange, or the first instant past the grant's `exp`. - Why one code: the power over the span is one property. Each way it lapses is already a room record (a lifecycle event, or the grant window) that the instant points at. The instant is what a recorder needs to choose a span it can sign. Separate codes would duplicate L2's lifecycle vocabulary and need a precedence order for spans that fail several ways. - **Key-log revocation** is timeless in L2 §5 ("refuses every use of the grant ... not bounded by a time"). So a head that revokes the signer's grant makes the room verifier refuse the signer's `join`, and the recording is refused at the room with `grant_revoked`, before the signer rule. The `signer_grant_revoked` vector shows this. Inside a session, L2 removes a power with `leave` (removed), `grant_exchange` or expiry, and each of those has a vector. - **New vectors:** `late_recorder_span` stands (director joins at 1 s and seals [1 s, 20 s]); `signer_power_late` is refused at `["signer", 0]` (the same director sealing from 0); `signer_removed` at 18 s; `signer_power_exchanged` at 17 s; `signer_grant_expired` at 18 s; `signer_grant_revoked` is refused at the room. The Python verifier states the same instants on its own, and two new mutations change a stated instant and must fail. - **A consequence of the decision that I changed, please confirm.** A recording holds the room's chains whole: L1 treats a chain that starts past seq 0 as a gap, and L2 can't replay a principal whose `join` isn't held. Under my earlier step 6 (every held record lies inside the span), the corollary "a recorder that gained the power partway signs a span that starts at its grant" could never verify, because earlier context records always exist. So step 6 now binds the **takes the package holds**: each take's `record_start` must be at or after `from` and its last held commitment at or before `to`, otherwise `outside_span` at that component. Records outside the span are context the manifest states nothing of. `complete` 2 counts the session's takes whose `record_start` lies within the span. The existing `outside_span` vector is now refused at its take component, `["component", 2]`. 7. **`complete` 2, the session's takes.** These are the take ids of accepted `record_start` events, within the span, whose target device answered with a `take_commit` naming that take. A start no device answered is not an omitted take. 8. **Region.** `WRM1.region` is checked against the room's pin and reuses L4's `store_outside_region`. 9. **Composite.** Referenced by component digest. Each `WCR1` receipt is named `receipt-<digest>.wcr` by its live-compose §8.1 digest. The verifier checks the digest only, so nothing depends on #296. The corpus composite file is a placeholder that "stands for a composed object and encodes nothing", like the chunk bytes. 10. **The task brief's "chunk missing in L4's resumed-upload case".** L4's `resumed_upload` vector misses no chunk: chunk 3 is sent twice and the upload is sealed. The chunk that is actually missing is in L4's `missing_chunk` take (chunk 6 never uploaded), so that take is the one used, for both the recording and the clip negative. ## Implemented and specified only - **Implemented:** - the package and its components; - `WRM1` and recording verification with the `complete` and `publishable` verdicts; - `WCL1`, range proofs, cutting by chunks, bytes or window, and clip verification; - the time correspondence and its bound; - FETCH addressing (stated per part in every accepted clip, and checked by Python). - **Specified, not implemented:** the §7 HLS/LL-CMAF mapping. The corpus masters are not CMAF. The repo has no muxer for a device's master: `wai-pack`'s CMAF writer writes AV1 floors and lives in a crate `wai-rs` does not depend on. No playlist is written. ## Verification Every cargo run went through `~/kani-logs/remote/rb` on the build host, under memguard, with output written to a log there and grepped. `origin/main` had not moved (`bea79dc6`), so no merge was needed. Earlier runs, on `7e620720` and before, all exited 0: | run | exit | |---|---| | `rb <wt> -- 'cargo test --no-default-features --features capture_take --no-run'` (warm-up) | 0 | | `rb --pull <wt> -- 'cargo run … --bin wai_live_record_vectors -- gen ../live-conformance/recordings'` (each regeneration) | 0 | | `rb --pull <wt> -- 'cargo run --no-default-features --bin wai -- registry export && … --check'` | 0 | The same set, rerun on the head **`99029a6d`**: | run | exit | |---|---| | `rb --pull <wt> -- 'gen && cargo test --no-default-features --features live_record --lib -- live_record:: capture_take:: output_tree:: && cargo test … --test live_record --test capture_take && wai_live_record_vectors verify'` | 0 | | `rb <wt> -- 'touch cbindgen.toml; cargo build --no-default-features --features live_record --lib; git diff --exit-code -- include/wai.h'` | 0 (header unchanged) | | `rb <wt> -- 'cargo clippy --no-default-features --features live_record --all-targets'` | 0, with no finding in the new code | | `rb <wt> -- 'cargo run --no-default-features --bin wai -- registry export --check && cargo test --no-default-features --lib -- codecs::registry::'` | 0 | | `rb <wt> -- 'cargo test --features live_record --lib -- live_record:: capture_take:: output_tree:: && cargo test --features live_record --test live_record --test capture_take && wai_live_record_vectors verify && wai_capture_take_vectors verify'` | 0 | | `rb <wt> -- 'cargo test --no-default-features --features neural_int,video_int,audio_int,world_int,splat_int,generate,score,staged,stage_measure,legacy_int --test int_kernels_vectors'` (the cargo-class corpora step's exact features) | 0 | - **Python** (local, standard library): `python3 -I live-conformance/live_record_verify.py live-conformance/recordings` exits 0 on 26 recordings and 34 clips. - The Ed25519 and range-proof self-tests pass. - Every vector matches what the Rust reference states, the signer instants included. - Reason coverage, good vectors and reuse all pass. - Every mutated copy fails. - The verifiers for events, rooms and takes also exit 0. - **Repo checks:** `check-tests-in-ci.py`, `check-spec-refs.py`, `check-wai-section-refs.py`, `check-no-vanity-metrics.sh`, `check-comparative-prose.sh` and `check-orphan-sources.py` all exit 0. `check-public-names.sh` exits 2 because `WAI_NAME_DENYLIST` is not set locally; I grepped the new text by hand for third-party names and found none. ## Deferred to L7b - **DVR over FETCH on the relay**: keeping a recording, its DVR window and storage, answering a FETCH by §8's addressing, and receipts for fetched groups. - **A CMAF muxer** for a device master that is not already CMAF, and writing the §7 playlists (VOD/EVENT, LL parts) with a player e2e. - **Verifying the composite's `WCR1` receipts** inside a recording, once live-compose (#296) lands. ## Notes - #296 (L3) touches the same files: `registry.rs`, SPEC, REGISTRY, CHANGELOG, `capabilities.json`, `v2.ttl`, the workflow and `int_kernels_vectors`. Whichever merges second needs a rebase of adjacent insertions, then `wai registry export`. - Not merged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- **Closed:** landed in main through #303 (wai/timed-text), which contains this branch's head 4ece5962 unchanged; 99029a6d was green on its own (55), and #303 was green with both (55).
output_tree gains audit_path, range_proof and verify_range: RFC 6962's PATH taken over a run
of leaves, whose one-leaf case is the audit path node for node, tested against RFC 9162
§2.1.3.2's check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
live-rooms §3.7 said the recording extension checks a recording's storage against the pin;
WRM1 now carries region and the verifier refuses one outside it (store_outside_region).
live-events §8.6, live-rooms §3.7 and capture-binding §1 point at live-recording.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The registry lists the record and its magics WRM1 (§4.1) and WCL1 (§5.1); the
independent-verifiers job runs the module's tests, tests/live_record.rs and
live_record_verify.py; the workflow's path lists name the extension; int_kernels_vectors'
live-conformance exclusion names recordings and clips. live-conformance/recordings is
regenerated from its seeds with the manifest's region and the outside_region vector.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: live-conformance/recordings regenerated with the composite vectors
Some checks failed
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI neural sink gates / does this change touch it (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-quantum WebGPU member / does this change touch it (pull_request) Has been cancelled
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been cancelled
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
7e620720a8
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A principal other than the room authority may sign WRM1 only under a grant with the record
power in effect over the whole span: effective at or before its start, with no leave,
grant_exchange or expiry taking the power away before its end. A refusal keeps the code
recording_signer_not_permitted and states the first instant of the span without the power,
at ["signer", t]. Since a recording holds the room's chains whole, the span now binds the
takes the package holds (each start and closing commitment within it) and the takes
complete counts, not every context record, so a recorder that gained the power partway
seals a span that starts at its grant. New vectors: late_recorder_span (stands),
signer_power_late, signer_removed, signer_power_exchanged, signer_grant_expired and
signer_grant_revoked (refused at the room: a key-log revocation is not bounded by a time).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: live-conformance/recordings regenerated with the record-power vectors
All checks were successful
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m33s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 4m59s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m29s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 11m30s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 2m0s
wai-pack / wai-pack · linux (pull_request) Successful in 1m20s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m10s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m23s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m7s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m24s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 24s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 12s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 31s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m2s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m42s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 12m37s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 15m32s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 50m52s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 49m10s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 5m36s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 48m57s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 5s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m54s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m42s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m18s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m22s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m29s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 27s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m21s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 4m37s
99029a6d33
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Main gained wai.live.compose (#296), which edits the same lines: SPEC §5's live-records
list and its paragraph, REGISTRY's list, wire-identifier table and magics, the registry's
capability constants, statuses and wire rows, Cargo features, binaries and tests, the
module list, the live-conformance README, the int_kernels_vectors reason and the
independent-verifiers job. Both are kept, compose before recording; the two CI steps stay
separate. capabilities.json is regenerated by wai registry export.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai registry export: wai.live.compose and wai.live.recording both listed
Some checks failed
WAI HTTP delivery / WAI HTTP · does this change touch it (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
4ece596222
Co-Authored-By: Claude Opus 5.5 <[email protected]>
dcharlot closed this pull request 2026-10-18 00:37:36 -04:00
Some checks failed
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 4s
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-quantum WebGPU member / does this change touch it (pull_request) Has been cancelled
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been cancelled
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI neural sink gates / does this change touch it (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / does this change touch it (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI HTTP delivery / WAI HTTP · does this change touch it (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!299
No description provided.