diff --git a/.github/workflows/wai-conformance.yml b/.github/workflows/wai-conformance.yml index 193ff9ebf..2c7c9ef1e 100644 --- a/.github/workflows/wai-conformance.yml +++ b/.github/workflows/wai-conformance.yml @@ -66,6 +66,15 @@ on: - 'wai/extensions/jwp-receipts.md' # The quantum referee requires this extension's Appendix B to state its phase tables. - 'wai/extensions/quantum-sim.md' + # tests/live_events.rs requires this extension's §9 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/live-events.md' + # tests/live_room.rs requires this extension's §11 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/live-rooms.md' + # tests/capture_take.rs requires this extension's §12 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/capture-binding.md' - 'wai/wai-web/**' # The audio provenance check below reads the corpora above with this tool. - 'wai/tools/wai_audio_provenance_check.py' @@ -103,6 +112,15 @@ on: - 'wai/extensions/jwp-receipts.md' # The quantum referee requires this extension's Appendix B to state its phase tables. - 'wai/extensions/quantum-sim.md' + # tests/live_events.rs requires this extension's §9 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/live-events.md' + # tests/live_room.rs requires this extension's §11 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/live-rooms.md' + # tests/capture_take.rs requires this extension's §12 to list the codes the reference + # reports, and the registry's wire identifiers test reads its sections. + - 'wai/extensions/capture-binding.md' - 'wai/wai-web/**' # The audio provenance check below reads the corpora above with this tool. - 'wai/tools/wai_audio_provenance_check.py' @@ -753,7 +771,9 @@ jobs: # verdicts required to equal wai_signer_vectors' line for line), and # int_payload_verify.py (the integer payloads and their refusal fixtures), and # staged_verify.py (the staged-delivery corpus), and http_verify.py (the HTTP delivery - # corpus), and quantum-conformance/tools/referee.py (both quantum-sim capabilities). + # corpus), and quantum-conformance/tools/referee.py (both quantum-sim capabilities), and + # live_events_verify.py (the live-events corpus), and live_rooms_verify.py (the + # live-rooms corpus), and capture_take_verify.py (the capture-binding corpus). # Each exits non-zero on any failure or any difference, and the step fails with it. # One platform: what they check is the reading of the text, not the architecture. independent-verifiers: @@ -874,6 +894,56 @@ jobs: for seed in 1 2; do python3 staged-measure-conformance/sim_diff.py wai-rs/target/debug/wai_stage_measure "$seed" 1500 done + # wai.live.events (extensions/live-events.md): the reference module's unit tests and + # tests/live_events.rs (the committed corpus regenerates byte for byte from its fixed + # seeds, wai-rs gives every vector, policy case and binding case its stated outcome, + # the corpus covers every kind and reason, and §9 lists exactly the reference's + # codes); then the corpus's second implementation, live_events_verify.py, written + # from the extension's text and sharing no code with wai-rs, which verifies the same + # cases with WAI's strict Ed25519 (claim-conformance/_ed25519.py) and BLAKE3 + # (claim-conformance/_blake3.py), standard library only, run isolated (-I). + - name: live events · wai-rs and live_events_verify.py + working-directory: wai + shell: bash + run: | + set -euo pipefail + (cd wai-rs && cargo test --no-default-features --features live_events --lib live_events::) + (cd wai-rs && cargo test --no-default-features --features live_events --test live_events) + python3 -I live-conformance/live_events_verify.py live-conformance/events + # wai.live.room (extensions/live-rooms.md): the reference module's unit tests and + # tests/live_room.rs (the committed corpus regenerates byte for byte from its fixed + # seeds, wai-rs gives every vector its stated outcome, every reason of §11 refuses a + # vector, and §11 lists exactly the reference's codes); then the corpus's second + # implementation, live_rooms_verify.py, written from the extension's text and sharing + # no code with wai-rs, which verifies every event with live_events_verify.py and every + # signature with WAI's strict Ed25519 (claim-conformance/_ed25519.py), standard + # library only, run isolated (-I). + - name: live rooms · wai-rs and live_rooms_verify.py + working-directory: wai + shell: bash + run: | + set -euo pipefail + (cd wai-rs && cargo test --no-default-features --features live_room --lib live_room::) + (cd wai-rs && cargo test --no-default-features --features live_room --test live_room) + python3 -I live-conformance/live_rooms_verify.py live-conformance/rooms + # wai.capture.take (extensions/capture-binding.md): the reference module's unit tests, + # the output tree's (whose RFC 6962 hash and RFC 9162 consistency proofs the take tree + # reuses), and tests/capture_take.rs (the committed corpus regenerates byte for byte + # from its fixed seeds, wai-rs gives every vector its stated outcome, every reason of + # §12 appears in it, and §12 lists exactly the reference's codes); then the corpus's + # second implementation, capture_take_verify.py, written from the extension's text and + # sharing no code with wai-rs, which verifies each room with live_rooms_verify.py and + # every signature with WAI's strict Ed25519 (claim-conformance/_ed25519.py), and + # requires every mutated copy of the corpus to fail; standard library only, run + # isolated (-I). + - name: capture take · wai-rs and capture_take_verify.py + working-directory: wai + shell: bash + run: | + set -euo pipefail + (cd wai-rs && cargo test --no-default-features --features capture_take --lib -- capture_take:: output_tree::) + (cd wai-rs && cargo test --no-default-features --features capture_take --test capture_take) + python3 -I live-conformance/capture_take_verify.py live-conformance/takes # The quantum corpus's second implementation (quantum-sim extension), integers only: # it derives the circuit/1 phase table by its recurrence and the circuit2 table by an # interval-certified procedure, and requires both literal tables and their digests, diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index 6734836e3..953adf182 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -6,6 +6,112 @@ wire format may change and such changes are recorded here. ## v0.4.0 — current +### `wai.capture.take`: a device's master recording bound to a live room + +- **The extension** ([capture-binding](extensions/capture-binding.md)) registers the + record `wai.capture.take`, for the case of a lesson or an audition where the live call is + low quality and the master is made on the performer's own device and uploaded after the + session. A take answers a `record_start` addressed to the device; its id is derived from + the room, the device and that event. The device's grant binds it to the principal it + captures for (the grant attribute `subject`), and may mark that principal a minor + (`minor`). +- **Commitments.** While it captures, the device emits a `take_commit` event every commit + interval of the room's recording policy (live-events §4.12's payload, defined here): the + take id, the chunk range it adds, the root over every chunk so far, its offset to the room + clock, and an RFC 9162 consistency proof that the root extends the last one. The take + tree is staged-measurement Appendix C's (RFC 6962's Merkle tree hash, its node) over + leaves that bind each chunk's index, capture range, length and hash; the output tree + exposes that hash and gains consistency proofs for it. +- **Upload and manifest.** The master is uploaded resumably by chunk hash; the store, a key + the room's key log lists with the new authority `capture/store`, signs `WUR1` receipts of + the upload's state machine (open, progress, resume, sealed) within the room's region pin. + The device signs a `WTM1` take manifest listing the chunks, their root, every + commitment's digest and each subject's `WCN1` consent (purposes live, record, distribute + and train; a guardian's signature for a minor; revocable through the key log). +- **Verdicts.** A take verifier replays the room (live-rooms §9) and gives `single-take`, + `aligned`, `complete` and `publishable` for each purpose a verdict, each failure a named + reason (§12): a commitment not delivered is `delivery_gap`; a part not committed at its + index is altered, reordered or extra; a missing part fails `complete`, not `single-take`. + A room-clock instant maps into the master, so a marker set on the live call lands in it. +- **Live rooms.** The recording policy gains `commit_interval_ms` and `jitter_ms` + (live-rooms §3.7; 2 000 and 500 by default), and the rooms corpus is regenerated. +- **C2PA live video** (C2PA Technical Specification 2.4 §19): the mapping of a take and its + CMAF output onto per-segment manifests and Verifiable Segment Info, session keys, AI + disclosure and sustainability is specified; the crate has no CBOR or COSE encoder, so it + implements only the stream id. +- **Reference and corpus.** `wai-rs` feature `capture_take` (`src/capture_take.rs`); + `live-conformance/takes/`, written from fixed seeds by `wai_capture_take_vectors`, and + checked by `tests/capture_take.rs` and by `live-conformance/capture_take_verify.py`, a + second implementation that shares no code with `wai-rs` and requires every mutated copy + of the corpus to fail. The registry lists the record and its magics (`WTM1`, `WUR1`, + `WCN1`). + +### `wai.live.room`: room descriptors, room grants and the room verifier + +- **The extension** ([live-rooms](extensions/live-rooms.md)) registers the record + `wai.live.room`. A room is fixed by a signed descriptor, `WRD1`, whose digest is the + room id every `WEV1` event names: its authority, its clock and `t0`, the roles a + principal may hold (publish per media kind, subscribe up to a layer, the event kinds it + may send, and the moderate, direct, compose and record powers), its limits and event + ceiling, the slots several publishers may stand behind, its publish profiles, its + review policy and its recording policy with a region pin. +- **Grants.** A principal takes part under a signed room grant, `WRG1`: its role and + capabilities, a window of at most fourteen days, its delivery origins, a single-use + nonce, a viewer id, the `WEP1` event policy of live-events §5 it is held to, its joule + and funds ceilings, the profiles it publishes with, and at most 1 KB of composition + attributes. A grant is exchanged for one chained to it at a tick of the room clock, + recorded as the `grant_exchange` lifecycle event, and revoked through the authority's + key log: the head's `revoked_modules` lists revoked grants and viewers, and the + authority's key holds the new authority `live/room` (jwp-receipts §7.2, §7.5, §7.6). +- **Tracks, slots and profiles.** A track is named by the MOQT namespace tuple (room, + principal or slot, media kind) and its layer. A slot is a virtual track: a publisher of + higher precedence takes it over with no new session, and a standby takes it on failover + under the slot's rule. The lifecycle kinds' `detail` is defined. The publish profiles + `speech`, `music`, `screen`, `camera-720` and `camera-1080` fix codecs, layers and + limits as data. +- **Room verification.** Given a descriptor, grants, a key-log head and every principal's + chain, a verifier merges the chains by room clock, verifies each event with the + live-events verifier under the policy of the grant in effect at its `t`, and replays the + lifecycle into room state; each refusal has a named reason (§11). +- **Bindings**, as tables: the Common Access Token's claims (CTA-5007-B), the `moqt` claim + of `draft-ietf-moq-c4m-01` (whose scopes the reference derives from each grant), URI + Signing (RFC 9246) and Privacy Pass (`draft-ietf-moq-privacy-pass-auth-03`). No CAT + encoding: the crate has no CBOR. +- **Reference and corpus.** `wai-rs` feature `live_room` (`src/live_room.rs`); + `live-conformance/rooms/`, written from fixed seeds by `wai_live_room_vectors`, and + checked by `tests/live_room.rs` and by `live-conformance/live_rooms_verify.py`, a second + implementation that shares no code with `wai-rs`. The registry lists the record and its + magics (`WRD1`, `WRG1`). + +### `wai.live.events`: a signed, timeline-bound event track + +- **The extension** ([live-events](extensions/live-events.md)) registers the record + `wai.live.events`. Timed metadata, ad and chapter cues (with an SCTE 35-1 + `splice_info_section()` or an SCTE 35-2 message carried verbatim), chat, reactions, + polls, markers, remote-control commands, captions with their machine-generation label, + moderation decisions, take commitments and room lifecycle are each one `WEV1` record: + signed by its principal, hash-chained per principal (`seq`, `prev`), stamped with the + room clock and optionally anchored to one MoQ object. Its digest is SHA-256 over the + record without the signature, and its signature is verified strictly (SPEC §7 + *Signatures*). +- **Policy and verification.** The event policy `WEP1` states the kinds a principal may + send and the payload, text and rate bounds, every bound a default a room may change; the + room grant of a later extension carries the same fields. A verifier refuses a record + with a named reason (§9), and reports a delivery gap as a gap, never as corruption. +- **Polls** replay as `wai.feed.state` cells through `wai.world.sim.feed0` (`ADD_INT`): + a tally is replay-equivalent, and a tally a poll's author states is checked. +- **Bindings**, field semantics only: an MSF event timeline over MoQ (`eventType` + `urn:wai:event:1`, one track per principal, one-minute groups, a join set repeated at + each group start), `EXT-X-DATERANGE` (`CLASS="science.transaction.wai.event"`, + `X-WAI-EVENT`, with `SCTE35-OUT`/`-IN`/`-CMD` for cues), a version 1 `emsg` + (`scheme_id_uri` `urn:wai:event:1`), a WebRTC data channel and a recording. +- **Reference and corpus.** `wai-rs` feature `live_events` (`src/live_events.rs`); + `live-conformance/events/`, written from fixed seeds by `wai_live_events_vectors`, and + checked by `tests/live_events.rs` and by `live-conformance/live_events_verify.py`, a + second implementation that shares no code with `wai-rs`. The registry lists the record + and its wire identifiers (`WEV1`, `WEP1`, `urn:wai:event:1`, + `science.transaction.wai.event`, `X-WAI-EVENT`). + ### wai-quantum 0.6.2: the HIP member's matrix-instruction kernel, and the Metal member's tensor-operation kernel Additive. Every pinned digest is unchanged. diff --git a/wai/REGISTRY.md b/wai/REGISTRY.md index 21dec382e..28d1b1f30 100644 --- a/wai/REGISTRY.md +++ b/wai/REGISTRY.md @@ -39,7 +39,9 @@ Every registered string has one kind. capability decoded and names no payload format. - **record** — a signed record a WAI tool emits and verifies (a receipt kind: `wai.asset.provenance`, the quantum-operations receipts, the delivery records - `wai.video.manifest` and its siblings). It names no payload format. + `wai.video.manifest` and its siblings; the live records `wai.live.events`, + `wai.live.room` and `wai.capture.take`). + It names no payload format. A derivation or record string is not a payload capability, so it is not dispatchable (SPEC §4): dispatch never takes an envelope's capability that names @@ -58,8 +60,10 @@ Two further tables hold strings that look like capabilities and are not: A third holds the **wire identifiers**: the names the container, its delivery bindings ([http-delivery](extensions/http-delivery.md), [moq-streaming-format](extensions/moq-streaming-format.md)), the key discovery -they serve ([jwp-receipts](extensions/jwp-receipts.md) §7) and -[packaging](extensions/packaging.md) put on the wire outside a +they serve ([jwp-receipts](extensions/jwp-receipts.md) §7), +[packaging](extensions/packaging.md), [live-events](extensions/live-events.md), +[live-rooms](extensions/live-rooms.md) and [capture-binding](extensions/capture-binding.md) +put on the wire outside a manifest — magic numbers, a media type, `codecs` prefixes, paths, playlist tags and attributes, document kinds and catalog fields — each with its kind, the section that defines it, and whether it is defined, provisional (test material only until @@ -164,6 +168,7 @@ and a role are fixed once registered. | `wai.audio.scene` | payload | registered | audio | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content | | `wai.audio.score` | payload | registered | audio | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content | | `wai.avatar.pose` | payload | registered | interactive | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content | +| `wai.capture.take` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.derive.crop` | derivation | registered | — | — | patent-pool | — | — | §5 Prior artifacts, general tensors and derivation operations | | `wai.derive.dissolve` | derivation | registered | — | — | patent-pool | — | — | §5 Prior artifacts, general tensors and derivation operations | | `wai.derive.grid_composition` | derivation | registered | — | — | patent-pool | — | — | §5 Prior artifacts, general tensors and derivation operations | @@ -187,6 +192,8 @@ and a role are fixed once registered. | `wai.image.jpegai` | payload | registered | image | standalone | royalty-free | neural-entropy-exact | — | §5 Neural capabilities | | `wai.image.jxl` | payload | registered | image | standalone | royalty-free | standard-tolerance | recommended | §5 Recommended modern set | | `wai.image.png` | payload | registered | image | standalone | royalty-free | standard-defined | floor | §5 Mandatory floor | +| `wai.live.events` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | +| `wai.live.room` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.mesh.draco` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR | | `wai.mesh.glb` | payload | registered | volumetric | standalone | royalty-free | standard-unclassified | — | §5 Interactive, temporal & computed content | | `wai.meta.dovi` | companion | registered | metadata | companion | proprietary | standard-unclassified | — | §5 Immersive audio, cinema, volumetric, haptics, HDR | @@ -281,19 +288,30 @@ and a role are fixed once registered. | `WAI1` | magic | defined | SPEC §2 | | `WAI2` | magic | defined | SPEC §7.1 | | `WAI_RECEIPT` | catalog | defined | moq-streaming-format §5 | +| `WCN1` | magic | defined | capture-binding §8.1 | +| `WEP1` | magic | defined | live-events §5 | +| `WEV1` | magic | defined | live-events §3.1 | | `WHP1` | magic | defined | http-delivery §6.2 | +| `WRD1` | magic | defined | live-rooms §3.1 | +| `WRG1` | magic | defined | live-rooms §4.1 | | `WSIX` | magic | defined | packaging §6 | +| `WTM1` | magic | defined | capture-binding §7.1 | +| `WUR1` | magic | defined | capture-binding §6.2 | +| `X-WAI-EVENT` | playlist-attribute | defined | live-events §8.3 | | `X-WAI-FLOOR` | playlist-attribute | defined | http-delivery §11.1 | | `application/wai` | media-type | proposed | http-delivery §3 | | `mr/` | path | defined | http-delivery §8.6 | | `rcpt/` | path | defined | http-delivery §8.1 | | `science.transaction.wai.class` | data-id | defined | packaging §8 | +| `science.transaction.wai.event` | playlist-attribute | defined | live-events §8.3 | | `science.transaction.wai.multivariant` | data-id | defined | http-delivery §11.1 | | `science.transaction.wai.stages` | data-id | defined | packaging §8 | | `tag:transaction.science,2026:wai/class` | scheme | defined | packaging §8 | | `tag:transaction.science,2026:wai/floor` | scheme | defined | http-delivery §11.1 | | `tag:transaction.science,2026:wai/http-delivery` | scheme | defined | http-delivery §11.1 | | `tag:transaction.science,2026:wai/stages` | scheme | defined | packaging §8 | +| `urn:wai:event:1` | scheme | defined | live-events §8.4 | +| `urn:wai:event:1` | catalog | defined | live-events §8.1 | | `wai` | catalog | defined | moq-streaming-format §3 | | `wai-key-status` | document-kind | defined | jwp-receipts §7.9 | | `wai-module-grant` | document-kind | defined | jwp-receipts §7.9 | diff --git a/wai/SPEC.md b/wai/SPEC.md index ef304ed51..52d76145d 100644 --- a/wai/SPEC.md +++ b/wai/SPEC.md @@ -591,7 +591,8 @@ kind: - a **record**: a signed record a WAI tool emits and verifies (a receipt kind — `wai.asset.provenance`, `wai.quantum.calibration`, `wai.quantum.job`, and the delivery records `wai.video.manifest`, `wai.video.ssai`, `wai.video.keys`, - `wai.video.package` and `wai.video.channel`), which names no payload format. + `wai.video.package` and `wai.video.channel`; and the live records `wai.live.events`, + `wai.live.room` and `wai.capture.take`), which names no payload format. Only payload, companion and refinement capabilities have a media class, a fidelity tier, a replicate class and a role. A derivation or record string is not a payload @@ -855,6 +856,44 @@ grant's joule ceiling (gate ⊗ meter ⊗ receipt in one object). WAI owns the receipt; the sink's control system runs the hardware: [`extensions/quantum-ops.md`](extensions/quantum-ops.md). +The same verify half, for **live events** — `wai.live.events`, a signed, +timeline-bound event track: timed metadata, ad and chapter cues, chat, reactions, +polls, markers, remote-control commands, captions, moderation decisions and room +lifecycle, each one `WEV1` record signed by its principal, hash-chained to that +principal's previous event, stamped with the room clock and optionally anchored to +one media object, so a delivery gap is told apart from corruption and a poll's tally +replays as `wai.feed.state` cells. The same bytes ride an MSF event timeline, an +`EXT-X-DATERANGE` tag, a version 1 `emsg` box, a data channel and a recording: +[`extensions/live-events.md`](extensions/live-events.md). + +And for the **rooms** those events belong to — `wai.live.room`: the signed room +descriptor whose digest is the room id, fixing the room's authority, its clock and `t0`, +the roles a principal may hold, its limits, the slots several publishers may stand +behind, its publish profiles, and its review and recording policies (with a region pin +for data residency); and the signed room grant under which one principal takes part, +carrying its capabilities, a window of at most fourteen days, a single-use nonce, the +event policy it is held to, its joule and funds ceilings and its composition attributes. +A grant is exchanged at a tick of the room clock and revoked through the authority's key +log; a room verifier replays every principal's events under the grant in effect at each +instant. The grant maps onto existing token formats rather than defining one: +[`extensions/live-rooms.md`](extensions/live-rooms.md). + +And for a **take** recorded in a room — `wai.capture.take`: a device's full-quality master +recording, made on the device beside a live call of lower quality, bound to the room while +it is captured. Every commit interval of the room's recording policy the device emits a +`take_commit` event in the room's event track, carrying the take id (derived from the +director's `record_start`), the chunks it adds, the root of a Merkle tree over every chunk +so far with a consistency proof that it extends the last, and the device's offset to the +room clock, so the room clock stamps each commitment and every participant holds it. The +master is uploaded by chunk hash under the store's signed receipts, and the device signs a +take manifest listing the chunks, their root, every commitment and the consent of each +subject, a guardian's for a minor, revocable through the key log. A verifier checks it +against the room's events and gives each claim its verdict: `single-take` (one continuous +take, every chunk committed while it was captured, every part uploaded the chunk committed +at its index), `aligned` (capture began at the count-in's instant), `complete`, and +`publishable` for each purpose. The take maps onto C2PA live video output: +[`extensions/capture-binding.md`](extensions/capture-binding.md). + ### Payloads of the WAI-native integer codecs This revision pins a payload format to each WAI-native integer codec whose row named diff --git a/wai/extensions/capture-binding.md b/wai/extensions/capture-binding.md new file mode 100644 index 000000000..001f72fc7 --- /dev/null +++ b/wai/extensions/capture-binding.md @@ -0,0 +1,727 @@ +# WAI Extension: Capture Binding + +> Status: Draft. Registers the record `wai.capture.take`: the binding of a device's +> full-quality **master** recording to a live room, so that the master, uploaded after +> the session, proves it is one continuous take committed while it was being captured. +> While it records, the device publishes rolling commitments to its master, `take_commit` +> events ([live-events](live-events.md) §4.12) in the room's event track, where they are +> stamped with the room clock and held by the relay and by every other participant. After +> the session the device uploads the master, resumably and by content address, the store +> records the upload in signed receipts, and the device signs a **take manifest** listing +> the chunks, their root, every commitment and the consent of every principal the master +> records. A verifier checks the manifest against the room's events and gives each claim +> its verdict: `single-take`, `aligned`, `complete` and `publishable` for each purpose. +> The reference case is a lesson or an audition, where the live call is low quality and +> the master is made on the performer's own device. No new transport: the commitments are +> events, and the mapping onto C2PA live video output is field semantics (§11). The +> reference implementation is the `capture_take` module of `wai-rs` (feature +> `capture_take`); the corpus is [`live-conformance/takes/`](../live-conformance/takes/), +> and its second implementation is `live-conformance/capture_take_verify.py`. +> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174. +> +> Texts read for this revision: RFC 6962 §2.1 and RFC 9162 §2.1.4 (the Merkle tree hash +> and its consistency proofs); ISO/IEC 23000-19 (CMAF) and ISO/IEC 14496-12; and the C2PA +> Technical Specification, version 2.4: §13.2.1, §18.15, §18.25, §18.26, §18.28 and §19. +> A section number of that specification in this text is that version's. + +## 1. Scope + +In scope: how a device and a take bind to the principal they capture for, the take id, +and what a `record_start` and `record_stop` pair brackets (§3); the chunks of a master and +the tree over them (§4); the `take_commit` payload and the chain of a take's commitments +(§5); the upload, by content address, and the store's signed receipts (§6); the take +manifest (§7); the consent record (§8); verification of a take and the verdict of each +claim (§9); the mapping from a room-clock instant to a position in the master, and its +bound (§10); and the mapping of a take and its CMAF output onto C2PA live video (§11). + +Out of scope: a transport; the master's codec and container (a take commits to its bytes, +whatever they encode); how a store is operated; the room's own recording (a later +extension); per-object receipts of the relay that witness when a commitment was seen +(a later extension); and what a party does with a verdict. + +Relationship to the core spec: `wai.capture.take` is a **record** ([SPEC](../SPEC.md) §5): +a signed record a WAI tool emits and verifies. It names no payload format and is not +dispatchable. + +## 2. Terms + +- **Room**, **room clock**, **principal**, **event**, **chain**, **grant**, **grant in + effect**, **room key**, **merged order**: as in live-events §2 and live-rooms §2, §9.2. +- **Device**: the Ed25519 key (RFC 8032) of the device that captures. It takes part in the + room under a grant (live-rooms §4) as a principal: it signs its `take_commit` events and + its take manifest. +- **Master**: the encoded recording the device makes, at the quality it captures. +- **Device clock**: the clock the device stamps its capture with, in microseconds. Its + epoch is the device's. +- **Offset**: the room clock less the device clock, in microseconds, as the device measures + it: a device-clock instant *d* is the room-clock instant *d* + offset. +- **Chunk**: a contiguous run of the master's bytes (§4.1). +- **Take**: one continuous capture on one device, answering one `record_start` (§3). +- **Store**: the service the master is uploaded to, named by its Ed25519 key (§6). +- **Subject**: a principal the master depicts or records. +- **Purpose**: a use a subject consents to: `live` (1), `record` (2), `distribute` (4), + `train` (8), each a bit of a purposes byte. +- *I* and *J*: the room's `commit_interval_ms` and `jitter_ms` (live-rooms §3.7), each + times 1000, in microseconds. + +Integers are little-endian. A digest is SHA-256 (FIPS 180-4), 32 bytes. An event's digest +is live-events §3.2's. + +## 3. The device, its principal and the take + +### 3.1 Binding a device to a principal + +A device captures for one principal, which its grant names: the device's grant in effect +**binds** it to principal *P* when the grant's attributes (live-rooms §4.4) hold the key +`subject` whose value is *P*'s key as 64 lowercase hexadecimal digits, or, when they hold +no `subject`, when *P* is the device's own key. The room authority signs the grant, so the +binding is the authority's statement that this device captures for *P*: a device can be +a key of its own (one per room, live-events §11) and still capture for a principal its +participants know. + +A principal is **marked a minor** in a take when the device's grant that binds it holds +the attribute `minor` with the value `true`, or when its consent record says so (§8.1). + +### 3.2 The take id + +A take is named by its **take id**, derived and never chosen: SHA-256 over the 18 bytes +`wai:capture-take` (ASCII) and 0x01, then the room id, the device's key, and the digest of +the `record_start` event the take answers. One `record_start` addressed to one device +names one take. + +### 3.3 What a take brackets + +A take answers a `control` event (live-events §4.9) whose command is `record_start` and +whose `target` is the device, sent by a principal with the record power (live-rooms §3.3, +§9.2 step 5). Its **start** is that event. Its **capture instant** is the room-clock +instant `t` + `count_in_ms` × 1000 of the start: the count-in fixes when capture begins, +for every participant alike. + +Its **stop** is the first `control` event in the merged order after the start whose command +is `record_stop` and whose `target` is the device; a take need not have one. A second +`record_start` to the same device before the stop starts another take. + +The device's first commitment of the take **opens** it, in answer to the start; its last +**closes** it, after the stop (§5.3). A room whose recording policy has `mode` 0 is never +recorded, and no take in it is permitted (§9.1). The interval *I* and the jitter *J* a +take is held to are the room's (live-rooms §3.7), so no device chooses its own. + +## 4. Chunks and the take tree + +### 4.1 Chunks + +The device cuts its encoded master into chunks, by bytes or by duration, in the order the +master's bytes run. Where the master is CMAF (ISO/IEC 23000-19), chunk 0 is the CMAF +header followed by the first CMAF segment, and each later chunk is one CMAF segment, so +that the header, whose edit lists could reorder what a segment presents, is committed +with the first chunk. A chunk is described by 64 bytes, its **descriptor**: + +| offset | size | field | meaning | +|---|---|---|---| +| 0 | 8 | `index` | u64: the chunk's position in the master, from 0 | +| 8 | 8 | `start` | u64: the device-clock instant its capture begins | +| 16 | 8 | `end` | u64: the device-clock instant its capture ends (exclusive) | +| 24 | 8 | `len` | u64: its length in bytes, at least 1 | +| 32 | 32 | `hash` | the digest of its bytes | + +A chunk holds the encoded samples captured from `start` to `end`. Its capture range is +the device's statement; the commitments fix it while the capture runs (§5), and the +verdicts hold the device to it (§9.4). + +### 4.2 The take tree + +The take tree is the tree of [staged-measurement](staged-measurement.md) Appendix C: RFC +6962's Merkle tree hash over SHA-256, its node that appendix's, over leaves of the take's +own domain: + +``` +leaf = SHA-256("wai:take-leaf\x01" ‖ descriptor) 64-byte descriptor, §4.1 +node = SHA-256("wai:out-node\x01" ‖ left ‖ right) staged-measurement Appendix C +``` + +The **root** over the descriptors of chunks 0 to *n* − 1, *n* ≥ 1, is RFC 6962 §2.1's +`MTH`: one leaf is itself; otherwise `node(MTH(D[0:k]), MTH(D[k:n]))`, with *k* the +largest power of two below *n*. No leaf is duplicated, so a root and its size fix the +list of descriptors. The root over no chunk is 32 zero bytes. A **commitment** is a size +and its root; as there, a root alone is not one. The leaf binds each chunk's index, its +capture range, its length and its hash, so a commitment fixes when each chunk was captured +as well as what it holds. + +### 4.3 Consistency + +A commitment (*n*, root′) **extends** (*m*, root) when the first *m* chunks under root′ are +the chunks under root. The proof of it is RFC 9162 §2.1.4.1's consistency proof, the +`PROOF(m, D[n])` of RFC 6962 §2.1.2, a list of nodes, checked as RFC 9162 §2.1.4.2 checks +one, with the node of §4.2 in place of its `HASH(0x01 ‖ …)`. RFC 9162 leaves two cases to +the caller, and this extension decides them: every commitment extends (0, zero), with an +empty proof; and (*m*, root′) extends (*m*, root), with an empty proof, exactly when the +roots are equal. Otherwise 0 < *m* < *n* and the proof is not empty. + +A witness that holds only the previous commitment checks that the next extends it: the +relay and every participant can check, while the take runs, that the device never +rewrites what it has committed. A proof does not fix either size, as an audit path does +not (staged-measurement Appendix C): a commitment states its size, and a verifier that +holds the chunks recomputes every root under the size stated (§9.4). + +## 5. Commitments + +### 5.1 The `take_commit` payload + +Every *I* while it captures, the device emits a `take_commit` event (live-events §4.12) in +the room, on its own events track. Its payload: + +| field | size | meaning | +|---|---|---| +| `take` | 32 | the take id (§3.2) | +| `n` | 4 | u32: the commitment's number in the take, from 0 | +| `phase` | 1 | 1 open, 2 running, 3 close | +| `prev` | 32 | the digest of the take's commitment `n` − 1; 32 zero bytes when `n` is 0 | +| `first` | 8 | u64: the index of the first chunk this commitment adds | +| `size` | 8 | u64: the chunks committed so far; this commitment adds chunks `first` to `size` − 1 | +| `root` | 32 | the root over chunks 0 to `size` − 1 (§4.2) | +| `offset` | 8 | i64, two's complement: the offset (§2) the device measures at the event | +| `proof_len` | 1 | the number of nodes in `proof`, at most 64 | +| `proof` | 32 × `proof_len` | that (`size`, `root`) extends the previous commitment (`first`, its root) (§4.3) | + +The fixed part is 126 bytes, so a proof of up to 28 nodes fits live-events' default +`max_payload` of 1024. The chunk range it names, `first` to `size` − 1, is what a witness +that missed the previous commitment still learns. + +### 5.2 Reading a payload + +A reader reads the payload in the order of §5.1 and refuses it as `commit_malformed`: when +it ends before a field or holds bytes after `proof`; when `phase` is not 1, 2 or 3; when +`size` is below `first`; when `proof_len` is above 64; or when `size` is 0 and `root` is +not 32 zero bytes. A room verifier (live-rooms §9) carries the payload opaque, as +live-events §4.12 has it; a take verifier reads it (§9.2). + +### 5.3 The chain of a take's commitments + +A take's commitments are the `take_commit` events of the device whose `take` is the take +id, in the order of the device's chain. They form their own chain: + +- The **opening** commitment is the first: `n` 0, `phase` open, `prev` zero, `first` and + `size` 0, and no proof. The device emits it when the start reaches it, before its + capture begins. +- Each later commitment `n` has `n` one above the previous one's, `prev` the previous + one's digest, `first` the previous one's `size`, and `phase` running or close. It adds + the chunks the device has completed since the previous one, perhaps none, and proves + that its commitment extends the previous one (§4.3). +- The **closing** commitment, `phase` close, is the last: after the stop, it adds the + chunks captured up to the stop, and no commitment of the take follows it. + +The chain needs nothing a witness does not hold: `n` and `prev` make a commitment that was +not delivered a gap in the take, as live-events §6.2 makes it one in the device's chain, +and the proof makes a rewritten history a commitment that does not extend. + +## 6. Upload + +### 6.1 Parts + +After the session the device uploads its master to a store, chunk by chunk, each chunk a +**part**: its index and its bytes, addressed by the chunk's hash. The upload is +resumable: a part that did not arrive is sent again, and a part sent twice is the same +part. A verifier fetches the parts from the store by hash and is given them as a list of +(index, bytes) in the order it received them. + +### 6.2 The upload receipt + +The store records the upload's state in signed **upload receipts**, `WUR1`, one at each +change of state: + +| offset | size | field | meaning | +|---|---|---|---| +| 0 | 4 | `magic` | `WUR1` (ASCII) | +| 4 | 1 | `version` | 1 in this revision | +| 5 | 32 | `store` | the store's Ed25519 key | +| 37 | 32 | `take` | the take id | +| 69 | 8 | `seq` | u64: the receipt's position in the upload's chain, from 0 | +| 77 | 32 | `prev` | the digest of receipt `seq` − 1; 32 zero bytes when `seq` is 0 | +| 109 | 8 | `at` | u64: the store's clock, in microseconds since 1970-01-01T00:00:00Z | +| 117 | 1 | `state` | 1 open, 2 progress, 3 resume, 4 sealed | +| 118 | 8 | `held` | u64: the chunks the store holds, from index 0 with none missing | +| 126 | 32 | `root` | the root over those chunks (§4.2), zero when `held` is 0 | +| 158 | 2 | `region` | ISO 3166-1 alpha-2: where the store keeps the chunks | +| 160 | 64 | `sig` | Ed25519 by `store` | + +The **digest** of a receipt is SHA-256 over its bytes before `sig`. The **signature** is +Ed25519 by `store` over the 17 bytes `wai:take-upload` (ASCII) and 0x01, followed by the +bytes the digest covers, verified strictly (SPEC §7 *Signatures*). + +A reader reads exactly the bytes it is given, as live-events §3.3 reads a record with +`WUR1` for `WEV1`: `truncated`, `malformed` or `unknown_version`. + +### 6.3 The state machine + +The receipts of an upload are a chain, and its states move only this way: + +- receipt 0 is `open`, with `held` 0; +- `progress`: `held` above the previous receipt's, as parts arrive; +- `resume`: `held` equal to the previous receipt's: an upload interrupted and resumed, + which continues from the chunk at `held`; +- `sealed`: `held` equal to the previous receipt's; the store holds the master, and no + receipt follows. + +A verifier, given the receipts in a list, checks each in the list's order and refuses at +the first that fails, naming it by its index: the record reads (§6.2); its `state` is 1 to +4, its `region` two capitals `A`–`Z`, and its `root` zero when `held` is 0, otherwise +`upload_receipt_invalid`; its `store` and `take` are the manifest's (§7), +`upload_receipt_invalid`; its signature verifies (`bad_key`, `bad_signature`); its `seq` +is its index, its `prev` the previous receipt's digest, its `at` not below the previous +one's, its `region` receipt 0's, and its `state` one the list above allows after the +previous receipt, otherwise `upload_receipt_invalid`; its `held` is at most the +manifest's chunk count and its `root` the root over the manifest's first `held` chunks, +otherwise `upload_receipt_mismatch`; and, where the room's recording policy pins regions +(live-rooms §3.7), its `region` is one of them, otherwise `store_outside_region`. + +### 6.4 The store + +A room whose descriptor names an `origin` (live-rooms §5) names its stores in that +origin's key log: a store's key is an entry of the head whose `may_sign` holds the +authority `capture/store` ([jwp-receipts](jwp-receipts.md) §7.5) and whose `status` is +not `revoked`. A verifier refuses a take whose store the head does not so list as +`store_not_listed`. In a room with no origin the store is the one the manifest names, and +its receipts are its statement alone. + +## 7. The take manifest + +### 7.1 Layout + +When the upload is complete, the device signs a take manifest, `WTM1`: + +| field | size | meaning | +|---|---|---| +| `magic` | 4 | `WTM1` (ASCII) | +| `version` | 1 | 1 in this revision | +| `room` | 32 | the room id | +| `device` | 32 | the device's key, which signs the manifest | +| `principal` | 32 | the principal the take is captured for (§3.1) | +| `start` | 32 | the digest of the take's start (§3.3) | +| `take` | 32 | the take id (§3.2) | +| `store` | 32 | the store's key (§6) | +| `claims` | 1 | the claims the manifest makes: bit 0 `single-take`, bit 1 `aligned`, bit 2 `complete` | +| `purposes` | 1 | the purposes it claims the master `publishable` for (§2) | +| `chunks` | 4 + 64 × *n* | a u32 count *n*, then each chunk's descriptor (§4.1), in index order | +| `root` | 32 | the root over the *n* chunks (§4.2) | +| `commits` | 4 + 32 × *m* | a u32 count *m*, then the digest of each of the take's commitments, in the order of `n` | +| `depicted` | 1 + 64 × *k* | a u8 count *k*, then each subject: its key (32) and the digest of its consent record (32; zero for none) (§8) | +| `sig` | 64 | Ed25519 by `device` | + +The **digest** of a manifest is SHA-256 over its bytes before `sig`; its **signature** is +Ed25519 by `device` over the 21 bytes `wai:capture-manifest` (ASCII) and 0x01, followed by +the bytes the digest covers, verified strictly (SPEC §7 *Signatures*). + +### 7.2 Reading and rules + +A reader reads exactly the bytes it is given, as live-events §3.3 reads a record with +`WTM1` for `WEV1` (`truncated`, `malformed`, `unknown_version`), and refuses a manifest +that breaks any of these rules as `manifest_invalid`: + +- `claims` sets no bit above bit 2, and `purposes` none above bit 3; +- *n* is at least 1, each chunk's `index` is its position in the list, and each `len` is + at least 1; +- `root` is the root over the chunks; +- *m* is at least 1, and no digest is listed twice; +- *k* is 1 to 32, the subjects' keys in strictly ascending byte order, and `principal` is + one of them; +- `take` is the take id of `room`, `device` and `start` (§3.2). + +It then refuses a manifest whose `room` is not the room's as `wrong_room`, and one whose +signature does not verify as `bad_key` or `bad_signature`. + +The manifest lists every subject the master depicts or records, the take's principal +among them, and binds each to its consent. A claim bit or a purpose bit states what the +device claims; a verifier gives every claim its verdict whether the manifest makes it or +not (§9.4). + +## 8. Consent + +### 8.1 The consent record + +A subject's consent is a signed record, `WCN1`: + +| offset | size | field | meaning | +|---|---|---|---| +| 0 | 4 | `magic` | `WCN1` (ASCII) | +| 4 | 1 | `version` | 1 in this revision | +| 5 | 32 | `subject` | the subject's key | +| 37 | 1 | `minor` | 1 when the subject is a minor, otherwise 0 | +| 38 | 32 | `guardian` | the key of the subject's guardian; 32 zero bytes for none | +| 70 | 1 | `purposes` | the purposes consented to (§2) | +| 71 | 32 | `room` | the room it is for; 32 zero bytes for any room | +| 103 | 8 | `nbf` | u64: seconds since 1970-01-01T00:00:00Z from which it holds | +| 111 | 8 | `exp` | u64: the second before which it holds | +| 119 | 16 | `nonce` | distinguishes two consents with the same fields | +| 135 | 64 | `sig` | Ed25519 by the guardian when `guardian` is not zero, by the subject otherwise | + +The **digest** of a consent is SHA-256 over its bytes before `sig`. The **signature** is +over the 20 bytes `wai:capture-consent` (ASCII) and 0x01, followed by the bytes the digest +covers, verified strictly (SPEC §7 *Signatures*): a minor's consent is the guardian's +act, any other the subject's own. + +### 8.2 Reading + +A verifier, given consent records in a list, checks each in its order and refuses at the +first that fails, naming it by its index: the record reads, as live-events §3.3 reads one +with `WCN1` for `WEV1`; it holds these rules, otherwise `consent_invalid`: `minor` is 0 or +1, `guardian` is zero when `minor` is 0, `guardian` is not `subject`, `purposes` is not 0 +and sets no bit above bit 3, and `nbf` is below `exp`; and its signature verifies +(`bad_key`, `bad_signature`). A record marked a minor with no guardian reads: it is a +record no minor's consent can rest on (§9.4). + +### 8.3 Revocation + +A consent is revoked through the room authority's key log, as a grant is (live-rooms §5): +its digest is added to the head's `revoked_modules`, which is append-only, so a +revocation stays. A subject or guardian that withdraws consent asks the authority to list +it. In a room whose descriptor names no origin no consent can be revoked, and a room that +records subjects **SHOULD** name one. + +## 9. Verification + +### 9.1 Inputs and steps + +A take verifier is given the room (a descriptor, grants, the head of the authority's key +log or none, and the chains, as live-rooms §9.1), the take manifest, the parts (§6.1), the +upload receipts, the consent records, and an **evaluation instant** `at`, in seconds since +1970-01-01T00:00:00Z: the time its verdicts are about. It runs these steps and stops at +the first refusal, which it reports with the reason and where: + +1. **The room** (live-rooms §9): a refusal is the take's, at `room`, with the room's own + place. A gap is not a refusal: the steps go on over the records the room verifier + holds, and §9.4 says what a gap fails. +2. **The manifest** (§7.2): at `manifest`. +3. **The take in the room** (§9.2): at `manifest`, or at the record it names. +4. **The store** (§6.4): at `store`. **The receipts** (§6.3): at the receipt's index. +5. **The consents** (§8.2): at the record's index. +6. **The verdicts** (§9.4). + +### 9.2 The take in the room + +Over the records the room verifier accepted, in the merged order (live-rooms §9.2), with +each one's grant: + +1. The recording policy's `mode` is not 0: otherwise `recording_not_permitted`. +2. The manifest's `start` is the digest of an accepted record that is a `control` event + whose command is `record_start` and whose `target` is the manifest's `device`: + otherwise `take_unknown`. +3. Every accepted `take_commit` event of the device has a payload §5.2 reads: otherwise + `commit_malformed`, at that record. Those whose `take` is the take id are the take's + **held commitments**, in the device's chain order. +4. At each held commitment, the device's grant in effect binds it to the manifest's + `principal` (§3.1): otherwise `device_not_bound`, at that record. +5. The held commitments are the manifest's `commits`, in its order, with those not held + left out; a listed digest that is not held is the digest of no accepted record, and + the room verifier reports a gap in the device's chain. Otherwise `manifest_mismatch`. + +A commitment listed and not held is so a commitment the relay did not deliver, and the +device's chain shows the gap; a manifest cannot list one the room holds out of its place, +leave one out, or list one no gap can account for. + +### 9.3 Mapping and timing + +The take's clock mapping is the offset *o* of its opening commitment: a device-clock +instant *d* maps to the room-clock instant *d* + *o*, computed without overflow (the +reference computes in 128-bit integers). A chunk's **mapped end** is its `end` mapped. For +each commitment, its `t` is the room-clock instant of its event; the capture instant, the +start and the stop are §3.3's. Every comparison in this section is between room-clock +instants, in microseconds. + +### 9.4 The verdicts + +Each claim holds, or fails with the first reason below that applies to it. + +**`single-take`** holds when the master is one continuous take, every chunk of it +committed while it was captured, and every part uploaded is the chunk committed at its +index: + +1. `delivery_gap`: a commitment the manifest lists is not held. +2. `commit_chain_broken`: the held commitments are not a chain of §5.3: the first is not + an opening one, a later one's `n`, `prev` or `first` does not follow its predecessor, + a later one is an opening one, or a commitment follows a closing one. +3. `root_not_extending`: a commitment does not extend its predecessor (§4.3): its proof + does not verify, a proof is given where §4.3 gives none, or a commitment that adds no + chunk changes the root. +4. `take_not_closed`: the last held commitment is not a closing one, or the take has no + stop. +5. `manifest_not_committed`: the manifest's chunk count is not the closing commitment's + `size`, or, for a held commitment whose `size` is above 0, the root over the + manifest's first `size` chunks is not its `root`. +6. `clock_unstable`: a commitment's offset differs from *o* by more than *J*. +7. `capture_discontinuous`: a chunk's `start` is not below its `end`, or a chunk's + `start` is not the previous chunk's `end`. +8. `chunk_too_long`: a chunk's `end` − `start` is above *I*. +9. `commit_early`: the opening commitment's `t` is below the start's; the closing one's + is below the stop's; or a commitment's `t` + *J* is below the mapped end of a chunk it + adds (it committed a chunk before the chunk was captured). +10. `commit_late`: a commitment's `t` is above the mapped end of a chunk it adds plus *I* + plus *J*. +11. Over the parts, in the order given, the first that is not the chunk committed at its + index: `chunk_extra` when its index is not below the chunk count; `chunk_reordered` + when its bytes' digest and length are another committed chunk's; `chunk_altered` + otherwise. + +By rules 8 and 10, every byte of the master was committed within 2 × *I* + *J* of its +capture on the take's clock mapping, and by rule 6 that mapping held to within *J* +throughout. + +A part missing from the upload does not fail `single-take`: what was uploaded is what was +committed, and the commitments verify. It fails `complete`. A party promised an unedited +single take needs `single-take` and `complete` together: `single-take` alone holds of an +upload that left chunks out. + +**`aligned`** holds when capture began at the instant the count-in fixed: + +1. `delivery_gap`: the first commitment the manifest lists is not held. +2. `commit_chain_broken`: the first held commitment is not an opening one. +3. `manifest_not_committed`: no held commitment adds a chunk, or the root over the + manifest's first `size` chunks is not the root of the first held commitment that does. +4. `misaligned`: chunk 0's `start`, mapped, differs from the capture instant by more than + *J*. + +**`complete`** holds when the upload covers every committed chunk and the store sealed it: +with *s* and *r* the `size` and `root` of the last held commitment, + +1. `manifest_not_committed`: *s* is 0, *s* is above the manifest's chunk count, or the + root over the manifest's first *s* chunks is not *r*. +2. `chunk_missing`: an index below *s* has no part whose bytes' digest and length are that + chunk's. +3. `upload_not_sealed`: the last receipt is not `sealed`, or its `held` is not *s*. + +**`publishable`** for purpose *p* holds when every subject the manifest lists consented to +the recording and to *p*. For each subject, in the manifest's order, the first that +fails: + +1. `consent_missing`: its consent digest is zero, or no consent record given has it, or + that record's `subject` is not this subject, or its `room` is neither zero nor the room + id. +2. `guardian_missing`: the subject is marked a minor (§3.1: by the record's `minor`, or, + for the take's principal, by the `minor` attribute of the device's grant in effect at + its first held commitment) and the record's `guardian` is zero. +3. `consent_revoked`: the head's `revoked_modules` lists the record's digest (§8.3). +4. `consent_expired`: the record does not hold (`nbf` ≤ *s* < `exp`) at the start's + instant, *s* = ⌊(`t0` + `t`) / 10^6⌋ of the start, or at `at`. +5. `purpose_not_consented`: its `purposes` lack `record`, or lack *p*. + +### 9.5 Outcome + +A take verification gives one outcome: + +- **refuse**: the reason and where (§9.1). +- **verdicts**: the verdict of `single-take`, `aligned`, `complete`, and `publishable` + for each of the four purposes, each `holds` or its reason; and whether the manifest + **stands**: every claim it makes, and `publishable` for every purpose it names, holds. + +## 10. Dual-tier binding + +The live tracks of the room and the master share the room clock: every event of the room +has its `t` on it (live-events §3.1), and the take's mapping places the master on it +(§9.3). A room-clock instant *t* within the take maps to the master: + +- the device-clock instant is *d* = *t* − *o*; +- the chunk is the one whose `start` ≤ *d* < `end`; +- the position is *d* − that chunk's `start` into the chunk, and *d* − chunk 0's `start` + into the master. + +An instant before chunk 0's mapped start or at or after the last chunk's mapped end is +outside the master. A marker set on the live call at room time *t* (live-events §4.8) so +lands at its instant in the master. The bound: where `single-take` and `aligned` hold, the +mapping strays from the device's own clock mapping at any commitment by at most *J* (rule +6), and the master's start from the capture instant by at most *J*. The marker's `t` is +its author's statement of the room clock (live-events §11), and a marker set by watching +the live call lags what it marks by that call's own delay; a marker anchored to a live +object (live-events §3.1) names the object instead, and a sink that knows that object's +capture instant on the room clock maps that instant. + +## 11. C2PA live video + +This section maps a take, and a CMAF output of a room, onto the C2PA Technical +Specification's live video provenance (§19 there). It is field semantics, and this +revision implements none of it beyond the stream id: `wai-rs` has no CBOR or COSE +encoder, and the C2PA signer `c2pa_emit` uses writes whole-asset manifests and fragmented +BMFF manifests (one manifest in the initialization segment, a Merkle tree over the +fragments), with no live video segment assertion, no session keys assertion and no +Verifiable Segment Info. The take's commitments are the WAI side's witness; the C2PA +output is what a C2PA validator reads, and each is checked on its own. + +### 11.1 What maps to what + +- **The stream.** A take is one live video session. Its `streamId` (§19.3.2) is the take + id's first 16 bytes as an RFC 9562 UUID of version 8: byte 6's high four bits set to + `1000`, byte 8's high two bits to `10`, written in the 8-4-4-4-12 lowercase form. The + corpus states it for each take. +- **The segments.** Where the master is CMAF, chunk *i* holds the segment whose movie + fragment the device numbers *i* + 1 in its `mfhd` `sequence_number` + (ISO/IEC 14496-12), and that is the segment's `sequenceNumber` in both methods. Chunk 0 + holds the initialization segment too (§4.1), with the C2PA Manifest Box §19.2.3 + requires. +- **The hashes.** A chunk's `hash` covers every byte of the chunk, its C2PA boxes + included; the segment's `c2pa.hash.bmff.v3` excludes them by §19's exclusions. The two + are different digests of different spans. + +### 11.2 Per-segment manifests (§19.3) + +Each segment carries a C2PA Manifest Box in a `uuid` box, whose manifest holds a +`c2pa.hash.bmff.v3` over the segment and the assertion `c2pa.livevideo.segment` with +`sequenceNumber` as above, `streamId` the take's, `continuityMethod` `c2pa.manifestId`, +and `previousManifestId` the manifest identifier of chunk *i* − 1's segment. The +initialization segment's manifest carries `c2pa.actions.v2` whose first action is +`c2pa.created` with the IPTC digital source type `digitalCapture` (§18.15.2). + +Each segment's manifest **MAY** also carry the assertion `science.transaction.wai.take`, +a map of `take` (the take id), `room` (the room id), `device` (the device's key) and +`commit` (the digest of the device's last `take_commit` before the segment was written, +absent before the first), each a byte string, so that a C2PA validator finds the room +events that witness the take. + +### 11.3 Verifiable Segment Info (§19.4) + +- **The session key** (§18.25, `c2pa.session-keys`, in the initialization segment's + manifest): the device's key, as an OKP COSE_Key of curve Ed25519, EdDSA being among + §13.2.1's algorithms, with `kid` the key's 32 bytes; `minSequenceNumber` 1; `createdAt` + the opening commitment's instant, `t0` + `t`; `validityPeriod` from then to the `exp` + of the device's grant; and `signerBinding`, a COSE_Sign1 by the session key over the + claim signer's end-entity certificate, as §18.25 has it. The device's key is then + bound to the room by its grant and to the C2PA signer by the binding. +- **Each segment** carries an `emsg` box of version 0, `scheme_id_uri` + `urn:c2pa:verifiable-segment-info`, `value` `fseg`, `presentation_time_delta` 0, + `timescale` and `event_duration` covering the segment, `id` the `sequenceNumber`, and + `message_data` a COSE_Sign1_Tagged by the session key whose payload holds + `sequenceNumber`, `bmffHash` (the segment's, excluding its C2PA `emsg` boxes, with no + `merkle` field) and `manifestId` (§19.4.1, §19.4.2). +- A COSE Sig_structure begins with the context string `Signature1`, and every message + WAI signs begins with a `wai:` domain, so no signature of one is a signature of the + other. + +### 11.4 A room's CMAF output + +A CMAF rendition a packager makes of a room's live tracks maps the same way, as its own +live video session: its own `streamId`, its own session key, its own claim signer. That +is the packager's provenance of its output, not the device's of its take. + +### 11.5 AI disclosure and sustainability + +- **AI disclosure** (§18.28, `c2pa.ai-disclosure`). A take's manifest has no field for a + trained model, and its C2PA output carries no `c2pa.ai-disclosure`: its source type is + a digital capture. A CMAF output that carries captions a model produced (live-events + §4.10, `origin` 2 or 3) discloses them: `modelIdentifier` is `sha256:` followed by the + caption's `model` digest in lowercase hexadecimal; `contentProfile` + `humanOversightLevel` is `fully_autonomous` for `origin` 2 and `human_validated` for 3; + `modelType` is required and an event does not carry it, so an emitter writes the + assertion only where it knows the model's type (§18.28's Table 12). +- **Sustainability** (§18.26, `c2pa.environmental-sustainability`). An emitter writes + `energy_kwh` only from a measured figure with its class, under + [energy-binding](energy-binding.md)'s rules, and never `carbon_kgco2e` or + `water_litres` derived from a figure and a factor. A take carries no energy figure in + this revision, so its output carries no such assertion. + +## 12. Reasons + +The codes this extension adds, each with where it is raised: + +| reason | raised at | +|---|---| +| `recording_not_permitted` | §9.2 step 1 | +| `take_unknown` | §9.2 step 2 | +| `commit_malformed` | §5.2, §9.2 step 3 | +| `device_not_bound` | §3.1, §9.2 step 4 | +| `manifest_invalid` | §7.2 | +| `manifest_mismatch` | §9.2 step 5 | +| `store_not_listed` | §6.4 | +| `upload_receipt_invalid` | §6.3 | +| `upload_receipt_mismatch` | §6.3 | +| `store_outside_region` | §6.3 | +| `consent_invalid` | §8.2 | +| `commit_chain_broken` | §9.4 `single-take` 2, `aligned` 2 | +| `root_not_extending` | §4.3, §9.4 `single-take` 3 | +| `take_not_closed` | §9.4 `single-take` 4 | +| `manifest_not_committed` | §9.4 `single-take` 5, `aligned` 3, `complete` 1 | +| `clock_unstable` | §9.4 `single-take` 6 | +| `capture_discontinuous` | §9.4 `single-take` 7 | +| `chunk_too_long` | §9.4 `single-take` 8 | +| `commit_early` | §9.4 `single-take` 9 | +| `commit_late` | §9.4 `single-take` 10 | +| `chunk_extra` | §9.4 `single-take` 11 | +| `chunk_reordered` | §9.4 `single-take` 11 | +| `chunk_altered` | §9.4 `single-take` 11 | +| `misaligned` | §9.4 `aligned` 4 | +| `chunk_missing` | §9.4 `complete` 2 | +| `upload_not_sealed` | §9.4 `complete` 3 | +| `consent_missing` | §9.4 `publishable` 1 | +| `guardian_missing` | §9.4 `publishable` 2 | +| `consent_revoked` | §9.4 `publishable` 3 | +| `consent_expired` | §9.4 `publishable` 4 | +| `purpose_not_consented` | §9.4 `publishable` 5 | + +The first eleven are refusals; the rest are verdicts. A take verifier also raises every +code a room verifier raises (live-rooms §11 and the live-events codes it lists), at +`room`; `truncated`, `malformed`, `unknown_version`, `bad_key` and `bad_signature` for a +manifest, a receipt or a consent record that does not read or whose signature fails; +`wrong_room` for a manifest of another room; and `delivery_gap` as a verdict. + +## 13. Conformance + +[`live-conformance/takes/`](../live-conformance/takes/) holds the corpus, in one file, +`vectors.json`, written from fixed seeds by `wai_capture_take_vectors gen`. Each vector is +a room, a manifest, parts, receipts, consent records and an evaluation instant, with the +outcome §9.5 gives them; one with verdicts also states the take id, its commitment count +and digests, its size and root, its stream id (§11.1), and the master position of every +marker of the room within the take (§10). + +- **Good takes**: a lesson take (the director's remote `record_start` with a count-in, + the performer's chunks and commitments, the director's markers, `record_stop`, the + upload and the manifest), whose every claim holds but `publishable` for `train`, which + the performer did not consent to; the same take with an upload interrupted and resumed; + and a minor's take under a guardian's consent. +- **Negatives**, each a control of one defect: a commitment not delivered, a spliced + chunk, a reordered one, an extra one never committed, a missing one (`complete` fails, + `single-take` holds), a late commitment, a root that does not extend its predecessor, + a capture that ignored the count-in, a consent missing, expired or revoked, a minor + without a guardian, a device not bound to the principal; and every other reason of §12, + with a manifest of another room and one whose signature fails. + +A conforming verifier gives every vector the outcome, the reason, the place, the verdicts +and the data the corpus states. `wai_capture_take_vectors verify` and the test +`tests/capture_take.rs` check that the file regenerates byte for byte, that `wai-rs` gives +every vector its outcome, that every reason of §12 appears in the corpus, and that §12 +lists exactly the reference's codes. `live-conformance/capture_take_verify.py` is the +second implementation, written from this text: it shares no code with `wai-rs`, verifies +signatures with WAI's strict rule written from RFC 8032 (`claim-conformance/_ed25519.py`), +verifies the room with the live-rooms corpus's own second implementation +(`live_rooms_verify.py`, which verifies each event with `live_events_verify.py`), and gives +every vector the same outcome; it also mutates copies of the corpus and requires every +copy to fail. + +## 14. Security and privacy considerations + +- The commitments are events: signed by the device, chained, stamped with the room clock + and held by every participant. A relay can drop one, which the take's chain and the + device's chain both show, but cannot alter one. A device that edits its master after + committing it cannot upload the edit as its take: the edited chunk is not the committed + one, and a history it rewrites does not extend what it committed. +- A commitment's `t` is its author's statement (live-events §11). A device that + pre-dates its commitments is held by the room's other records: its events take their + place in the merged order among everyone's, and the per-hop receipts of a later + extension witness when each was seen. The take's timing rules bound everything to the + room clock from the start's instant on, within *I* and *J*. +- The capture range of a chunk is the device's statement. The rules bind it to the room + clock at every commitment (rules 6 to 10 of `single-take`) and to the count-in + (`aligned`), so a device can neither stretch a chunk over time it did not capture nor + commit a chunk before its capture ends; it can still capture something other than the + room, which no commitment proves. +- Content addressing makes a part its own check: a part whose bytes do not hash to its + chunk's `hash` is not that chunk, whoever stored it. +- The store's receipts state the upload's state machine; they cannot make a part the + committed chunk, and a store's statement of `held` is checked against the manifest's + chunks. The region pin binds where the store keeps the master, as the room's policy + requires (live-rooms §3.7). +- A consent is the subject's act, or a guardian's for a minor, and revocable through the + key log as a grant is. `publishable` reads the head the caller gives: a revocation the + head does not yet list is not seen. A minor is marked by the room authority in the + device's grant, and by the record itself, so a minor's consent signed by the minor + alone does not stand. +- A take links the device's key, the principal it captures for and every subject's + consent. A manifest names subjects by key; who a key is stays with the room authority + and the store that keep the master. The master is personal data of everyone it records: + the region pin and the room's `retention_days` (live-rooms §3.7) apply to it, and a + consent's `purposes` and `exp` bound what may be done with it. diff --git a/wai/extensions/jwp-receipts.md b/wai/extensions/jwp-receipts.md index a2688520a..9ea1df194 100644 --- a/wai/extensions/jwp-receipts.md +++ b/wai/extensions/jwp-receipts.md @@ -2864,7 +2864,7 @@ is a JSON object with exactly these members, under §2.4.3's encodings: | `root` | 32 B hex | The Ed25519 key that signs this revision. | | `next_root` | 32 B hex | The commitment (below) to the key that may sign as `root` after this one; never the commitment to `root`. | | `keys` | array | The key entries, below. | -| `revoked_modules` | array of 32 B hex | The SHA-256 digests of the modules and pinned parameter sets the origin has revoked (§7.9), none twice. | +| `revoked_modules` | array of 32 B hex | The SHA-256 digests of the modules and pinned parameter sets the origin has revoked (§7.9), of the room grants and viewers it has revoked ([live-rooms](live-rooms.md) §5), and of the consent records withdrawn in its rooms ([capture-binding](capture-binding.md) §8.3), none twice. | | `grant_max_s` | integer | The longest module grant, in seconds, the origin issues: at least 1 and at most §7.9's ceiling. | | `status_max_age_s` | integer | How long, in seconds, a key status stays fresh: at least 1 and at most §7.9's ceiling. | | `sig` | 64 B hex | `root`'s signature, below. | @@ -3113,6 +3113,8 @@ A confirmation needs every one of them: | the energy figure of a `reconstruct-session` claim whose `energy` is not `null` | `reconstruct-session`, and `energy/` followed by `energy.energy_provenance` | | a receipt of another WAI family that signs its own `signer_pubkey` and `signer_id` | `receipt`; and `energy/` for each class its figures carry a label for | | a module grant (§7.9) | `module/decoder` or `module/reconstruct`, by its `form` | +| a room descriptor or room grant ([live-rooms](live-rooms.md) §3, §4) | `live/room` | +| an upload receipt of a take ([capture-binding](capture-binding.md) §6) | `capture/store` | A class registered in §2.4.4 registers its authority here with it, and a family that needs a narrower authority than `receipt` registers one here. @@ -3209,6 +3211,12 @@ its keys is that party is the origin's decision, and its log records it: names; `module/reconstruct` lets it grant a reconstruct module (§7.9). Neither is pinned-only; §7.8 says what a module authorised under a fetched anchor is. +- **Rooms.** `live/room` lets a key act as a room authority: sign room descriptors and + the grants under them ([live-rooms](live-rooms.md) §5). It is not pinned-only, and it + is not `delivery`. +- **Stores.** `capture/store` lets a key act as a store a room's takes are uploaded to: + sign the upload receipts of a take ([capture-binding](capture-binding.md) §6.4). It is + not pinned-only, and it is not `delivery`. - **Pre-emption** ([unidirectional-delivery](unidirectional-delivery.md) §3), relay attestation (§4.3) other than a `delivery-gap` claim, and reconciliation have no class and so no authority. When one is registered for pre-emption it is pinned-only, @@ -3233,6 +3241,10 @@ its keys is that party is the origin's decision, and its log records it: - **A module or a pinned parameter set** is revoked by adding its digest to `revoked_modules` (§7.9). A revocation, like a key's, stays in every later revision. +- **A room grant or a viewer** is revoked by adding the grant's digest, or the viewer's + tag, to `revoked_modules` ([live-rooms](live-rooms.md) §5); **a consent record** is + withdrawn by adding its digest there ([capture-binding](capture-binding.md) §8.3). The + list holds digests of each kind under one rule: append-only, none twice. - **The root** is pre-committed: each revision commits to the next root, and only a rotation changes the commitment. Whoever steals the root key in use can sign revisions that add keys, but can neither rotate nor diff --git a/wai/extensions/live-events.md b/wai/extensions/live-events.md new file mode 100644 index 000000000..270ad3c5a --- /dev/null +++ b/wai/extensions/live-events.md @@ -0,0 +1,675 @@ +# WAI Extension: Live Events + +> Status: Draft. Registers the record `wai.live.events`: a signed, timeline-bound event +> track. Timed metadata, ad and chapter cues, chat, reactions, polls, markers, +> remote-control commands, captions, moderation decisions and room lifecycle are all +> *events*, and an event is one record, `WEV1`: signed by its principal, hash-chained to +> that principal's previous event, stamped with the room clock, and optionally anchored to +> one media object. The same bytes ride an MSF event timeline over MoQ, an +> `EXT-X-DATERANGE` tag, a CMAF `emsg` box, a WebRTC data channel and a recording. No new +> transport: WAI defines none by charter, and this extension does not change that. Field +> semantics and rules over them only. The reference implementation is the `live_events` +> module of `wai-rs` (feature `live_events`); the corpus is +> [`live-conformance/events/`](../live-conformance/events/), and its second implementation +> is `live-conformance/live_events_verify.py`. +> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174. +> +> Drafts read for this revision: `draft-ietf-moq-msf-01` (MSF), +> `draft-wilaw-moq-scte35-event-timeline-00`, `draft-wilaw-moq-webvtt-msf-00`, +> `draft-jennings-moq-mocha-chat-00` and `draft-jennings-moq-mocha-reactions-00`, all +> Internet-Drafts, none past Working Group Last Call; with RFC 8216 §4.3.2.7 and AOM +> id3-emsg v1.0.0. A section number of one of those drafts in this text is that +> revision's. + +## 1. Scope + +In scope: the event record and its digest and signature (§3); the kinds and their +payloads (§4); the event policy a verifier holds each principal to (§5); verification of +one record and of each principal's chain, with a delivery gap told apart from corruption +(§6); poll tallies as `wai.feed.state` cells (§7); and the field mappings onto MoQ, LL-HLS, +CMAF and DASH, WebRTC and a recording, with what a subscriber joining mid-stream receives +(§8). + +Out of scope: a transport; the room descriptor, which fixes a room's id and its clock, and +the room grant, which carries a principal's policy (both belong to a later extension); +the contents of a `take_commit` (§4.12), which [capture binding](capture-binding.md) +§5 defines; moderation +workflow; and how a sink renders any event. + +Relationship to the core spec: `wai.live.events` is a **record** ([SPEC](../SPEC.md) §5): +a signed record a WAI tool emits and verifies. It names no payload format and is not +dispatchable. + +## 2. Terms + +- **Room**: a multi-party live session. Its id is 32 bytes. The room extension defines it + as the digest of the signed room descriptor; here it is opaque, and a verifier is given + it. +- **Room clock**: microseconds since the room's `t0`, a UTC instant the room fixes. A + binding that needs a wallclock is given `t0` as microseconds since 1970-01-01T00:00:00Z; + one that needs a media time is given the presentation time of `t0`. +- **Principal**: an Ed25519 public key (RFC 8032), 32 bytes. Its `did:key` form names the + same key. +- **Event**, **record**: one `WEV1` (§3). +- **Chain**: one principal's events in one room, ordered by `seq`. +- **Head**: the event of a chain a verifier accepted last. +- **Stream order**: the order in which a verifier is offered one principal's records. Each + binding says what it is (§8). + +## 3. The event record + +### 3.1 Layout + +Integers are little-endian. + +| offset | size | field | meaning | +|---|---|---|---| +| 0 | 4 | `magic` | `WEV1` (ASCII) | +| 4 | 1 | `version` | 1 in this revision | +| 5 | 32 | `room` | the room's id | +| 37 | 32 | `principal` | the author's Ed25519 public key | +| 69 | 8 | `seq` | u64: the event's position in its chain, from 0 | +| 77 | 32 | `prev` | the digest (§3.2) of the chain's event `seq − 1`; 32 zero bytes when `seq` is 0 | +| 109 | 8 | `t` | u64: the room clock at the event | +| 117 | 1 | `anchor_flag` | 0: no anchor; 1: an anchor follows | +| 118 | 48 | `anchor` | only when `anchor_flag` is 1: `track` (32 bytes), `group` u64, `object` u64 | +| *a* | 1 | `kind` | §4 | +| *a* + 1 | 2 | `payload_len` | u16 | +| *a* + 3 | `payload_len` | `payload` | §4 | +| *a* + 3 + `payload_len` | 64 | `sig` | §3.2 | + +*a* is 118 without an anchor and 166 with one. + +An **anchor** binds an event to one MoQ object, so that a marker, a cue or a caption lands +on an exact frame. `track` is SHA-256 over the track's namespace as its MSF catalog entry +has it (its own, or the catalog track's that it inherits, MSF §5.2.2), one zero byte, and +the track's name; `group` and `object` are the object's MOQT Group ID and Object ID. An +anchor names an object on MoQ; the other bindings carry it unchanged. + +`payload_len` lets a payload be up to 65535 bytes, the format's limit; the bound a +verifier applies is the policy's `max_payload` (§5). + +### 3.2 Digest and signature + +The **digest** of an event is SHA-256 (FIPS 180-4) over its record from `magic` through +`payload`: every byte but `sig`. It is written as 64 lowercase hexadecimal digits. An event +is named by its digest wherever another event refers to it: `prev`, a vote's poll, a +reaction's or a decision's target. + +The **signature** is Ed25519 (RFC 8032, pure Ed25519) by `principal`, over the 15 bytes +`wai:live-event` (ASCII) and 0x01, followed by the bytes the digest covers. It is verified +strictly, as [SPEC](../SPEC.md) §7 *Signatures* requires: a key that fails step 1 or 2 is +`bad_key`, and a signature that fails a later step is `bad_signature`. + +### 3.3 Reading a record + +A reader reads exactly the bytes it is given as one record, in the order of §3.1, and +refuses at the first of these that holds: + +1. Fewer than 4 bytes: `truncated`. A magic other than `WEV1`: `malformed`. +2. No byte after the magic: `truncated`. A version other than 1: `unknown_version`. A + reader reads no further field, since a later version's layout is its own. +3. The bytes end before a field the layout requires: `truncated`. An `anchor_flag` other + than 0 or 1, when it is read: `malformed`. +4. Bytes after `sig`: `malformed`. + +## 4. Kinds and payloads + +| code | kind | payload | +|---|---|---| +| `0x01` | `meta` | §4.2 | +| `0x02` | `cue` | §4.3 | +| `0x03` | `chat` | §4.4 | +| `0x04` | `reaction` | §4.5 | +| `0x05` | `poll_open` | §4.6 | +| `0x06`, `0x07` | `vote`, `poll_close` | §4.7 | +| `0x08` | `marker` | §4.8 | +| `0x09` | `control` | §4.9 | +| `0x0A` | `caption` | §4.10 | +| `0x0B` | `decision` | §4.11 | +| `0x0C` | `take_commit` | §4.12 | +| `0x10`–`0x16` | `join`, `leave`, `publish`, `unpublish`, `grant_exchange`, `takeover`, `failover` | §4.13 | + +No other code is defined in this revision; a record of another kind is refused +`unknown_kind` (§6.1). Codes `0x17` to `0x1F` are reserved for lifecycle kinds. + +A payload is read in the order its fields are written, and each field's rule applies when +it is read. A payload that ends before a field, that holds bytes after its last field, or +whose field holds a value this section does not allow, is `malformed_payload`; a text +field's own rules are §4.1's. Integers are little-endian. A digest field is 32 bytes. + +### 4.1 Text + +A text field is a u16 length followed by that many bytes. Its rules, in order: + +1. The bytes are UTF-8 (RFC 3629): no overlong form, no surrogate, nothing above U+10FFFF. + Otherwise `bad_utf8`. +2. They hold at most the policy's `max_text_cp` code points (§5; 500 by default). + Otherwise `text_too_long`. + +Each text field is bounded on its own. Empty text is allowed. + +### 4.2 `meta` + +Opaque application metadata: the whole payload, read for its length alone. It is the timed +metadata a player hands to its application. + +### 4.3 `cue` + +| field | size | meaning | +|---|---|---| +| `type` | u8 | 1 out (leave the program for a break), 2 in (return to it), 3 chapter, 4 break (out and back, its duration known) | +| `cue_id` | u32 | ties an out to its in; an SCTE-35 `splice_event_id` where the message has one | +| `duration_ms` | u32 | out and break: the planned duration; in: the actual duration since its out; chapter: its length; 0 when not known | +| `form` | u8 | 0: no SCTE-35 message; 1: an SCTE 35-1 `splice_info_section()`; 2: an SCTE 35-2 event-based signaling message | +| `scte_len` | u16 | only when `form` is not 0 | +| `scte` | `scte_len` | the message, verbatim | + +Form 1 is read only as far as this: `table_id` is 0xFC, and `section_length` (the low 12 +bits of bytes 1 and 2) plus 3 is `scte_len`. WAI reads no command, descriptor or CRC of +it. Form 2 is at least one byte, carried opaque. A `type` or `form` not in the table is +`malformed_payload`. The summary (`type`, `cue_id`, `duration_ms`) is what a sink acts on +without parsing SCTE-35. Where a message is carried too, both describe one splice, and a +producer **MUST NOT** write a summary its message contradicts. + +### 4.4 `chat` + +One text field: the message. + +### 4.5 `reaction` + +| field | size | meaning | +|---|---|---| +| `type` | u8 | 1 emoji, 2 vote, 3 raise, 4 applause, 5 custom: the reaction types of `draft-jennings-moq-mocha-reactions-00` §4.4 | +| `value` | u16 | not 0: for emoji and raise, that draft's §4.5 integer encodings; for the others, the application's | +| `flags` | u8 | bit 0: a target follows; bit 1: this retracts the reaction it repeats; every other bit 0 | +| `target` | 32 | only when bit 0 is set: the digest of the event reacted to | + +A reaction without a target is **standalone**. Standalone reactions are held to the +policy's reaction rate (§6.3), as that draft holds them to one per second per device +(§5.1 there). A room's polls use `poll_open` and `vote`, not reaction type 2. + +### 4.6 `poll_open` + +`question` (text), `n` (u8, at least 2), then `n` option texts. A poll is named by the +digest of its `poll_open`. + +### 4.7 `vote` and `poll_close` + +- `vote`: `poll` (a poll's digest), `option` (u8). +- `poll_close`: `poll`, `n` (u8, at least 2), then `n` counts (u32 each): the author's + statement of the final tally. + +§7 says which votes count, which `poll_close` closes a poll, and when a stated tally is +checked. + +### 4.8 `marker` + +| field | size | meaning | +|---|---|---| +| `taxonomy` | u32 | what the marker observes, in the application's taxonomy | +| `polarity` | u8 | 0 neutral, 1 positive, 2 negative | +| `text` | text | a note | +| `has_attachment` | u8 | 0 or 1 | +| `attachment` | 32 | only when `has_attachment` is 1: a digest naming an attached object, such as a voice note sealed as a WAI envelope ([jwp-receipts](jwp-receipts.md) §2.1 content hash) | + +### 4.9 `control` + +`target` (the principal the command is for), `command` (u8), then the command's argument: + +| `command` | name | argument | +|---|---|---| +| 1 | `record_start` | `count_in_ms` u32: recording starts this long after `t` | +| 2 | `record_stop` | none | +| 3 | `zoom` | `q16` u32: the zoom factor in Q16.16, not 0 | +| 4 | `mute` | `on` u8: 1 mute, 0 unmute | +| 5 | `layer_request` | `layer` u8: the layer asked for | + +A control event takes effect at its `t` on the room clock, so a count-in lines up for every +participant. Whether the target acts on it is the target's; the event records that it was +asked, by whom and when. + +### 4.10 `caption` + +| field | size | meaning | +|---|---|---| +| `duration_ms` | u32 | how long the caption shows; 0 when not known | +| `origin` | u8 | 1 human, 2 machine, 3 machine-reviewed | +| `model` | 32 | only when `origin` is 2 or 3: a digest naming the model that produced the text | +| `lang_len` | u8 | | +| `lang` | `lang_len` | a BCP 47 language tag (RFC 5646), in ASCII | +| `text` | text | the caption | + +`lang` is read here only as far as this: 2 to 35 characters; a first subtag of 2 to 8 +letters; then subtags of 1 to 8 letters or digits, each after one hyphen. A tag that fails +is `malformed_payload`. `origin` is the event's machine-generation disclosure: a sink that +labels machine-generated content, in its player, in a playlist characteristic or in a +provenance assertion, takes the label from it. + +### 4.11 `decision` + +`verdict` (u8: 1 allow, 2 deny, 3 redact), `target` (the digest of the event decided on), +`reason` (u16: a reason code the room defines). A decision is an event of the principal +that decided, and the target stays in its chain unchanged. A sink **SHOULD NOT** show +content a decision of a principal the room authorises to moderate denies or redacts. + +### 4.12 `take_commit` + +Read here for its length alone, which `max_payload` bounds: a room's verifier carries it +opaque. [Capture binding](capture-binding.md) §5 defines its contents, a device's rolling +commitment to the master it is capturing, and a take verifier reads them. + +### 4.13 Lifecycle + +| code | kind | +|---|---| +| `0x10` | `join` | +| `0x11` | `leave` | +| `0x12` | `publish` | +| `0x13` | `unpublish` | +| `0x14` | `grant_exchange` | +| `0x15` | `takeover` | +| `0x16` | `failover` | + +Payload: `subject` (the principal the event is about), then `detail`, the rest of the +payload, opaque in this revision: a track name, or the digest of a grant. The room +extension defines `detail` for each kind. A room authority, or a relay acting for it, +authors these; the default policy permits them to no one (§5). + +## 5. The event policy + +An event policy states what one principal may send. A verifier holds every principal to a +policy: a default one, and one of the principal's own where it has one. In this revision +the verifier's caller gives it the policies. The room grant of a later extension carries +these same fields, per principal. + +The policy record, `WEP1`, is 65 bytes; integers are little-endian. + +| offset | size | field | meaning | default | +|---|---|---|---|---| +| 0 | 4 | `magic` | `WEP1` (ASCII) | | +| 4 | 1 | `version` | 1 in this revision | | +| 5 | 32 | `kinds` | kind *k* is permitted when bit *k* mod 8 of byte *k* div 8 is set | every kind of §4 but the lifecycle kinds | +| 37 | 2 | `max_payload` | the longest payload, in bytes | 1024 | +| 39 | 2 | `max_text_cp` | the most code points in one text field | 500 | +| 41 | 4 | `max_events` | the most events in one window (§6.3) | 50 | +| 45 | 8 | `window_us` | the window, in microseconds of room clock | 1 000 000 | +| 53 | 4 | `max_reactions` | the most standalone reactions in one reaction window | 1 | +| 57 | 8 | `reaction_window_us` | the reaction window | 1 000 000 | + +A reader refuses a policy record: with fewer than 4 bytes, `truncated`; with another magic, +`policy_malformed`; with no version byte, `truncated`; with another version, +`unknown_version`; shorter than 65 bytes, `truncated`; longer, `policy_malformed`; that +permits a kind §4 does not define, or in which any bound is 0, `policy_malformed`. + +Every bound this extension gives a number for is one of these defaults, and a room +**MAY** set any other. A room authority's policy is the default with the lifecycle kinds +also permitted. + +## 6. Verification + +A verifier verifies one room's records, against the room id it is given. It is offered +records one at a time, each principal's in stream order. A record it refuses changes +nothing it holds. + +### 6.1 One record + +In this order; the first check that fails names the refusal: + +1. The record reads (§3.3): `truncated`, `malformed` or `unknown_version`. +2. Its `kind` is one §4 defines: otherwise `unknown_kind`. +3. Its `room` is the verifier's room: otherwise `wrong_room`. +4. Its signature verifies (§3.2): otherwise `bad_key` or `bad_signature`. +5. Its principal's policy permits its kind: otherwise `kind_not_permitted`. +6. `payload_len` is at most the policy's `max_payload`: otherwise `payload_too_large`. +7. Its payload reads (§4), with the policy's `max_text_cp`: otherwise `malformed_payload`, + `bad_utf8` or `text_too_long`. + +### 6.2 A principal's chain + +For each principal the verifier keeps the digests of the events it holds, by `seq`, and +the chain's head. For a record that passed §6.1: + +1. If the verifier holds an event with this `seq` and this digest, the record is a + **duplicate**: it is ignored, counted nowhere, and checked no further. The records a + group repeats at its start (§8.2) are duplicates to a subscriber that holds them. +2. With a head: + - `seq` at or below the head's: `seq_replay` when an event with this `seq` is held (a + second, different event claims a `seq` already used), and `seq_not_increasing` + otherwise (it arrives behind the head); + - `seq` one above the head's: `prev` **MUST** be the head's digest, otherwise + `chain_broken`; + - `seq` more than one above the head's: the seqs between are a gap; + - in each of the last two cases, `t` **MUST NOT** be below the head's `t`, otherwise + `time_reversed`. +3. Without a head, the first record of the principal the verifier accepts: when `seq` is + 0, `prev` **MUST** be 32 zero bytes, otherwise `chain_broken`; when `seq` is above 0, + seqs 0 to `seq − 1` are a gap. + +Then §6.3. An event accepted becomes the head, and a gap it opens is recorded. + +A gap is a **detectable delivery gap**, reported with the code `delivery_gap`. The +verifier knows exactly which seqs it does not hold, and that the events it does hold are +the principal's, in order. A gap is not a refusal, and a verifier **MUST NOT** report it as +corruption. A receiver **MAY** fill a gap by fetching the events it lacks (MOQT FETCH of +earlier groups, or a recording) and verifying the chain again from its start. It **MUST +NOT** splice an event behind its head into a chain it has moved past: that record is +refused `seq_not_increasing`, by step 2. + +### 6.3 Rates + +Over the events of the principal the verifier has accepted (a duplicate or a refused +record is not counted): + +1. Counting this event, more than `max_events` events whose `t` is less than `window_us` + before this event's `t`: `rate_exceeded`. +2. For a standalone reaction (§4.5), counting it, more than `max_reactions` standalone + reactions whose `t` is less than `reaction_window_us` before its `t`: + `rate_exceeded`. + +An earlier event at `t_f` is within a window `w` of an event at `t` when `t − t_f < w`: +two events exactly one window apart do not share one. A verifier with a gap counts only +what it holds; one that holds the whole chain checks the rate exactly. + +### 6.4 Outcomes + +Verifying a sequence of records gives one outcome: + +- **refuse**: the reason and the index of the first record refused. The verifier stops + there. +- **gap**: no record was refused, and the verifier does not hold every seq of every chain + it saw. It states each gap as the principal and the first and last seq it lacks, in the + order found, under the code `delivery_gap`. +- **accept**: no record was refused, there is no gap, and every stated tally equals the + replay (§7). A stated tally that does not is **refuse**, `tally_mismatch`, at the index + of its `poll_close`. + +## 7. Polls replay as feed state + +A poll's tally is a record of `wai.feed.state` cells ([state-feeds](state-feeds.md)): the +state an op log of `wai.world.sim.feed0` replays to. A tally is therefore +replay-equivalent, and a tally an author states is checkable. + +Over the events a verifier accepted: + +- A **poll** is a `poll_open`. Its **close** is the `poll_close` naming it with the lowest + `seq` among those its author wrote. A `poll_close` by any other principal closes + nothing. +- A `vote` **counts** when the verifier holds its poll, its `option` is below the poll's + `n`, its `t` is at or after the `poll_open`'s `t`, and the poll has no close or the + vote's `t` is before the close's `t`. +- A principal's vote in a poll is its last vote that counts, by `seq`; an earlier one is + replaced. + +The feed: each poll is the node `mint_node_id(author, seq)` of its `poll_open` +([interactive-worlds](interactive-worlds.md) §5.4), whose record is the `Int` cells +`state, count_0, …, count_{n−1}`. Its ops are: + +- `CREATE` with `Int(1)` and `n` cells `Int(0)`, the actor the poll's author and the + Lamport counter the `poll_open`'s `seq`; +- `ADD_INT(1 + option, 1)` for each principal's vote; +- `SET_CELL(0, Int(0))` when the poll has a close. + +Every verifier derives these ops from signed events; they are not sent and not signed. A +vote one principal changes is, equally, `ADD_INT −1` on the old option and `+1` on the new, +and the replay reaches the same state. The tally's state hash is feed0's, +`BLAKE3("wai:world-state\x01" ‖ canonical state bytes)` ([state-feeds](state-feeds.md) +§4), over every poll the verifier holds. + +A `poll_close`'s counts are its author's statement. A verifier that holds every chain +whole (no gap) checks each close: its `n` equals the poll's, and each count equals the +votes for that option. Otherwise it refuses with `tally_mismatch`, at the lowest index of +such a close. With a gap a verifier does not make this check: a tally it computes is +unchecked. + +## 8. Bindings + +Field semantics only. Each binding says how the record is carried, what it derives from +the record, its stream order (§6), and how a reader refuses what it cannot read +(`binding_malformed`) or what disagrees with the record it carries (`binding_mismatch`). +The record a reader takes from a binding is then verified by §6. + +### 8.1 MoQ: an MSF event timeline + +- Each principal publishes its events on a track of its own, as + `draft-jennings-moq-mocha-chat-00` §3.3 has each device publish on its own track. A + chain and a track are then one unit, and a relay fans tracks out without merging them. + The room extension names the tracks. +- The track is an MSF event timeline (MSF §8). Its catalog entry has `packaging` + `"eventtimeline"` (MSF §5.2.4), `eventType` `"urn:wai:event:1"` (MSF §5.2.5), `mimetype` + `"application/json"`, and `depends` naming the tracks its anchors name (MSF §8.2). +- A **record** of the timeline (MSF §8.1) has one index member and `data`: + - an anchored event whose `group` and `object` are each at most 2^53 − 1 has + `"l": [group, object]`, the MOQT Location of the anchored object; + - any other event has `"t"`: `⌊(t0 + t) / 1000⌋`, the wallclock in milliseconds since + 1970 (MSF §7.1.1), which **MUST** be at most 2^53 − 1; + - `data` is `{"wev1": ""}`, the record in base64url without padding + (RFC 4648 §5). + + It is written `{"t":,"data":{"wev1":""}}` or + `{"l":[,],"data":{"wev1":""}}`, with no whitespace. This binding + never writes `m`: an event has no media timestamp of its own, and an anchor names its + object exactly. An events track uses `t` and `l` record by record, as + `draft-wilaw-moq-scte35-event-timeline-00` §4.2 also does; MSF §8.1's preference for + one index type is a **SHOULD**. +- A reader parses the record as JSON and ignores members this binding does not define. + It refuses as `binding_malformed`: anything but a JSON object; no string `data.wev1`; + one that is not the canonical base64url of its bytes (the RFC 4648 §5 alphabet, no `=`, + and the encoding of what it decodes to); bytes that §3.3 does not read as a record of a + kind §4 defines; and a record with other than exactly one of `t`, `l` and `m`. It refuses + as `binding_mismatch` an index other than the one this binding writes for the event: + `t` a JSON integer equal to the event's, or `l` an array of exactly two integers equal + to its anchor's. +- **Groups.** An event's group is `⌊t / 60 000 000⌋`, the minute of room clock it falls + in, as `draft-jennings-moq-mocha-chat-00` §3.4 groups messages by minute. Group IDs + increase with `t`, since `t` never decreases along a chain. Object 0 of a group is the + independent object of MSF §8.3: a JSON array of the join set (§8.2) at the group's + start. Each event of the group is then the next object, an array of its one record, an + incremental update (MSF §8.3). MSF §8.3 has the independent object hold every record + "accumulated and accessible" so far. For an events track the records accessible at a + group boundary are its join set; earlier records stay reachable by FETCH of earlier + groups. +- **Stream order** is Location order: by group, then by object, and the records of one + object in the order written. +- **Cues.** A publisher **MAY** also publish each cue of form 1 on a timeline of + `draft-wilaw-moq-scte35-event-timeline-00`, its `scte35_payload` the base64 (RFC 4648 + §4) of the cue's section and its index chosen by that draft's §4.2, so that a consumer + of SCTE-35 alone reads it unchanged. That draft registers the event type + `urn:scte:scte35:2022:bin`, and MSF §14.2's initial table spells it + `urn:scte:scte35:2013:bin`; this revision takes no position between the two. +- **Captions.** A publisher **MAY** also publish each caption as a cue of + `draft-wilaw-moq-webvtt-msf-00` on a timeline of its own. This revision defines no + mapping between the two. +- **Registration.** WAI requests `urn:wai:event:1` in the "MSF Event Timeline Types" + registry (MSF §14.2, Expert Review). The URN is the form of that registry's entries, + and it is also this extension's `emsg` scheme (§8.4). Until it is registered it is a + custom type in MSF §10.5's sense. + +### 8.2 Joining mid-stream + +The **join set** of a principal's track at the start of group *g* (room clock *g* × 60 s) +is drawn from the principal's events whose `t` is before that instant. In `seq` order it +holds: + +- every `poll_open` whose poll has no `poll_close` of its author before the instant + (**MUST**); +- in each of those polls, the principal's last vote (**MUST**); +- every `caption` with a `duration_ms` above 0 whose interval, `t` to + `t + duration_ms`, contains the instant (**MUST**); +- every `cue` of type out or break with no later `in` of the same `cue_id` (**MUST**); +- any other event (**MAY**). + +The records are repeated byte for byte, so each is a duplicate (§6.2 step 1) to a +subscriber that holds it and the state a joining subscriber starts from. This is how +`draft-wilaw-moq-webvtt-msf-00` §5 has the first object of each group carry the cues +accumulated so far. A subscriber that joins verifies from the first record it holds and +reports what it lacks as gaps (§6.2), so it knows a tally it computes is unchecked. It +learns a final tally from the poll author's `poll_close`, or checks one by fetching the +voters' earlier groups. + +### 8.3 LL-HLS: `EXT-X-DATERANGE` + +An event in a Media Playlist is one `EXT-X-DATERANGE` tag (RFC 8216 §4.3.2.7, which +low-latency HLS keeps). Its attributes are written in this order, separated by commas with +no spaces: + +| attribute | when | value | +|---|---|---| +| `ID` | always | quoted: the event's digest, 64 lowercase hexadecimal digits | +| `CLASS` | always | quoted: `science.transaction.wai.event` | +| `START-DATE` | always | quoted: `t0 + t` as `YYYY-MM-DDTHH:MM:SS.mmmZ`, in UTC, the milliseconds floored, always three digits after the point | +| `DURATION` | a cue of type in or chapter, or a caption, with `duration_ms` above 0 | `duration_ms` as decimal seconds with three digits after the point (`30.000`) | +| `PLANNED-DURATION` | a cue of type out or break with `duration_ms` above 0 | as `DURATION` | +| `SCTE35-OUT`, `SCTE35-IN`, `SCTE35-CMD` | a cue of form 1 | `0x` and the section in uppercase hexadecimal: `SCTE35-OUT` for out and break, `SCTE35-IN` for in, `SCTE35-CMD` for chapter (RFC 8216 §4.3.2.7.1) | +| `X-WAI-EVENT` | always | quoted: the record in base64url without padding | + +- RFC 8216 §4.3.2.7.1 represents a splice out/in pair with tags that share one `ID`. Here + each tag carries an event of its own under its own `ID`, because two tags of a playlist + that share an `ID` must agree on every attribute both carry, and their `X-WAI-EVENT` + values differ. `cue_id` ties the pair. +- RFC 8216 asks a client attribute's name to follow reverse-DNS form. `X-WAI-EVENT` + appears only under its `CLASS`, whose semantics every date range of that class follows + (RFC 8216 §4.3.2.7). +- A playlist that carries one of these tags **MUST** carry `EXT-X-PROGRAM-DATE-TIME` + (RFC 8216 §4.3.2.7), on the same UTC timeline as `t0`. +- **Stream order** is the order of the tags in the playlist, across its updates. +- A reader takes the tag as `#EXT-X-DATERANGE:` and an attribute list (RFC 8216 §4.2): + attribute names of `A`–`Z`, `0`–`9` and `-`, each at most once, and a quoted value that + runs to the next quote. It refuses as `binding_malformed`: another tag; an attribute list + that does not read; no `X-WAI-EVENT`, one not quoted, or one that is not canonical + base64url (§8.1); and bytes that §3.3 does not read as a record of a kind §4 defines. It + then renders the tag for that record and refuses as `binding_mismatch` unless each + attribute of the table above is, in the tag and in the rendering, either absent from + both or present in both with the same value as written. Attributes the table does not + name are ignored, and their order is not compared. + +### 8.4 CMAF and DASH: `emsg` version 1 + +An event is one Event Message box, version 1 (ISO/IEC 23009-1, the syntax AOM id3-emsg +v1.0.0 §2.2.2 reproduces). Integers are big-endian: + +| field | value | +|---|---| +| `size` | the box's length in bytes | +| `type` | `emsg` | +| `version`, `flags` | 1, 0 | +| `timescale` | 1000 | +| `presentation_time` | u64: `pt0 + ⌊t / 1000⌋`, where `pt0` is the presentation time of `t0` in milliseconds on the track's timeline | +| `event_duration` | a cue or a caption: `duration_ms`, or 0xFFFFFFFF (not known) when it is 0; any other kind: 0 | +| `id` | the first four bytes of the event's digest, as a u32 | +| `scheme_id_uri` | `urn:wai:event:1`, then a zero byte | +| `value` | the kind's name (§4), then a zero byte | +| `message_data` | the record | + +- `id` lets a player drop a box it has seen. A receiver identifies an event by its digest + (§6.2), since four bytes of a digest can repeat. +- **Stream order** is presentation order: the order of the boxes in the segments, by + `presentation_time`, and within one time in the order the segment holds them. +- A reader refuses as `binding_malformed`: a box shorter than 32 bytes, whose `size` is + not its length, whose type is not `emsg` or whose version is not 1; a box without two + strings each ended by a zero byte; and `message_data` that §3.3 does not read as a + record of a kind §4 defines. It then renders the box for that record and refuses as + `binding_mismatch` unless the two are equal byte for byte. +- A publisher whose players surface only ID3 timed metadata **MAY** also carry the record + in ID3 as AOM id3-emsg v1.0.0 has it (scheme `https://aomedia.org/emsg/ID3`). This + revision defines no ID3 frame for it. + +### 8.5 WebRTC + +A data channel (RFC 8831), reliable and ordered, with binary messages. One message is one +record, whole. **Stream order** is message order. A sink that needs an event's media time +takes it from the anchor or from the room clock; the RTP absolute capture time header +extension, where a sender adds it, is experimental. + +### 8.6 Recording + +A recording holds each principal's chain whole: its records concatenated in `seq` order, +each record's length following from its own fields (§3.1). **Stream order** is that order. +In a sealed package the events are one component; packaging them is the recording +extension's, a later one. A recording verifies with the outcome accept, or states its gaps. + +## 9. Reasons + +| reason | raised at | +|---|---| +| `truncated` | §3.3, §5 | +| `malformed` | §3.3 | +| `unknown_version` | §3.3, §5 | +| `unknown_kind` | §6.1 step 2 | +| `wrong_room` | §6.1 step 3 | +| `bad_key` | §3.2, §6.1 step 4 | +| `bad_signature` | §3.2, §6.1 step 4 | +| `kind_not_permitted` | §6.1 step 5 | +| `payload_too_large` | §6.1 step 6 | +| `malformed_payload` | §4, §6.1 step 7 | +| `bad_utf8` | §4.1 | +| `text_too_long` | §4.1 | +| `seq_replay` | §6.2 step 2 | +| `seq_not_increasing` | §6.2 step 2 | +| `chain_broken` | §6.2 steps 2 and 3 | +| `time_reversed` | §6.2 step 2 | +| `delivery_gap` | §6.2, §6.4: a gap, not a refusal | +| `rate_exceeded` | §6.3 | +| `tally_mismatch` | §7 | +| `policy_malformed` | §5 | +| `binding_malformed` | §8.1, §8.3, §8.4 | +| `binding_mismatch` | §8.1, §8.3, §8.4 | + +## 10. Conformance + +[`live-conformance/events/`](../live-conformance/events/) holds the corpus, in one file, +`vectors.json`, written from fixed seeds by `wai_live_events_vectors gen`. It has: + +- **vectors**: a room, the policies its principals are held to, and records in stream + order, with the outcome §6.4 gives them. An accepted vector also states each record's + digest, the tally (§7) and each record's MSF record, `EXT-X-DATERANGE` tag and `emsg` + box (§8); a vector with a gap states its gaps. Every kind has an accepted vector, and + chains of several principals are interleaved in one. Every refusal of §6 has a vector + refused with it, each a control of one defect: a flipped signature bit and three + forgeries that a lenient Ed25519 verifier accepts, a broken chain, a reorder, a replayed + `seq`, `t` going back, an oversize payload, a kind not permitted, both rates exceeded, + invalid UTF-8 and overlong text, truncated and malformed records, an unknown version and + kind, the wrong room, malformed payloads and a stated tally the replay does not reach. +- **policy cases**: policy records, read (§5) or refused with their reason. +- **binding cases**: tags, boxes and MSF records, read back to their record (§8) or + refused with their reason. + +A conforming verifier gives every vector, policy case and binding case the outcome, the +reason, the index, the gaps, the digests, the tally and the renderings the corpus states. +`wai_live_events_vectors verify` and the test `tests/live_events.rs` check that the file +regenerates byte for byte and that `wai-rs` gives every case its outcome. +`live-conformance/live_events_verify.py` is the second implementation, written from this +text: it shares no code with `wai-rs`, verifies signatures with WAI's strict rule written +from RFC 8032 (`claim-conformance/_ed25519.py`) and computes BLAKE3 from its specification +(`claim-conformance/_blake3.py`). It gives every case the same outcome. + +## 11. Security and privacy considerations + +- Every field of an event is signed. A relay can drop an event but cannot alter one, and + a drop is a gap the receiver detects (§6.2). +- `t` is its author's claim. A room clock authority and per-hop receipts, both of later + extensions, witness when an event was seen; this revision checks only that a chain's + `t` never goes back. +- Two different events with one `seq` are refused `seq_replay`. A receiver that holds + both holds two signatures by one key over one position: evidence the author + equivocated. +- Payloads are untrusted data: an SCTE-35 message, `meta`, a lifecycle `detail` and a + `take_commit` are carried, not interpreted, as + `draft-wilaw-moq-scte35-event-timeline-00` §6.2 has SCTE-35 payloads treated. +- The policy's payload, text and rate bounds limit how much one principal can make every + receiver hold and check. +- A principal's events are linkable to one another, since one key signs them all. A room + that needs participation that cannot be linked across rooms gives principals a key per + room. Events persist in recordings, and a `decision` that redacts an event does not + remove it from the chains that hold it (§4.11). +- Confidentiality is the carrying transport's, and end-to-end encryption of tracks is + [confidentiality](confidentiality.md)'s; this extension signs events and does not + encrypt them. + +## Appendix A — Registration request + +For the "MSF Event Timeline Types" registry (MSF §14.2): + +| Event Type | Description | Specification | +|---|---|---| +| `urn:wai:event:1` | WAI live event records (`WEV1`), one per record, in `data.wev1` | this extension | diff --git a/wai/extensions/live-rooms.md b/wai/extensions/live-rooms.md new file mode 100644 index 000000000..b4e6d4edf --- /dev/null +++ b/wai/extensions/live-rooms.md @@ -0,0 +1,799 @@ +# WAI Extension: Live Rooms + +> Status: Draft. Registers the record `wai.live.room`: the signed **room descriptor** +> that fixes a room, its id, its clock and what each role may do; and the signed **room +> grant** under which one principal takes part, carrying the event policy +> [live-events](live-events.md) §5 holds it to. A grant is exchanged for another at a tick +> of the room clock, and revoked through the room authority's key log +> ([jwp-receipts](jwp-receipts.md) §7). Tracks are named in the MoQ namespace tuple; a +> slot lets a publisher of higher precedence take a virtual track over, and a standby +> take it on failover; the publish profiles fix codecs, layers and limits as data. A +> room verifier replays every principal's events under the grant in effect at each +> instant of the room clock. No new transport and no new token format: the grant maps +> onto existing token formats (§10). The reference implementation is the `live_room` +> module of `wai-rs` (feature `live_room`); the corpus is +> [`live-conformance/rooms/`](../live-conformance/rooms/), and its second implementation +> is `live-conformance/live_rooms_verify.py`. +> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174. +> +> Drafts read for this revision: `draft-ietf-moq-transport-22` (MOQT), +> `draft-ietf-moq-msf-01` (MSF), `draft-ietf-moq-c4m-01` and +> `draft-ietf-moq-privacy-pass-auth-03`, all Internet-Drafts, none past Working Group +> Last Call; with RFC 9246, RFC 8392, and CTA-5007-B as the IANA "CBOR Web Token (CWT) +> Claims" registry lists its claims (keys 308 to 323). A section number of one of those +> drafts in this text is that revision's. + +## 1. Scope + +In scope: the room descriptor, its digest (the room id) and signature (§3); the room +grant, its checks, its attributes, how a receipt names it, and its exchange (§4); +revocation through the key log (§5); track naming (§6); precedence and redundancy over +slots, and the `detail` of every lifecycle kind of live-events §4.13 (§7); the publish +profiles (§8); room verification (§9); and the bindings onto token formats (§10). + +Out of scope: a transport; how a principal obtains a grant; composition, which reads the +grant's attributes (a later extension); the review workflow, of which this extension +fixes only the policy's fields and their meaning (§3.6); and what a recording holds, +which the recording policy constrains (§3.7) and later extensions define: a device's +master recording is [capture-binding](capture-binding.md)'s take. + +Relationship to the core spec: `wai.live.room` is a **record** ([SPEC](../SPEC.md) §5): a +signed record a WAI tool emits and verifies. It names no payload format and is not +dispatchable. + +## 2. Terms + +- **Room authority**: the Ed25519 key (RFC 8032) that signs a room's descriptor and its + grants. +- **Clock**: the key, named by the descriptor, that stamps the room clock and authors the + room's lifecycle events for the authority. It **MAY** be the authority's key. +- **Room key**: the authority's key or the clock's. +- **Room clock**, **principal**, **event**, **chain**: as in live-events §2. +- **Grant in effect**: for a present principal, the grant its latest `join` or + `grant_exchange` named (§9.3). +- **Slot**: a virtual track the descriptor declares, which one live publisher stands + behind at a time (§7.1). +- **Name**: 1 to 32 bytes of `a`–`z`, `0`–`9`, `_` and `-`. A **slot name** is 1 to 32 + bytes of `a`–`z`, `0`–`9` and `_`. A **token** is 1 or more bytes of `!` to `~` + (0x21–0x7E). +- **Kinds bitmap**: 32 bytes in which kind *k* is set when bit *k* mod 8 of byte *k* div + 8 is set, as live-events §5 writes `kinds`. + +## 3. The room descriptor + +### 3.1 Layout + +Integers are little-endian. A *short* field is a u8 length and that many bytes; a *long* +field is a u16 length and that many bytes. + +| field | size | meaning | +|---|---|---| +| `magic` | 4 | `WRD1` (ASCII) | +| `version` | 1 | 1 in this revision | +| `authority` | 32 | the room authority's Ed25519 key | +| `clock` | 32 | the clock's Ed25519 key | +| `t0` | 8 | u64: the room's `t0`, in microseconds since 1970-01-01T00:00:00Z | +| `tick` | 8 | u64: the room-clock tick, in microseconds, that a grant exchange takes effect on (§4.6) | +| `origin` | long | the origin whose key log lists the authority (§5); empty for none | +| `max_present` | 4 | u32: the most principals present at once (§3.5) | +| `max_publishers` | 2 | u16: the most principals publishing at once (§7.3) | +| `reval` | 4 | u32: the re-validation interval, in seconds, a token of the room carries (§10.2); 0 for none | +| `ceiling` | 65 | a `WEP1` record (live-events §5): the event ceiling no grant exceeds (§3.5) | +| `roles` | 1 + … | a u8 count, then each role: `name` (short), `publish` (u8), `subscribe` (u8), `max_layer` (u8), `powers` (u8), `events` (32, a kinds bitmap) (§3.3) | +| `slots` | 1 + … | a u8 count, then each slot: `name` (short), `media` (u8), `redundancy` (u8), `failover_ms` (u32) (§7.1) | +| `profiles` | 1 + … | a u8 count, then each publish profile (§8.1) | +| `review` | 37 | `kinds` (32, a kinds bitmap), `deadline_ms` (u32), `fallback` (u8) (§3.6) | +| `recording` | 12 + … | `mode` (u8), `retention_days` (u16), `commit_interval_ms` (u32), `jitter_ms` (u32), then a u8 count and that many 2-byte `regions` (§3.7) | +| `sig` | 64 | §3.2 | + +### 3.2 Digest, room id and signature + +The **digest** of a descriptor is SHA-256 (FIPS 180-4) over its record from `magic` +through `recording`: every byte but `sig`. It is the **room id**, the 32 bytes every event +of the room names (live-events §3.1). + +The **signature** is Ed25519 by `authority` over the 14 bytes `wai:live-room` (ASCII) and +0x01, followed by the bytes the digest covers. It is verified strictly, as +[SPEC](../SPEC.md) §7 *Signatures* requires: a key that fails step 1 or 2 is `bad_key`, +and a signature that fails a later step is `bad_signature`. + +### 3.3 Roles and capability sets + +A **role** maps a name to a **capability set**: + +- `publish`: bit *m* − 1 for each media kind *m* the role may publish: 1 `audio`, 2 + `video`, 3 `screen` (§6.1). +- `subscribe` (0 or 1) and `max_layer`: whether the role may subscribe, and the highest + layer (§6.3) it may subscribe to; 0 when it may not subscribe. +- `events`: the event kinds it may send, a kinds bitmap within the ceiling's `kinds`. +- `powers`: bit 0 **moderate** (its `decision` events, live-events §4.11, are a + moderator's), bit 1 **direct** (it may send `control` commands other than recording), + bit 2 **compose** (it may author the room's composition, a later extension), bit 3 + **record** (it may send `record_start` and `record_stop`). + +A role whose `events` permit `decision` has the moderate power; one whose `events` permit +`control` has direct or record. A grant narrows its role's set and never widens it +(§4.3). + +### 3.4 Reading and field rules + +A reader reads exactly the bytes it is given as one descriptor, in the order of §3.1, and +refuses at the first of these that holds: + +1. Fewer than 4 bytes: `truncated`. A magic other than `WRD1`: `malformed`. No byte after + the magic: `truncated`. A version other than 1: `unknown_version`. +2. The bytes end before a field the layout requires: `truncated`. +3. Bytes after `sig`: `malformed`. + +It then holds the descriptor to these rules, and refuses one that breaks any of them as +`descriptor_invalid`: + +- `tick` is above 0; `origin` is empty or a token of at most 255 bytes; `max_present` and + `max_publishers` are above 0. +- `ceiling` is a policy live-events §5 reads, and it permits no lifecycle kind (`0x10` to + `0x1F`). +- There are 1 to 16 roles, each named by a name no other role has, with `subscribe` 0 or + 1, `publish` setting no bit above bit 2, `powers` none above bit 3, `max_layer` 0 when + `subscribe` is 0, `events` within the ceiling's `kinds`, and the powers §3.3 requires + of its `events`. +- There are at most 16 slots, each named by a slot name no other slot has, of a media + kind of §6.1, with `redundancy` 1 and `failover_ms` 0, or `redundancy` 2 and + `failover_ms` above 0. +- There are at most 16 profiles, each meeting §8.1 and named by a name no other profile + has. A profile whose name §8.2 registers is that registered profile, field for field. +- The review policy and the recording policy meet §3.6 and §3.7. + +Then the signature (§3.2): `bad_key` or `bad_signature`. + +### 3.5 Limits + +- `max_present`: a `join` that would make more principals present than this is refused + `participant_limit` (§7.2). +- `max_publishers`: §7.3. +- `ceiling`: no grant's policy exceeds it (§4.3 step 8): its `max_payload`, `max_text_cp`, + `max_events` and `max_reactions` are at most the ceiling's, and its `window_us` and + `reaction_window_us` at least the ceiling's, so every window of the ceiling's length + holds no more events than the ceiling allows. The ceiling's `kinds` bound the roles'. + +### 3.6 The review policy + +`kinds` names the event kinds held for review; all zero, nothing is reviewed. An event of +a reviewed kind is shown by a sink only once a principal with the moderate power has sent +a `decision` on it (live-events §4.11), or once `deadline_ms` milliseconds of room clock +have passed after its `t` with none, when the `fallback` verdict applies: 1 allow, 2 deny. +With no reviewed kind, `deadline_ms` and `fallback` are 0; with one, the kinds are within +the ceiling's, `deadline_ms` is above 0, and `fallback` is 1 or 2. This revision fixes the +policy's fields and their meaning; the review workflow and its verification are a later +extension's. + +### 3.7 The recording policy + +- `mode`: 0 the room is never recorded; 1 it is recorded from a `record_start` command + (live-events §4.9) of a principal with the record power; 2 it is always recorded. +- `retention_days`: the most days a recording is kept; 0 states no bound. +- `commit_interval_ms` and `jitter_ms`: how often a device capturing a take commits to it + in the room's events, and the jitter its timing is allowed + ([capture-binding](capture-binding.md) §5, §7). With `mode` 0 both are 0. Otherwise + `commit_interval_ms` is above 0, 2 000 (two seconds) by default, and `jitter_ms` is at + most `commit_interval_ms`, 500 by default. +- `regions`: the **region pin**, for data residency: ISO 3166-1 alpha-2 codes, each two + capitals `A`–`Z`, in ascending order, at most 16. A recording of the room, and the + media and events a relay keeps of it beyond delivery, **MUST** be stored only within + those regions; none means no pin. A recording's receipt states where it is stored; the + recording extension checks it against the pin. + +`mode` is at most 2, and `commit_interval_ms` and `jitter_ms` keep the rule above. + +## 4. The room grant + +### 4.1 Layout + +| field | size | meaning | +|---|---|---| +| `magic` | 4 | `WRG1` (ASCII) | +| `version` | 1 | 1 in this revision | +| `room` | 32 | the room id | +| `principal` | 32 | the Ed25519 key the grant is for | +| `prev` | 32 | the digest of the grant this one is exchanged for (§4.6); 32 zero bytes for a first grant | +| `effective` | 8 | u64: for an exchanged grant, the room-clock tick it takes effect at; 0 for a first grant | +| `nbf`, `exp` | 8 each | u64: seconds since 1970-01-01T00:00:00Z, as RFC 8392's NumericDate: the grant is good from `nbf` until before `exp` | +| `role` | 1 | the index of its role in the descriptor | +| `publish`, `subscribe`, `max_layer`, `powers` | 1 each | its capability set (§3.3), within its role's | +| `precedence` | 1 | its precedence on a slot (§7.1) | +| `once` | 16 | a single-use nonce: when it is not zero, no two `join`s name grants with this `once` (§7.2); zero, the grant may be used again within its window | +| `viewer` | 16 | the viewer id revocation names (§5); zero for none | +| `policy` | 65 | a `WEP1` record (live-events §5): the event kinds it may send, its payload and text bounds, and its rate windows | +| `joules_ceiling` | 8 | u64: the energy its use may spend, in microjoules; 2^64 − 1 for no ceiling | +| `funds_ceiling` | 8 | u64: the funds its use may spend, in minor units of `currency`; 2^64 − 1 for no ceiling | +| `currency` | 3 | ISO 4217 alphabetic code; three zero bytes when there is no funds ceiling | +| `profiles` | 1 + *n* | a u8 count, then the index in the descriptor of each publish profile it publishes with | +| `origins` | 1 + … | a u8 count, then each delivery origin it is good for (short): a URI's scheme and authority, such as `https://relay.example` | +| `attrs` | long | its attributes (§4.4) | +| `sig` | 64 | §4.2 | + +### 4.2 Digest and signature + +The **digest** of a grant is SHA-256 over its record from `magic` through `attrs`. The +**signature** is Ed25519 by the descriptor's `authority` over the 20 bytes +`wai:live-room-grant` (ASCII) and 0x01, followed by the bytes the digest covers, verified +strictly (SPEC §7 *Signatures*). + +### 4.3 Checking the grants + +A verifier is given a room's grants in a list. It checks each in the list's order and +refuses at the first check that fails, naming the grant by its index: + +1. The record reads, as §3.4 steps 1 to 3 read a descriptor with `WRG1` for `WRD1`: + `truncated`, `malformed` or `unknown_version`. +2. Its signature verifies under the descriptor's `authority` (§4.2): `bad_signature`. +3. When `prev` is not zero, it is the digest of a grant earlier in the list + (`exchange_unlinked`), and that grant's `room` and `principal` are this one's + (`exchange_mismatch`). +4. Its `room` is the room id: `wrong_room`. +5. Its fields keep these rules, and `grant_invalid` refuses it otherwise: + - `exp` is above `nbf`; + - a first grant's `effective` is 0, and an exchanged grant's a multiple of the + descriptor's `tick`; + - `role` names a role; `subscribe` is 0 or 1; `publish` sets no bit above bit 2, + `powers` none above bit 3; `max_layer` is 0 when `subscribe` is 0; + - `policy` is a policy live-events §5 reads, permits no lifecycle kind, and the powers + §3.3 requires of its kinds are among `powers`; + - `funds_ceiling` is 2^64 − 1 exactly when `currency` is three zero bytes, and + `currency` is otherwise three capitals `A`–`Z`; + - each entry of `profiles` names a profile of the descriptor, of a media kind the + grant may publish, and no two name profiles of one media kind; + - there are at most 8 `origins`, each a token; + - `attrs` meets §4.4; + - its digest is no earlier grant's. +6. `exp` − `nbf` is at most 1 209 600 seconds, fourteen days: otherwise `grant_too_long`. +7. It is within its role (§3.3): its `publish` and `powers` set no bit its role's do not, + it subscribes only where its role does, its `max_layer` is at most its role's, and its + policy's kinds are within its role's `events`. Otherwise `caps_exceed_role`. +8. Its policy is within the room's ceiling (§3.5): otherwise `grant_exceeds_room`. + +A grant is **good at** room-clock `t` when `nbf` ≤ ⌊(`t0` + `t`) / 10^6⌋ < `exp`. + +### 4.4 Attributes + +`attrs` is a sequence of entries, each a key (a short field holding a slot name) and a +value (a long field holding UTF-8, RFC 3629). Keys are in strictly ascending byte order, +and the entries take at most 1024 bytes, not counting the field's own length. An entry +that runs past the field's end breaks the rule. + +Attributes are for composition: a later extension lays a room out from them. It reads +`featured` (`true` or `false`), `order` (a decimal integer) and `pip` (`true` or +`false`); this revision reads their syntax alone. Capture binding +([capture-binding](capture-binding.md) §3) reads two more: `subject`, the principal a +device captures for, as 64 lowercase hexadecimal digits of its key; and `minor` (`true` +or `false`), whether the authority marks that principal a minor. Attributes are signed with the grant, +so a layout computed from them is computed from what the authority stated. + +### 4.5 How a receipt names a grant + +A receipt that names the grant it was carried under does so with the grant reference +WAI's receipts already carry, the members `grant_hash`, `capability`, +`joule_ceiling_micro` and `funds_ceiling` that a package receipt +([packaging](packaging.md) §9) and a playlist receipt (http-delivery, Appendix H) write: +`grant_hash` is the grant's digest (§4.2), `capability` is `wai.live.room`, +`joule_ceiling_micro` is `joules_ceiling` (2^64 − 1 for no ceiling, as there), and +`funds_ceiling` is `funds_ceiling`, or none when that is 2^64 − 1. The reference carries +no currency; the grant it names does. Every object's receipt so names the grant it was +carried under, and the grant states the ceilings a meter holds that use to. + +### 4.6 Grant exchange + +A principal's grant is **exchanged** for a new grant that is chained to it: the new +grant's `prev` is the old grant's digest, and its `room` and `principal` are the old +one's (§4.3 step 3). The exchange takes effect at the new grant's `effective`, a tick of +the room clock, and is recorded as the clock's `grant_exchange` lifecycle event at that +`t` (§7.2). An exchange can widen what a principal may do (a viewer promoted to publish) +or narrow it, and only the authority can make one, since only it signs grants. + +An exchange **MUST NOT** leave the principal publishing what its new grant does not let +it publish: an authority that narrows a publisher's grant unpublishes first (§7.2). + +## 5. Revocation through the key log + +A room whose descriptor names an `origin` is revocable. Its authority's key is an entry +of that origin's key log ([jwp-receipts](jwp-receipts.md) §7.2) whose `may_sign` holds +the authority `live/room` (jwp-receipts §7.5). Revocation then goes through that log: + +- **A grant** is revoked by adding its digest to the head's `revoked_modules`. +- **A viewer** is revoked by adding its **tag**, SHA-256 over the 17 bytes + `wai:live-viewer` (ASCII) and 0x01 followed by the 16-byte `viewer`, to the same list. + Every grant naming that viewer is revoked with it, in every room whose descriptor names + that origin. +- **The authority** is revoked as any key is (jwp-receipts §7.6): with the key, every + descriptor and grant it signed is refused. + +The list is append-only (jwp-receipts §7.2 rule 6), so a revocation stays. A relay checks +a grant against the key status it holds ([http-delivery](http-delivery.md) §8.4) at +admission and at each re-validation (§10.2), so a grant revoked stops being honoured +within `reval` plus the head's `status_max_age_s` seconds. + +A room verifier is given the **head** the caller reached for the descriptor's origin +(jwp-receipts §7.4 step 3): anchoring the origin and walking its log to the head are the +caller's, and the verifier is a function of the head it is given. When `origin` is +empty, no key log is read, a head given is not read, and nothing is revoked. Otherwise, +in this order: + +1. A head is given: otherwise `key_log_missing`. +2. It is held for `origin`: jwp-receipts §7.2 rules 1 to 3 hold for it. Otherwise + `key_log_not_held`. +3. It has an entry whose `key` is the descriptor's `authority` and whose `may_sign` holds + `live/room`: otherwise `authority_not_listed`. +4. That entry's `status` is not `revoked`: otherwise `authority_revoked`. + +A grant whose digest, or whose viewer's tag, the head's `revoked_modules` lists is +**revoked**. A revocation refuses every use of the grant (§7.2): like a key's, it is not +bounded by a time, since a revoked grant may have been in another party's hands. An +authority that only wants a principal gone from a room removes it with `leave` (§7.2). + +## 6. Track naming + +### 6.1 The Full Track Name + +A track of a room is named by a MOQT Full Track Name (MOQT §2.4.1): + +- its **Track Namespace** is three fields: + 1. the room id, as 64 lowercase hexadecimal digits; + 2. the **owner**: the publishing principal's key as 64 lowercase hexadecimal digits, + or, for a slot (§7.1), `_` followed by the slot's name; + 3. the media kind: `audio` (1), `video` (2) or `screen` (3); or `events` for the + principal's events track (live-events §8.1); +- its **Track Name** is the layer (§6.3) in decimal, with no leading zero: `0`, `1`, …; + the events track's is `0`. + +Every byte of these fields is one of `a`–`z`, `0`–`9` and `_`, so the bytes are their +own canonical form (MOQT §2.4.1) and their rendering in MOQT §8.8's format is themselves: +the fields joined by `-`, then `--` and the name, as +`--video--1`. No field is empty and none begins with `.` (MOQT §2.4.3, +§8.7), and the whole is 64 + 64 + 6 + 3 bytes at most, within MOQT §8.7's limit. + +The layer is the Track Name, and not a fourth namespace field, because +[moq-streaming-format](moq-streaming-format.md) §4.1 has the tracks of a staged set share +one namespace. Namespace prefix matching (MOQT §2.4.2) on the first field reaches every +track of a room; on the first two, every track of one publisher or slot. + +### 6.2 The catalog + +A publisher's MSF catalog entry for a track carries its `namespace` (MSF §5.2.2) as the +MOQT §8.8 rendering of the namespace, and its `name` (MSF §5.2.3) as the Track Name. The +codec, dimensions, frame rate, bitrate, sample rate and channels of the entry are the +track's profile layer's (§8.1). A track that carries WAI envelopes declares `packaging` +`"wai"` ([moq-streaming-format](moq-streaming-format.md) §3), and the tracks of a staged +profile carry `wai_staged` with `layer` equal to the Track Name (moq-streaming-format +§4.1). An anchor's `track` (live-events §3.1) is SHA-256 over that rendering of the +namespace, one zero byte, and the Track Name. + +### 6.3 Layers + +A layer is an index from 0, the lowest. A profile's `layering` (§8.1) says what its +layers are: + +- `single`: one track, layer 0. +- `simulcast`: layer *k* is the profile's *k*-th layer, an independent encoding on a + track of its own. +- `staged`: layer 0 is the base and layer *k* the *k*-th refinement + ([staged-delivery](staged-delivery.md) §1), each on a track of its own. +- `svc`: one track, layer 0, carries every layer of the profile's scalability `mode`, + named as the W3C "Scalable Video Coding (SVC) Extension for WebRTC" names them + (`L1T3`, `S3T3`). A relay that forwards it to a subscriber whose `max_layer` is *m* + forwards the spatial layers 0 to *m* alone. + +A subscriber whose grant's `max_layer` is *m* subscribes to the tracks named `0` to *m* +(§10.2). A `layer_request` command (live-events §4.9) asks a publisher for a layer; it +grants nothing. + +## 7. Precedence and redundancy + +### 7.1 Slots, takeover and failover + +A **slot** is a virtual track the descriptor declares: a name, a media kind, a +`redundancy` of 1 or 2, and a `failover_ms`. Subscribers subscribe to the slot's tracks +(§6.1, owner `_`), and which principal publishes behind them can change without +any subscriber subscribing again: a relay switches the source and the subscription stands. +A slot has a **live** publisher, and, when its `redundancy` is 2, a **standby**. + +- **Takeover.** A principal whose grant in effect has a higher `precedence` than the live + publisher's replaces it: the clock records a `takeover`, the new publisher goes live, and + the replaced one leaves the slot. A takeover by a precedence not higher is refused + `takeover_not_higher`. +- **Redundancy.** With `redundancy` 2, two publishers are bound to the slot: the first to + publish into it is live, the second its standby. A third is refused `slot_full`, as is + a second where `redundancy` is 1. +- **Failover.** When the live publisher's media stops, the clock records a `failover` to + the standby. The rule: the standby goes live only once `failover_ms` milliseconds of + room clock have passed since the live publisher's last object reached the relay, which + the event states as `last_seen`; earlier is refused `failover_early`. A failover to a + principal that is not the standby is refused `failover_not_standby`. The failed + publisher leaves the slot, and can publish into it again as the standby. + +A standby whose live publisher unpublishes, or leaves the room, goes live with no event of +its own: its going live follows from the `unpublish` or `leave`. + +### 7.2 Lifecycle detail + +The lifecycle events of live-events §4.13 are authored by a room key. Their payload is the +`subject`, the principal the event is about, then `detail`, which this section defines +for each kind. A *slot* field is a short field holding a slot name or, where the +table allows, nothing (the subject's own track). `media` is a media kind of §6.1. + +| kind | `detail` | +|---|---| +| `join` | `grant` (32): the digest of the grant the subject takes part under | +| `leave` | `reason` (u8): 1 left, 2 removed, 3 its grant ended, 4 connection lost | +| `publish` | `slot` (empty for an own track), `media` (u8), `profile` (u8, the index of the profile in the descriptor), `layers` (u8, at least 1) | +| `unpublish` | `slot` (empty for an own track), `media` (u8) | +| `grant_exchange` | `old` (32), `new` (32): the grants' digests | +| `takeover` | `slot` (not empty), `media` (u8), `profile` (u8), `layers` (u8, at least 1), `previous` (32): the live publisher replaced | +| `failover` | `slot` (not empty), `media` (u8), `failed` (32): the live publisher that stopped, `last_seen` (u64): the room clock at its last object | + +A `detail` that does not read, with bytes after its last field, or with a value the table +does not allow, is `lifecycle_malformed`. Each event is then checked against the room +state (§9.3) at its `t`, in the order listed, and applied: + +- **`join`**: the grant is one the verifier holds (`grant_unknown`); its `principal` is + the subject (`grant_wrong_principal`); the subject is not present (`already_present`); + the grant is not revoked (§5, `grant_revoked`); a grant whose `once` is not zero names a + `once` no earlier `join` named (`grant_reused`); the grant is good at `t` + (`outside_grant_window`); and the room holds fewer than `max_present` principals + (`participant_limit`). The subject is present, under that grant. +- **`leave`**: the subject is present (`not_present`). It is not present any more, its + own tracks are unpublished, and it leaves every slot; a standby whose live publisher + leaves goes live. +- **`publish`**: the subject is present (`not_present`); a `slot` named is a slot of the + descriptor of that media kind (`slot_unknown`); the grant in effect may publish the + media kind (`publish_not_permitted`), and its `profiles` hold `profile`, a profile of + that media kind with at least `layers` layers (`profile_not_granted`); the subject does + not already publish that own track or stand in that slot (`already_published`); the + slot has room (§7.1, `slot_full`); and then at most `max_publishers` principals publish + (§7.3, `publisher_limit`). An own track is published with `layers` tracks; a slot's + publisher is live if the slot has none, and its standby otherwise. +- **`unpublish`**: the subject is present (`not_present`); a `slot` named is a slot of the + descriptor of that media kind (`slot_unknown`); the subject publishes that own track or + stands in that slot (`not_published`). It is unpublished; a standby whose live + publisher unpublishes goes live. +- **`grant_exchange`**: the subject is present (`not_present`); `old` is its grant in + effect (`exchange_not_current`); `new` is a grant the verifier holds (`grant_unknown`) + whose `prev` is `old` (`exchange_unlinked`); `t` is `new`'s `effective` + (`exchange_off_tick`); `new` is not revoked (`grant_revoked`) and is good at `t` + (`outside_grant_window`); and for everything the subject publishes, its own tracks by + media kind and then its places in slots in the descriptor's order, `new` may publish + the media kind (`publish_not_permitted`) and gives the profile (`profile_not_granted`). + `new` is then the grant in effect. +- **`takeover`**: the subject is present (`not_present`); the slot is the descriptor's, + of that media kind (`slot_unknown`); `previous` is its live publisher + (`not_published`); the grant in effect may publish the media kind and gives the profile + with at least `layers` layers (`publish_not_permitted`, `profile_not_granted`); the + subject is not `previous`, and its grant's `precedence` is higher than the grant in + effect of `previous` (`takeover_not_higher`); and then at most `max_publishers` + principals publish (`publisher_limit`). The subject is live, with `layers` layers; + `previous` leaves the slot, and the subject is no longer its standby. +- **`failover`**: the subject is present (`not_present`); the slot is the descriptor's, + of that media kind (`slot_unknown`); `failed` is its live publisher (`not_published`); + the subject is its standby (`failover_not_standby`); `last_seen` is at most `t`, and + `t` − `last_seen` is at least `failover_ms` × 1000 (`failover_early`). The standby is + live, and `failed` leaves the slot. + +### 7.3 Publishers + +A principal **publishes** while it has an own track published or stands in a slot, live +or standby. At most `max_publishers` principals publish at once; a `publish` or a +`takeover` after which more would is refused `publisher_limit`. + +## 8. Publish profiles + +### 8.1 The profile record + +A profile fixes, as data, what a publisher sends on one media kind: its codecs, its +layers and their limits, and its audio processing. + +| field | size | meaning | +|---|---|---| +| `name` | short | the profile's name | +| `media` | 1 | its media kind (§6.1) | +| `codecs` | 1 + … | a u8 count (1 to 4), then each `codecs` value (RFC 6381) as a short field holding a token of at most 64 bytes, in the order a publisher prefers them | +| `layering` | 1 | 0 `single`, 1 `simulcast`, 2 `svc`, 3 `staged` (§6.3) | +| `mode` | short | for `svc`, the scalability mode (§6.3): 1 to 16 of `A`–`Z`, `0`–`9` and `_`; otherwise empty | +| `layers` | 1 + 14 × *n* | a u8 count (1 to 8; exactly 1 for `single`), then each layer: `width`, `height`, `fps` (u16 each), `min_kbps`, `max_kbps` (u32 each) | +| `sample_rate` | 4 | u32: audio's sample rate in Hz; 0 for video | +| `channels` | 1 | audio's channel count, 1 to 8; 0 for video | +| `processing` | 1 | audio's processing: bit 0 echo cancellation, bit 1 noise suppression, bit 2 automatic gain control, bit 3 discontinuous transmission (DTX); 0 for video | + +Each layer's `max_kbps` is above 0 and `min_kbps` at most `max_kbps`: `min_kbps` is a +floor a publisher **SHOULD NOT** send below while the network allows, and `max_kbps` a +ceiling it **MUST NOT** exceed. An audio layer has `width`, `height` and `fps` 0, and an +audio profile a `sample_rate` above 0, 1 to 8 `channels`, and `processing` setting no bit +above bit 3; a video or screen layer has all three above 0. A publisher publishing under a +profile uses one of its codecs, its layering and its layers, and turns on exactly the +processing it names. + +### 8.2 Registered profiles + +| name | media | codecs | layering | layers (width × height @ fps, kbps) | audio | +|---|---|---|---|---|---| +| `speech` | audio | `opus` | single | 16–64 | 48 000 Hz, 1 channel; echo cancellation, noise suppression, gain control and DTX on | +| `music` | audio | `opus` | single | 128–510 | 48 000 Hz, 2 channels (stereo, fullband); no echo cancellation, noise suppression, gain control or DTX | +| `screen` | screen | `av01.0.08M.08`, `avc1.640028` | svc, `L1T3` | 1920 × 1080 @ 15, 300–2500 | — | +| `camera-720` | video | `av01.0.05M.08`, `avc1.64001F` | simulcast | 640 × 360 @ 30, 150–500; 1280 × 720 @ 30, 500–1500 | — | +| `camera-1080` | video | `av01.0.08M.08`, `avc1.640028` | simulcast | 640 × 360 @ 30, 150–500; 1280 × 720 @ 30, 500–1500; 1920 × 1080 @ 30, 1500–4000 | — | + +`opus` is RFC 6716 audio, `av01` AV1 and `avc1` ITU-T H.264. `music`'s 128 kbps floor +and its processing turned off keep what an instrument plays: echo cancellation, noise +suppression and gain control are built for speech and remove parts of music, and DTX +stops sending in what it takes for silence. `screen` drops frames rather than resolution +(`L1T3`, temporal layers alone), since text on a screen does not survive scaling. A room +lists the profiles it allows in its descriptor, under these names with these values or +under names of its own; `wai_live_room_vectors` writes each registered profile's record +into the corpus, so an implementation checks its table against them. + +## 9. Room verification + +### 9.1 Inputs and steps + +A room verifier is given a descriptor, a list of grants, the head of the authority's key +log (or none), and the room's **chains**: a list of lists of `WEV1` records, each list one +principal's records in its stream order (live-events §6). It runs these steps and stops +at the first refusal, which it reports with the reason and where: + +1. **The descriptor** (§3.4, §3.2): its refusal, at `descriptor`. +2. **The key log** (§5): its refusal, at `key_log`. +3. **The grants** (§4.3): the refusal, at the grant's index. +4. **The records**, in the merged order (§9.2), each by §9.2: the refusal, at the + record's chain and its index in that chain. +5. **The outcome** (§9.4). + +### 9.2 The merged order and each record + +The **merged order** takes the records of every chain into one sequence, keeping each +chain's own order: repeatedly, of the chains with records left, it takes the next record +of the one whose next record has the least key. A record's key is its `t`, then 0 for a +room key's record and 1 for any other, then its chain's index; a record that live-events +§3.3 does not read has the key (0, 0, its chain's index). Lifecycle events therefore take +effect before the events of other principals at the same `t`. + +One live-events verifier (live-events §6) verifies every record, for the room id. Before +it is offered a record, the verifier is given the policy the record is held to. For each +record, in the merged order: + +1. live-events §6.1 steps 1 to 4: the record reads, its kind is defined, its `room` is + the room id, its signature verifies. Otherwise that section's reason. +2. A record whose digest is that of a record accepted before is a duplicate: it is + offered under the policy it was accepted under, which live-events §6.2 step 1 ignores, + and it changes nothing. +3. A room key's record is offered under the room authority's policy (live-events §5), + and refused with live-events' reason. A lifecycle event then has its `detail` read and + is applied (§7.2). +4. Any other principal's record: the principal is present (`not_present`), its grant in + effect is good at the record's `t` (`outside_grant_window`), and the record is offered + under that grant's `policy` and refused with live-events' reason: a kind the grant does + not permit is `kind_not_permitted`, a payload over its bound `payload_too_large`, and an + event past its rate window `rate_exceeded`. A participant's lifecycle event is + therefore `kind_not_permitted`, as no grant permits one (§4.3 step 5). +5. A `control` event of such a principal needs a power of its grant in effect (§3.3): + `record_start` and `record_stop` the record power, any other command the direct power. + Otherwise `power_not_granted`. + +Each principal's effective policy at `t` is so the policy of its grant in effect at `t`, +and the room keys' is the authority's. Each record is reported with the grant it was +verified under, or none for a room key's. + +### 9.3 Room state + +The room state is replayed from the lifecycle events alone, in the merged order: + +- **present**: each present principal and its grant in effect; +- **published**: each own track, by principal and media kind, with its profile and its + number of layers; +- **slots**: each slot's live publisher and standby, and the live publisher's precedence: + the slot's current **precedence holder**; +- **active grants**: each change of a principal's grant in effect (a `join` or a + `grant_exchange`), with its `t`, in the order they took effect. + +The tracks a subscriber of the room can subscribe to are named by §6.1: each own track's +layers, and each slot's live publisher's. + +### 9.4 Outcomes + +- **refuse**: the reason and where (§9.1). Step 5's `tally_mismatch` (live-events §7) is + at the record of its `poll_close`. +- **gap**: no record refused, and the live-events verifier does not hold every seq of + every chain (live-events §6.2): the gaps, under the code `delivery_gap`. The room state + is the replay of what it holds, and a tally it computes is unchecked. +- **accept**: no record refused, no gap, and every stated tally equal to the replay. + +## 10. Bindings + +A grant is WAI's own signed record. A relay, a CDN or an origin that authorises with an +existing token format is given a token that maps the grant's claims onto that format's; +WAI defines no second token format. A claim the grant has and the format does not stays +in the grant, which the relay holds beside the token (§10.1). + +### 10.1 Common Access Token (CTA-5007-B) + +A Common Access Token is a CWT (RFC 8392). Its claims are named here by name and by the +key the IANA CWT Claims registry gives them; the value syntax of each CAT claim is +CTA-5007-B's. + +| grant claim | CWT / CAT claim | mapping | +|---|---|---| +| the authority | `iss` (1) | the authority's `signer_id` (jwp-receipts §7.1): origin-bound, with its key-log entry's id, where `origin` is set; its `did:key` otherwise | +| `principal` | `sub` (2) | the principal's `did:key` | +| `room` | `aud` (3) | the room id, 64 lowercase hexadecimal digits | +| `nbf`, `exp` | `nbf` (5), `exp` (4) | the same NumericDates | +| `once` | `cti` (7), `catreplay` (308) | a `once` not zero is the token's `cti`, with `catreplay` set to prohibit replay; zero, `catreplay` permits it | +| `origins` | `catu` (312), `cath` (315) | each origin as a URI match on scheme and host; a deployment that matches on a request header carries it in `cath` | +| the token's renewal | `catr` (323) | a renewed token's `exp` is never later than the grant's; an exchange (§4.6) issues a new token | +| `principal`, as a key binding | `catdpop` (321), `cnf` (8) | proof of possession by the principal's key; `cattpk` (319) binds a TLS key, and applies only where the client's TLS key is the principal's | +| client network, geography | `catnip` (311), `catgeoiso3166` (316) | no grant claim: a deployment **MAY** add them; a room's restriction by place is a sink-evaluated predicate ([unidirectional-delivery](unidirectional-delivery.md) §2) | +| caps, `max_layer`, the slots | `moqt` | §10.2 | +| `reval` (descriptor) | `moqt-reval` | §10.2 | +| `role`, `precedence`, `policy`, `profiles`, `attrs`, `joules_ceiling`, `funds_ceiling`, `viewer` | none | WAI's alone; the relay holds the grant, and a deployment that links the two inside the token carries the grant's digest in a private-use claim (RFC 8392 §9.1) | + +`catv` (310) is the version CTA-5007-B gives; `catpor` (309), `catm` (313), `catalpn` +(314), `catgeocoord` (317), `catgeoalt` (318), `catif` (322) and `catifdata` (320) have +no grant claim. This revision implements no CAT encoding: the crate has no CBOR or COSE, +and the claims above are mapped by name and key. + +### 10.2 MOQT: the `moqt` claim (`draft-ietf-moq-c4m-01`) + +A token for MOQT carries the `moqt` claim, an array of scopes, each `[actions, namespace +matches, track match]` (`draft-ietf-moq-c4m-01` §2.1). Every action is blocked unless a +scope enables it (§2 there), so the scopes a grant maps onto are all it can do. With the +room id `R` and the principal `P` as 64 lowercase hexadecimal digits, the scopes are, in +this order: + +1. `[[0]]`: `CLIENT_SETUP`. +2. For each media kind the grant may publish, in ascending order of its code, with *m* its + name (§6.1): + `[[2, 6], [R, P, m, nil]]` (`PUBLISH_NAMESPACE` and `PUBLISH` of its own tracks), then, + for each slot of the descriptor of media kind *m*, in the descriptor's order, + `[[6], [R, "_" + slot, m, nil]]`. +3. When the grant's policy permits any kind: `[[2, 6], [R, P, "events", nil], "0"]`. +4. When the grant may subscribe: `[[3], [R]]` (`SUBSCRIBE_NAMESPACE`), then for each layer + *l* from 0 to `max_layer`, `[[4, 7, 8], [R], "l"]` (`SUBSCRIBE`, `FETCH`, + `TRACK_STATUS` of any track of the room named *l*). + +Each namespace or track match is a byte string, an exact match; `nil` ends a namespace +match at that length. The token's `moqt-reval` is the descriptor's `reval`: a relay +re-validates the token, and with it the grant's revocation (§5), at least that often, and +stops what the grant authorised when it fails (§2.2 there). A `reval` of 0 asks for no +re-validation, and then only expiry ends the token. A grant exchange (§4.6) issues a new +token at the tick. The corpus states each accepted vector's scopes per grant, written as +JSON: an exact match as a string and `nil` as `null`. + +### 10.3 URI Signing (RFC 9246) + +Over HTTP, a room's delivery (an LL-HLS or DASH rendition of its tracks) is authorised with +a URI Signing JWT: + +| grant claim | URI Signing claim | mapping | +|---|---|---| +| the authority | `iss` (§2.1.1 there) | as §10.1 | +| `principal` | `sub` (§2.1.2) | the principal's `did:key`, as a JWE as that section requires | +| `nbf`, `exp` | `nbf` (§2.1.5), `exp` (§2.1.4) | the same, with no leeway | +| `once` | `jti` (§2.1.7) | a `once` not zero, so a CDN that keeps token ids refuses a replay | +| `origins`, `room`, `max_layer` | `cdniuc` (§2.1.11) | a `regex:` container (§2.1.15.2) matching the grant's origins, the room's path, and the renditions of layers 0 to `max_layer` | +| client network | `cdniip` (§2.1.10) | no grant claim; a deployment **MAY** add it | +| renewal | `cdniets`, `cdnistt`, `cdnistd` (§2.1.12–§2.1.14) | a renewed token's `exp` is never later than the grant's | +| the rest | none | as §10.1 | + +`cdniv` is 1. + +### 10.4 Privacy Pass (`draft-ietf-moq-privacy-pass-auth-03`) + +A viewer that need not be identified is admitted by a Privacy Pass token instead of a +grant. The token's challenge carries the scope in its `origin_info` +(`MoQAuthorizationInfo`, §3.2.4 there), and its presentations are unlinkable to one +another (§2.2 there). + +| grant claim | Privacy Pass field | mapping | +|---|---|---| +| `room`, `subscribe`, `max_layer` | `origin_info` scopes | the subscribing scopes of §10.2 step 4, each a `MoQAuthScope` whose `namespace_match` is `MATCH_PREFIX` on `[R]` and whose `track_name_match` is `MATCH_EXACT` on the layer | +| `nbf`, `exp` | `redemption_context` (§3.2.1 there) | a hash of the time window the token is good for | +| `once` | the token's nonce | every token is single-use (§3.3.2 there) | +| `principal`, `viewer` | none | the token names no one; revocation is of the issuer's key, not of a viewer | +| `policy`, publish caps, ceilings, `attrs` | none | a Privacy Pass viewer sends no event and publishes nothing | + +A viewer that is to send events holds a grant for a key of its own; a key per room keeps +its events unlinkable across rooms (live-events §11). + +## 11. Reasons + +The codes this extension adds, each with where it is raised: + +| reason | raised at | +|---|---| +| `descriptor_invalid` | §3.4 | +| `key_log_missing` | §5 step 1 | +| `key_log_not_held` | §5 step 2 | +| `authority_not_listed` | §5 step 3 | +| `authority_revoked` | §5 step 4 | +| `grant_invalid` | §4.3 step 5 | +| `grant_too_long` | §4.3 step 6 | +| `caps_exceed_role` | §4.3 step 7 | +| `grant_exceeds_room` | §4.3 step 8 | +| `exchange_unlinked` | §4.3 step 3, §7.2 `grant_exchange` | +| `exchange_mismatch` | §4.3 step 3 | +| `lifecycle_malformed` | §7.2 | +| `grant_unknown` | §7.2 `join`, `grant_exchange` | +| `grant_wrong_principal` | §7.2 `join` | +| `grant_revoked` | §5, §7.2 `join`, `grant_exchange` | +| `grant_reused` | §7.2 `join` | +| `already_present` | §7.2 `join` | +| `not_present` | §7.2, §9.2 step 4 | +| `participant_limit` | §3.5, §7.2 `join` | +| `outside_grant_window` | §4.3, §7.2, §9.2 step 4 | +| `power_not_granted` | §9.2 step 5 | +| `publish_not_permitted` | §7.2 `publish`, `grant_exchange`, `takeover` | +| `profile_not_granted` | §7.2 `publish`, `grant_exchange`, `takeover` | +| `already_published` | §7.2 `publish` | +| `not_published` | §7.2 `unpublish`, `takeover`, `failover` | +| `slot_unknown` | §7.2 | +| `slot_full` | §7.1, §7.2 `publish` | +| `publisher_limit` | §7.3 | +| `exchange_not_current` | §7.2 `grant_exchange` | +| `exchange_off_tick` | §4.6, §7.2 `grant_exchange` | +| `takeover_not_higher` | §7.1, §7.2 `takeover` | +| `failover_not_standby` | §7.1, §7.2 `failover` | +| `failover_early` | §7.1, §7.2 `failover` | + +Of live-events §9's codes, a room verifier also raises `truncated`, `malformed` and +`unknown_version` when a descriptor or a grant does not read (§3.4, §4.3); `bad_key` and +`bad_signature` for their signatures (§3.2, §4.2); `wrong_room` for a grant of another +room (§4.3 step 4); every code live-events §6 raises for a record (§9.2); `tally_mismatch` +(§9.4); and `delivery_gap` for a gap, which is not a refusal. + +## 12. Conformance + +[`live-conformance/rooms/`](../live-conformance/rooms/) holds the corpus, in one file, +`vectors.json`, written from fixed seeds by `wai_live_room_vectors gen`. It has the +records of each registered profile (§8.2), and **vectors**: a descriptor, grants, a +key-log head or none, and chains, with the outcome §9.4 gives them. + +- **Accepted**: a lesson-style room (a director, a performer, an audience, and the + director's remote record control of the performer, under a key log whose head revokes + a grant and a viewer the room never admits); a broadcast room (one publisher, many + viewers, a moderator); a takeover; a redundant pair with failover; and a grant + exchange that promotes a viewer to a publisher. Each states the room id, every grant's + digest, the merged order with the grant each record was verified under, the room state + (§9.3) with the names of the tracks a subscriber can reach (§6.1), the tally + (live-events §7), and each grant's `moqt` scopes and re-validation interval (§10.2). +- **Gap**: a chain with a record not delivered. +- **Refused**: each reason of §11 at least once, each vector a control of one defect, and + the codes of live-events §9 that a descriptor, a grant or a record of a room raises. + +A conforming verifier gives every vector the outcome, the reason, the place, the gaps and +the state, order, tally and scopes the corpus states. `wai_live_room_vectors verify` and +the test `tests/live_room.rs` check that the file regenerates byte for byte, that `wai-rs` +gives every vector its outcome, and that §11 lists exactly the reference's codes. +`live-conformance/live_rooms_verify.py` is the second implementation, written from this +text: it shares no code with `wai-rs`, verifies signatures with WAI's strict rule written +from RFC 8032 (`claim-conformance/_ed25519.py`), verifies each event with the live-events +corpus's own second implementation (`live_events_verify.py`), and gives every vector the +same outcome. + +## 13. Security and privacy considerations + +- Every claim a principal acts under is signed by the room authority, and every event a + principal sends by the principal; a relay can drop either but alter neither, and a room + verifier replays the room from them alone. +- `t` is its author's claim (live-events §11). The clock's lifecycle events fix when a + principal was present and under which grant; a participant's `t` outside its grant's + window or outside its presence is refused. A clock that lies about time is the room's + own key lying, which its signature makes evidence of. +- A grant is a bearer capability only together with the principal's key: every event + under it is signed by that key, so a copied grant lets no one else send. A token mapped + from it (§10) is a bearer token, which is why the mapping binds it to the principal's + key where the format allows (`catdpop`, `cnf`) and why its window is fourteen days at + most. +- Revocation is through the key log, so it is as available as the log (jwp-receipts §7.8): + a relay with no fresh status for the authority's origin fails closed. +- A viewer's tag is a hash of an id the authority assigns; the key log publishes the tag, + not the id, and an authority **SHOULD** assign ids that are not otherwise meaningful. +- A grant names its principal, so a room's grants link that principal's participation; a + principal that needs participation unlinkable across rooms uses a key per room, and a + viewer that needs no identity is admitted by Privacy Pass (§10.4). +- The region pin (§3.7) binds where a recording is kept; checking a recording's receipt + against it is the recording extension's. diff --git a/wai/live-conformance/README.md b/wai/live-conformance/README.md new file mode 100644 index 000000000..491e1eb68 --- /dev/null +++ b/wai/live-conformance/README.md @@ -0,0 +1,24 @@ +# live-conformance — the `wai.live` family + +Conformance corpora of the live and interactive extensions, one directory per extension, +and the independent verifier of each, beside it. + +| directory | extension | verifier | +|---|---|---| +| [`events/`](events/) | [live-events](../extensions/live-events.md) (`wai.live.events`) | `live_events_verify.py` | +| [`rooms/`](rooms/) | [live-rooms](../extensions/live-rooms.md) (`wai.live.room`) | `live_rooms_verify.py` | +| [`takes/`](takes/) | [capture-binding](../extensions/capture-binding.md) (`wai.capture.take`) | `capture_take_verify.py` | + +**Provenance.** Generated here: `wai_live_events_vectors gen` writes `events/`, +`wai_live_room_vectors gen` writes `rooms/` and `wai_capture_take_vectors gen` writes +`takes/`, each from records authored in code, from fixed seeds (`events/README.md`, +`rooms/README.md`, `takes/README.md`). No recorded data. + +Each verifier is written from its extension's text, shares no code with `wai-rs`, and is +run by `.github/workflows/wai-conformance.yml` beside the reference's own check: + +``` +python3 live_events_verify.py events +python3 live_rooms_verify.py rooms +python3 capture_take_verify.py takes +``` diff --git a/wai/live-conformance/capture_take_verify.py b/wai/live-conformance/capture_take_verify.py new file mode 100644 index 000000000..cda213f7d --- /dev/null +++ b/wai/live-conformance/capture_take_verify.py @@ -0,0 +1,683 @@ +#!/usr/bin/env python3 +"""Independent verifier of the capture-binding corpus (extensions/capture-binding.md). + +Written from the extension's text. It shares no code with wai-rs, which generates the +corpus, and never runs it. It checks Ed25519 signatures with +../claim-conformance/_ed25519.py, WAI's strict rule (SPEC §7 *Signatures*) written from +RFC 8032 with the standard library. The room is verified by the live-rooms corpus's own +second implementation, live_rooms_verify.py (live-rooms §9), which verifies every event +with live_events_verify.py (live-events §6); both are likewise written from their texts +alone. Everything else is here: + +- the take tree (§4): leaves of the take's domain, the Merkle tree hash of RFC 6962 §2.1 + with staged-measurement Appendix C's node, and consistency checked as RFC 9162 §2.1.4.2 + checks it; +- the take_commit payload and its chain (§5), the upload receipts and their state machine + (§6), the take manifest (§7) and the consent record (§8), each read and checked here; +- take verification (§9): the take in the room, the store, the receipts, the consents, + the verdicts of single-take, aligned, complete and publishable, and whether the + manifest stands; the master position of every marker (§10); the stream id (§11.1). + +For every vector it requires the outcome, reason and place, and for one with verdicts the +take id, stream id, commitments, size, root, verdicts, standing and markers the corpus +states; of the corpus, that every reason of §12 and delivery_gap appear in it. Then it +mutates copies of the corpus, one defect each, and requires every copy to fail. + + python3 capture_take_verify.py + +Exit status 0 only if every vector verifies and every mutated copy fails. Python 3.8 or +later; standard library only. +""" +import copy +import hashlib +import json +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HERE) +sys.path.insert(0, os.path.join(HERE, "..", "claim-conformance")) +import live_events_verify as LEV # noqa: E402 +import live_rooms_verify as LRV # noqa: E402 +import _ed25519 as ED # noqa: E402 + +Refuse = LEV.Refuse + +TAKE_DOMAIN = b"wai:capture-take\x01" +LEAF_DOMAIN = b"wai:take-leaf\x01" +NODE_DOMAIN = b"wai:out-node\x01" +MANIFEST_DOMAIN = b"wai:capture-manifest\x01" +RECEIPT_DOMAIN = b"wai:take-upload\x01" +CONSENT_DOMAIN = b"wai:capture-consent\x01" +STORE_AUTHORITY = "capture/store" +ZERO = bytes(32) +OPEN, RUNNING, CLOSE = 1, 2, 3 +R_OPEN, R_PROGRESS, R_RESUME, R_SEALED = 1, 2, 3, 4 +PURPOSES = [(1, "live"), (2, "record"), (4, "distribute"), (8, "train")] +RECORD = 2 +SINGLE_TAKE, ALIGNED, COMPLETE = 1, 2, 4 +TAKE_COMMIT, MARKER, CONTROL = 0x0C, 0x08, 0x09 + +# §12, in its order. +REASONS = [ + "recording_not_permitted", "take_unknown", "commit_malformed", "device_not_bound", + "manifest_invalid", "manifest_mismatch", "store_not_listed", "upload_receipt_invalid", + "upload_receipt_mismatch", "store_outside_region", "consent_invalid", + "commit_chain_broken", "root_not_extending", "take_not_closed", "manifest_not_committed", + "clock_unstable", "capture_discontinuous", "chunk_too_long", "commit_early", "commit_late", + "chunk_extra", "chunk_reordered", "chunk_altered", "misaligned", "chunk_missing", + "upload_not_sealed", "consent_missing", "guardian_missing", "consent_revoked", + "consent_expired", "purpose_not_consented", +] + + +def sha(*parts): + h = hashlib.sha256() + for p in parts: + h.update(p) + return h.digest() + + +class Reader: + """Reads little-endian fields in order; running out is `out`.""" + + def __init__(self, b, p, out): + self.b, self.p, self.out = b, p, out + + def take(self, n): + if self.p + n > len(self.b): + raise Refuse(self.out) + s = self.b[self.p:self.p + n] + self.p += n + return s + + def u8(self): + return self.take(1)[0] + + def uint(self, n): + return int.from_bytes(self.take(n), "little") + + def i64(self): + return int.from_bytes(self.take(8), "little", signed=True) + + def done(self): + return self.p == len(self.b) + + +def read_head(b, magic): + """live-events §3.3's first steps, with `magic` for WEV1.""" + if len(b) < 4: + raise Refuse("truncated") + if b[:4] != magic: + raise Refuse("malformed") + if len(b) < 5: + raise Refuse("truncated") + if b[4] != 1: + raise Refuse("unknown_version") + + +def check_sig(key, domain, body, sig): + bad = ED.verify(key, domain + body, sig) + if bad: + raise Refuse(bad) + + +# ---------------------------------------------------------------- §4 the take tree + +def leaf(desc): + return sha(LEAF_DOMAIN, desc) + + +def node(left, right): + return sha(NODE_DOMAIN, left, right) + + +def split(n): + """The largest power of two below n, n >= 2.""" + k = 1 + while k * 2 < n: + k *= 2 + return k + + +def mth(ls): + """RFC 6962 §2.1, n >= 1.""" + if len(ls) == 1: + return ls[0] + k = split(len(ls)) + return node(mth(ls[:k]), mth(ls[k:])) + + +def root_of(chunks): + return ZERO if not chunks else mth([leaf(c["desc"]) for c in chunks]) + + +def consistent(first, second, first_root, second_root, path): + """RFC 9162 §2.1.4.2, with node() for HASH(0x01 || ...); 0 < first < second.""" + if not path: + return False + if first & (first - 1) == 0: + path = [first_root] + list(path) + fn, sn = first - 1, second - 1 + while fn & 1: + fn >>= 1 + sn >>= 1 + fr = sr = path[0] + for c in path[1:]: + if sn == 0: + return False + if fn & 1 or fn == sn: + fr = node(c, fr) + sr = node(c, sr) + if not fn & 1: + while not fn & 1 and fn != 0: + fn >>= 1 + sn >>= 1 + else: + sr = node(sr, c) + fn >>= 1 + sn >>= 1 + return fr == first_root and sr == second_root and sn == 0 + + +def extends(first, old, size, new, proof): + """§4.3, with the two cases RFC 9162 leaves to the caller.""" + if first == 0: + return not proof + if first == size: + return not proof and old == new + return first < size and consistent(first, size, old, new, proof) + + +# ---------------------------------------------------------------- §5, §6, §7, §8 records + +def read_commit(b): + """§5.2.""" + r = Reader(b, 0, "commit_malformed") + c = {"take": r.take(32), "n": r.uint(4), "phase": r.u8()} + if c["phase"] not in (OPEN, RUNNING, CLOSE): + raise Refuse("commit_malformed") + c["prev"], c["first"], c["size"] = r.take(32), r.uint(8), r.uint(8) + if c["size"] < c["first"]: + raise Refuse("commit_malformed") + c["root"] = r.take(32) + if c["size"] == 0 and c["root"] != ZERO: + raise Refuse("commit_malformed") + c["offset"] = r.i64() + k = r.u8() + if k > 64: + raise Refuse("commit_malformed") + c["proof"] = [r.take(32) for _ in range(k)] + if not r.done(): + raise Refuse("commit_malformed") + return c + + +def is_opening(c): + return (c["n"] == 0 and c["phase"] == OPEN and c["prev"] == ZERO and c["first"] == 0 and c["size"] == 0 + and not c["proof"]) + + +def read_chunk(r): + desc = r.take(64) + return {"desc": desc, "index": int.from_bytes(desc[0:8], "little"), "start": int.from_bytes(desc[8:16], "little"), + "end": int.from_bytes(desc[16:24], "little"), "len": int.from_bytes(desc[24:32], "little"), "hash": desc[32:]} + + +def is_chunk(c, b): + return len(b) == c["len"] and sha(b) == c["hash"] + + +def read_receipt(b): + """§6.2.""" + read_head(b, b"WUR1") + r = Reader(b, 5, "truncated") + x = {"store": r.take(32), "take": r.take(32), "seq": r.uint(8), "prev": r.take(32), "at": r.uint(8), + "state": r.u8(), "held": r.uint(8), "root": r.take(32), "region": r.take(2), "sig": r.take(64)} + if not r.done(): + raise Refuse("malformed") + x["body"] = b[:-64] + x["digest"] = sha(x["body"]) + return x + + +def read_manifest(b, room): + """§7.2: the manifest, or Refuse.""" + read_head(b, b"WTM1") + r = Reader(b, 5, "truncated") + m = {k: r.take(32) for k in ("room", "device", "principal", "start", "take", "store")} + m["claims"], m["purposes"] = r.u8(), r.u8() + m["chunks"] = [read_chunk(r) for _ in range(r.uint(4))] + m["root"] = r.take(32) + m["commits"] = [r.take(32) for _ in range(r.uint(4))] + m["depicted"] = [(r.take(32), r.take(32)) for _ in range(r.u8())] + m["sig"] = r.take(64) + if not r.done(): + raise Refuse("malformed") + keys = [p for p, _ in m["depicted"]] + ok = (m["claims"] & ~0b111 == 0 and m["purposes"] & ~0b1111 == 0 and len(m["chunks"]) >= 1 + and all(c["index"] == i and c["len"] >= 1 for i, c in enumerate(m["chunks"])) + and m["root"] == root_of(m["chunks"]) + and len(m["commits"]) >= 1 and len(set(m["commits"])) == len(m["commits"]) + and 1 <= len(keys) <= 32 and all(a < z for a, z in zip(keys, keys[1:])) and m["principal"] in keys + and m["take"] == sha(TAKE_DOMAIN, m["room"], m["device"], m["start"])) + if not ok: + raise Refuse("manifest_invalid") + if m["room"] != room: + raise Refuse("wrong_room") + check_sig(m["device"], MANIFEST_DOMAIN, b[:-64], m["sig"]) + return m + + +def read_consent(b): + """§8.1, §8.2.""" + read_head(b, b"WCN1") + r = Reader(b, 5, "truncated") + c = {"subject": r.take(32), "minor": r.u8(), "guardian": r.take(32), "purposes": r.u8(), "room": r.take(32), + "nbf": r.uint(8), "exp": r.uint(8), "nonce": r.take(16), "sig": r.take(64)} + if not r.done(): + raise Refuse("malformed") + ok = (c["minor"] in (0, 1) and (c["minor"] == 1 or c["guardian"] == ZERO) and c["guardian"] != c["subject"] + and c["purposes"] != 0 and c["purposes"] & ~0b1111 == 0 and c["nbf"] < c["exp"]) + if not ok: + raise Refuse("consent_invalid") + signer = c["subject"] if c["guardian"] == ZERO else c["guardian"] + check_sig(signer, CONSENT_DOMAIN, b[:-64], c["sig"]) + c["digest"] = sha(b[:-64]) + return c + + +def stream_id(take): + """§11.1: an RFC 9562 version-8 UUID of the take id's first 16 bytes.""" + u = bytearray(take[:16]) + u[6] = (u[6] & 0x0F) | 0x80 + u[8] = (u[8] & 0x3F) | 0x80 + h = u.hex() + return "%s-%s-%s-%s-%s" % (h[:8], h[8:12], h[12:16], h[16:20], h[20:]) + + +# ---------------------------------------------------------------- §9 verification + +class Stop(Exception): + def __init__(self, at, reason): + Exception.__init__(self, reason) + self.at, self.reason = at, reason + + +def attrs_of(g): + return dict(LRV.read_attrs(g["attrs"]) or []) + + +def binds(g, principal): + """§3.1.""" + a = attrs_of(g) + return a["subject"] == principal.hex() if "subject" in a else g["principal"] == principal + + +def control(ev, device, command): + """The control payload of `ev`, when it is `command` addressed to `device`.""" + if ev["kind"] != CONTROL: + return None + try: + p = LEV.read_payload(CONTROL, ev["payload"], 65535) + except Refuse: + return None + return p if p["target"] == device and p["command"] == command else None + + +def find(d, grants, seen, gaps, m): + """§9.2: the start, its count-in, the stop and the held commitments.""" + if d["mode"] == 0: + raise Stop(["manifest"], "recording_not_permitted") + pos = next((k for k, s in enumerate(seen) if s["ev"]["digest"] == m["start"]), None) + start = None if pos is None else control(seen[pos]["ev"], m["device"], 1) + if start is None: + raise Stop(["manifest"], "take_unknown") + stop = next((s for s in seen[pos + 1:] if control(s["ev"], m["device"], 2) is not None), None) + mine = sorted((s for s in seen if s["ev"]["principal"] == m["device"] and s["ev"]["kind"] == TAKE_COMMIT), + key=lambda s: s["ev"]["seq"]) + commits = [] + for s in mine: + try: + c = read_commit(s["ev"]["payload"]) + except Refuse as e: + raise Stop(["record", s["chain"], s["record"]], e.reason) + if c["take"] == m["take"]: + commits.append((s, c)) + for s, _ in commits: + g = grants.get(s["grant"]) + if g is None or not binds(g, m["principal"]): + raise Stop(["record", s["chain"], s["record"]], "device_not_bound") + device_gap = any(g["principal"] == m["device"].hex() for g in gaps) + held = [s["ev"]["digest"] for s, _ in commits] + every = {s["ev"]["digest"] for s in seen} + listed_held = [x for x in m["commits"] if x in held] + unheld = [x for x in m["commits"] if x not in held] + if listed_held != held or any(x in every or not device_gap for x in unheld): + raise Stop(["manifest"], "manifest_mismatch") + return seen[pos], start["count_in_ms"], stop, commits + + +def head_of(text): + return json.loads(text) if text is not None else None + + +def check_upload(d, head, m, receipts): + """§6.4, §6.3: the last receipt, or Stop.""" + if d["origin"] != b"": + h = head_of(head) + listed = h is not None and any( + e["key"] == m["store"].hex() and STORE_AUTHORITY in e["may_sign"] and e["status"] != "revoked" for e in h["keys"]) + if not listed: + raise Stop(["store"], "store_not_listed") + prev = None + for i, b in enumerate(receipts): + at = ["receipt", i] + try: + x = read_receipt(b) + except Refuse as e: + raise Stop(at, e.reason) + fields = (x["state"] in (1, 2, 3, 4) and all(0x41 <= c <= 0x5A for c in x["region"]) + and (x["held"] != 0 or x["root"] == ZERO)) + if not fields or x["store"] != m["store"] or x["take"] != m["take"]: + raise Stop(at, "upload_receipt_invalid") + bad = ED.verify(x["store"], RECEIPT_DOMAIN + x["body"], x["sig"]) + if bad: + raise Stop(at, bad) + if prev is None: + chained = x["seq"] == 0 and x["prev"] == ZERO and x["state"] == R_OPEN and x["held"] == 0 + else: + step = {R_PROGRESS: x["held"] > prev["held"], R_RESUME: x["held"] == prev["held"], + R_SEALED: x["held"] == prev["held"]}.get(x["state"], False) + chained = (x["seq"] == i and x["prev"] == prev["digest"] and x["at"] >= prev["at"] + and x["region"] == prev["region"] and prev["state"] != R_SEALED and step) + if not chained: + raise Stop(at, "upload_receipt_invalid") + if x["held"] > len(m["chunks"]) or x["root"] != root_of(m["chunks"][:x["held"]]): + raise Stop(at, "upload_receipt_mismatch") + if d["regions"] and x["region"] not in d["regions"]: + raise Stop(at, "store_outside_region") + prev = x + return prev + + +def single_take(f, m, clock, parts): + """§9.4 single-take: None when it holds, else its reason.""" + start, _, stop, commits = f + interval, jitter, o = clock + held = {s["ev"]["digest"] for s, _ in commits} + if any(x not in held for x in m["commits"]): + return "delivery_gap" + cs = [c for _, c in commits] + if not cs or not is_opening(cs[0]): + return "commit_chain_broken" + for (ps, p), (_, c) in zip(commits, commits[1:]): + if p["phase"] == CLOSE or c["phase"] == OPEN or c["n"] != p["n"] + 1 or c["prev"] != ps["ev"]["digest"] or c["first"] != p["size"]: + return "commit_chain_broken" + for p, c in zip(cs, cs[1:]): + if not extends(c["first"], p["root"], c["size"], c["root"], c["proof"]): + return "root_not_extending" + last = cs[-1] + if last["phase"] != CLOSE or stop is None: + return "take_not_closed" + ch = m["chunks"] + if len(ch) != last["size"] or any(c["size"] > 0 and root_of(ch[:c["size"]]) != c["root"] for c in cs): + return "manifest_not_committed" + if any(abs(c["offset"] - o) > jitter for c in cs): + return "clock_unstable" + if any(c["start"] >= c["end"] for c in ch) or any(b["start"] != a["end"] for a, b in zip(ch, ch[1:])): + return "capture_discontinuous" + if any(c["end"] - c["start"] > interval for c in ch): + return "chunk_too_long" + added = [(s["ev"]["t"], ch[c["first"]:c["size"]]) for s, c in commits] + if (commits[0][0]["ev"]["t"] < start["ev"]["t"] or commits[-1][0]["ev"]["t"] < stop["ev"]["t"] + or any(t + jitter < x["end"] + o for t, xs in added for x in xs)): + return "commit_early" + if any(t > x["end"] + o + interval + jitter for t, xs in added for x in xs): + return "commit_late" + for index, b in parts: + if index >= len(ch): + return "chunk_extra" + if not is_chunk(ch[index], b): + return "chunk_reordered" if any(c["index"] != index and is_chunk(c, b) for c in ch) else "chunk_altered" + return None + + +def aligned(f, m, clock): + """§9.4 aligned.""" + start, count_in_ms, _, commits = f + _, jitter, o = clock + if not commits or commits[0][0]["ev"]["digest"] != m["commits"][0]: + return "delivery_gap" + if not is_opening(commits[0][1]): + return "commit_chain_broken" + adds = next((c for _, c in commits if c["size"] > 0), None) + if adds is None or adds["size"] > len(m["chunks"]) or root_of(m["chunks"][:adds["size"]]) != adds["root"]: + return "manifest_not_committed" + if abs(m["chunks"][0]["start"] + o - (start["ev"]["t"] + count_in_ms * 1000)) > jitter: + return "misaligned" + return None + + +def complete(f, m, parts, last_receipt): + """§9.4 complete.""" + commits = f[3] + s, r = (commits[-1][1]["size"], commits[-1][1]["root"]) if commits else (0, ZERO) + if s == 0 or s > len(m["chunks"]) or root_of(m["chunks"][:s]) != r: + return "manifest_not_committed" + for c in m["chunks"][:s]: + if not any(i == c["index"] and is_chunk(c, b) for i, b in parts): + return "chunk_missing" + if last_receipt is None or last_receipt["state"] != R_SEALED or last_receipt["held"] != s: + return "upload_not_sealed" + return None + + +def publishable(p, m, consents, room, revoked, principal_minor, start_s, at): + """§9.4 publishable for purpose bit p.""" + for subject, digest in m["depicted"]: + c = next((c for c in consents if digest != ZERO and c["digest"] == digest and c["subject"] == subject + and c["room"] in (ZERO, room)), None) + if c is None: + return "consent_missing" + if (c["minor"] == 1 or (subject == m["principal"] and principal_minor)) and c["guardian"] == ZERO: + return "guardian_missing" + if c["digest"] in revoked: + return "consent_revoked" + if not (c["nbf"] <= start_s < c["exp"]) or not (c["nbf"] <= at < c["exp"]): + return "consent_expired" + if not c["purposes"] & RECORD or not c["purposes"] & p: + return "purpose_not_consented" + return None + + +def position(chunks, o, t): + """§10: (chunk, into the chunk, into the master), or None outside the master.""" + dv = t - o + for c in chunks: + if c["start"] <= dv < c["end"]: + return c["index"], dv - c["start"], dv - chunks[0]["start"] + return None + + +def verify_take(v): + """§9: a dict of what the corpus states for the vector.""" + descriptor = bytes.fromhex(v["descriptor"]) + grants = [bytes.fromhex(g) for g in v["grants"]] + head = v["key_log_head"] + chains = [[bytes.fromhex(r) for r in c] for c in v["chains"]] + room_out = LRV.verify_room(descriptor, grants, head, chains) + if room_out["outcome"] == "refuse": + return {"outcome": "refuse", "reason": room_out["reason"], "at": ["room"] + room_out["at"]} + d = LRV.read_descriptor(descriptor) + held_grants, _ = LRV.check_grants(d, grants) + by_digest = {g["digest"]: g for g in held_grants} + seen, digests = [], set() + for c, i, g in room_out["order"]: + ev = LEV.read_record(chains[c][i]) + if ev["digest"] not in digests: + digests.add(ev["digest"]) + seen.append({"chain": c, "record": i, "ev": ev, "grant": bytes.fromhex(g) if g else None}) + try: + try: + m = read_manifest(bytes.fromhex(v["manifest"]), d["room"]) + except Refuse as e: + raise Stop(["manifest"], e.reason) + f = find(d, by_digest, seen, room_out.get("gaps", []), m) + last_receipt = check_upload(d, head, m, [bytes.fromhex(r) for r in v["receipts"]]) + consents = [] + for k, b in enumerate(v["consents"]): + try: + consents.append(read_consent(bytes.fromhex(b))) + except Refuse as e: + raise Stop(["consent", k], e.reason) + except Stop as e: + return {"outcome": "refuse", "reason": e.reason, "at": e.at} + _, _, _, commits = f + o = commits[0][1]["offset"] if commits else 0 + clock = (d["commit_interval_ms"] * 1000, d["jitter_ms"] * 1000, o) + parts = [(p["index"], bytes.fromhex(p["bytes"])) for p in v["parts"]] + revoked = set() + if d["origin"] != b"": + revoked = {bytes.fromhex(x) for x in head_of(head)["revoked_modules"]} + first_grant = by_digest.get(commits[0][0]["grant"]) if commits else None + principal_minor = first_grant is not None and attrs_of(first_grant).get("minor") == "true" + start_s = (d["t0"] + f[0]["ev"]["t"]) // 1000000 + verdicts = { + "single_take": single_take(f, m, clock, parts) or "holds", + "aligned": aligned(f, m, clock) or "holds", + "complete": complete(f, m, parts, last_receipt) or "holds", + "publishable": {n: publishable(b, m, consents, d["room"], revoked, principal_minor, start_s, v["evaluated_at"]) or "holds" + for b, n in PURPOSES}, + } + claimed = [(SINGLE_TAKE, "single_take"), (ALIGNED, "aligned"), (COMPLETE, "complete")] + stands = (all(not m["claims"] & b or verdicts[k] == "holds" for b, k in claimed) + and all(not m["purposes"] & b or verdicts["publishable"][n] == "holds" for b, n in PURPOSES)) + markers = [] + if verdicts["aligned"] == "holds": + for s in seen: + if s["ev"]["kind"] == MARKER: + at = position(m["chunks"], o, s["ev"]["t"]) + if at is not None: + markers.append({"event": s["ev"]["digest"].hex(), "t": s["ev"]["t"], "chunk": at[0], + "into_chunk": at[1], "into_master": at[2]}) + last = commits[-1][1] if commits else None + return {"outcome": "verdicts", "take": m["take"].hex(), "stream_id": stream_id(m["take"]), + "commits": [s["ev"]["digest"].hex() for s, _ in commits], + "size": last["size"] if last else 0, "root": (last["root"] if last else ZERO).hex(), + "verdicts": verdicts, "stands": stands, "markers": markers} + + +# ---------------------------------------------------------------- the corpus + +def problems_of(v): + """What differs between the vector's statement and this verifier's outcome.""" + try: + got = verify_take(v) + except Exception as e: # a crash on a mutated copy is a failure to read it + return ["the vector does not verify: %s: %s" % (type(e).__name__, e)], None + out = [k for k in got if v.get(k) != got[k]] + out += [k for k in ("outcome", "reason", "at") if k in v and k not in got] + return out, got + + +def check(doc, quiet=False): + """Every vector against its statement: the failures.""" + fails = [] + for v in doc["vectors"]: + problems, got = problems_of(v) + if not quiet: + what = "?" if got is None else got["outcome"] + (" " + got["reason"] if got["outcome"] == "refuse" else "") + print(("PASS" if not problems else "FAIL") + " vector %s: %s" % (v["name"], what)) + for k in problems: + fails.append("%s: %s is %s, the corpus states %s" % ( + v["name"], k, json.dumps(got.get(k))[:300] if got else k, json.dumps(v.get(k))[:300])) + return fails + + +def flip(h, at): + """Hexadecimal h with the byte at `at` (from the end when negative) changed.""" + b = bytearray(bytes.fromhex(h)) + b[at] ^= 0x01 + return b.hex() + + +def mutations(doc): + """Copies of the corpus, each with one defect a conforming verifier must catch.""" + names = {v["name"]: k for k, v in enumerate(doc["vectors"])} + lesson = names["lesson"] + + def mutate(label, f): + d = copy.deepcopy(doc) + f(d["vectors"]) + return label, d + + def device_chain(vs, k): + dev = doc["principals"]["device"] + return next(c for c in vs[k]["chains"] if LEV.read_record(bytes.fromhex(c[0]))["principal"].hex() == dev) + + out = [ + mutate("a byte of the lesson's chunk 2 part", lambda vs: vs[lesson]["parts"][2].update(bytes=flip(vs[lesson]["parts"][2]["bytes"], 5))), + mutate("the lesson's parts 0 and 1 swapped", lambda vs: vs[lesson]["parts"][0].update(bytes=vs[lesson]["parts"][1]["bytes"])), + mutate("the lesson's last part dropped", lambda vs: vs[lesson]["parts"].pop()), + mutate("a byte of the lesson's manifest signature", lambda vs: vs[lesson].update(manifest=flip(vs[lesson]["manifest"], -10))), + # Chunk 0's descriptor begins at byte 203 of a manifest (§7.1); byte 8 of it is `start`'s. + mutate("a byte of the lesson's chunk 0 descriptor", lambda vs: vs[lesson].update(manifest=flip(vs[lesson]["manifest"], 203 + 8))), + mutate("the lesson's sealed receipt removed", lambda vs: vs[lesson]["receipts"].pop()), + mutate("a byte of the lesson's consent", lambda vs: vs[lesson]["consents"].__setitem__(0, flip(vs[lesson]["consents"][0], 70))), + mutate("the lesson's second commitment not delivered", lambda vs: device_chain(vs, lesson).pop(1)), + mutate("the lesson evaluated a year on", lambda vs: vs[lesson].update(evaluated_at=vs[lesson]["evaluated_at"] + 365 * 86400)), + mutate("the lesson's stated root", lambda vs: vs[lesson].update(root="00" * 32)), + mutate("the lesson's stated stream id", lambda vs: vs[lesson].update(stream_id="0" + vs[lesson]["stream_id"][1:])), + mutate("the lesson's stated marker position", lambda vs: vs[lesson]["markers"][0].update(into_master=vs[lesson]["markers"][0]["into_master"] + 1)), + mutate("the missing chunk stated complete", lambda vs: vs[names["missing_chunk"]]["verdicts"].update(complete="holds")), + mutate("the late commitment stated single", lambda vs: vs[names["late_commit"]]["verdicts"].update(single_take="holds")), + mutate("the misaligned take stated aligned", lambda vs: vs[names["misaligned"]]["verdicts"].update(aligned="holds")), + mutate("the revoked consent stated publishable", lambda vs: vs[names["consent_revoked"]]["verdicts"]["publishable"].update(record="holds")), + mutate("the impostor's refusal at the manifest", lambda vs: vs[names["device_not_bound"]].update(at=["manifest"])), + mutate("the store outside its region stated listed", lambda vs: vs[names["store_outside_region"]].update(reason="store_not_listed")), + ] + return out + + +def main(corpus_dir): + fails = [] + st = ED._self_test() + print(("PASS" if not st else "FAIL") + " Ed25519 strict rule self-test " + ",".join(st)) + if st: + fails.append("ed25519 self-test") + with open(os.path.join(corpus_dir, "vectors.json"), encoding="utf-8") as f: + doc = json.load(f) + fails += check(doc) + seen = set() + for v in doc["vectors"]: + if v.get("reason"): + seen.add(v["reason"]) + if "verdicts" in v: + vd = v["verdicts"] + seen |= {vd["single_take"], vd["aligned"], vd["complete"]} | set(vd["publishable"].values()) + missing = [r for r in REASONS + ["delivery_gap"] if r not in seen] + if missing: + fails.append("no vector gives %s" % ", ".join(missing)) + takes = ["lesson", "resumed_upload", "minor_guardian"] + absent = [t for t in takes if not any(v["name"] == t and v.get("stands") for v in doc["vectors"])] + if absent: + fails.append("good takes that do not stand: %s" % ", ".join(absent)) + print("%s every reason of §12 appears, and every good take of §13 stands" % ("PASS" if not (missing or absent) else "FAIL")) + for label, mutated in mutations(doc): + changed = [v for v, o in zip(mutated["vectors"], doc["vectors"]) if v != o] + caught = check({"vectors": changed}, quiet=True) if changed else [] + print(("PASS" if caught else "FAIL") + " mutated copy fails: %s%s" % (label, " (%s)" % caught[0][:120] if caught else "")) + if not caught: + fails.append("a mutated copy verifies: %s" % label) + for f in fails: + print("FAIL " + f) + print(("PASS" if not fails else "FAIL") + " capture-binding corpus: %d vectors" % len(doc["vectors"])) + return 1 if fails else 0 + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("usage: capture_take_verify.py ", file=sys.stderr) + sys.exit(2) + sys.exit(main(sys.argv[1])) diff --git a/wai/live-conformance/events/README.md b/wai/live-conformance/events/README.md new file mode 100644 index 000000000..3c1a2c220 --- /dev/null +++ b/wai/live-conformance/events/README.md @@ -0,0 +1,98 @@ +# live-conformance/events — live events + +The corpus of [`extensions/live-events.md`](../../extensions/live-events.md) §10: `WEV1` +event records in stream order, the policies their principals are held to, and the outcome +a verifier gives them; `WEP1` policy records; and the records' bindings onto MoQ, LL-HLS +and CMAF/DASH. + +**Live-event equivalence.** For each vector, a conforming verifier of the vector's room, +holding each principal to the policy the vector names for it (`policies`, else +`default_policy`) and offered `events` one at a time in the order given, reaches the +outcome the vector states (§6.4): + +- `refuse`: the `reason` and the `index` of the first record refused (§6.1–§6.3, or §7's + `tally_mismatch` at the index of the `poll_close` whose stated counts the replay does not + reach); +- `gap`: no record refused, and the `gaps` (principal, first and last seq not held) in the + order found, under the code `delivery_gap` (§6.2); +- `accept`: no record refused, no gap, and every stated tally equal to the replay. + +A vector that does not refuse also states each record's SHA-256 digest (§3.2). An accepted +vector states the tally (§7): each poll's state and counts, and the BLAKE3 state hash of +the `wai.feed.state` records they replay to; and each record's MSF event timeline record, +`EXT-X-DATERANGE` tag and version 1 `emsg` box (§8), which a verifier must render byte for +byte and read back to the record. A verifier that reaches another outcome, reason, index, +gap, digest, tally or rendering does not conform. + +**Provenance.** Generated here: `wai_live_events_vectors gen` writes every record from +events authored in code, from fixed seeds. Each principal's key is SHA-256 of a fixed label +and the principal's index, each room id likewise, every time is a constant, and Ed25519 +signing is deterministic (RFC 8032), so the file is the same bytes on every machine. The +generator asserts that each vector reaches the outcome it was written to have before it +writes it. The SCTE 35-1 sections are built to that standard's syntax, with their CRC; the +SCTE 35-2 message is a stand-in byte string, which the extension carries opaque. No +recorded data. + +## Layout + +One file, `vectors.json`: + +- `t0_unix_us`, `pt0_ms`: the room's `t0` as microseconds since 1970 (for the MSF `t` + index and `START-DATE`), and the presentation time of `t0` in milliseconds (for + `emsg`). +- `principals`, `rooms`: the keys and room ids, by name (informative). +- `policies`: the policy records the vectors name, in hexadecimal: `default` (§5's + defaults), `authority` (the defaults with the lifecycle kinds), `chat_only` (chat, + reaction and vote) and `slow` (the defaults with `max_events` 3). +- `vectors`: each with `name`, `about`, `room`, `default_policy`, `policies` (principal + key → policy name), `events` (records in hexadecimal, in stream order), `outcome`, and + as above `reason`, `index`, `gaps`, `digests`, `tally` and `bindings` (per record: + `msf`, `daterange`, and `emsg` in hexadecimal). +- `policy_cases`: policy records (§5), each read (`accept`) or refused with its reason. +- `binding_cases`: an `input` for one `binding` (`daterange`, `emsg` in hexadecimal, or + `msf`), read back to its `record` or refused with its reason (§8). + +Vectors: + +- one accepted vector per kind of §4 (`kind_*`): metadata that is empty, anchored, and at the + default bound; cues of every type, with and without an SCTE-35 message of each form; chat across + scripts and at the text bound; standalone reactions exactly one window apart and targeted + ones; a poll with a changed vote, a vote after the close and a vote for no poll, closed + with its tally, and a poll left open; markers with and without an attachment; every + control command; captions of each origin; moderation decisions; take commitments; and + the lifecycle kinds under the authority's policy; +- `room_interleaved`: several principals' chains interleaved in delivery order across + three one-minute groups, with anchored events and a poll; +- `join_set_repeats` and `joiner_mid_stream`: one host's track as a continuous subscriber + receives it, with each group's first object repeating its join set (§8.2), and as a + subscriber that joins at group 1 receives it, which reports what it does not hold as + gaps; +- `chain_gap`: a chain with a seq not delivered; +- one negative control per refusal, each a single defect refused with its reason: a + flipped signature bit; three forgeries a lenient Ed25519 verifier accepts (an identity + key, its non-canonical spelling, an `R` of small order); a broken chain and a broken + genesis; a reorder; a replayed seq; `t` going back; an oversize payload; a kind not + permitted, and a lifecycle kind from a participant; the event rate and the reaction rate + exceeded; an overlong and a surrogate UTF-8 encoding; text over the bound; two + truncations; an unknown version; a bad magic, trailing bytes and a bad anchor flag; + an unknown kind and a reserved lifecycle kind; the wrong room; a malformed cue, + language tag and poll; and a stated tally the replay does not reach. + +## Running + +``` +cd ../../wai-rs +cargo run --no-default-features --features live_events --bin wai_live_events_vectors -- verify ../live-conformance/events +cargo run --no-default-features --features live_events --bin wai_live_events_vectors -- gen ../live-conformance/events # regenerate +cargo test --no-default-features --features live_events --test live_events +cd ../live-conformance +python3 live_events_verify.py events +``` + +`wai_live_events_vectors verify` and `tests/live_events.rs` require the file to regenerate +byte for byte and `wai-rs` to give every case its outcome; the test also requires the +corpus to cover every kind and every reason, and the extension's §9 to list exactly the +reasons the reference reports. `live_events_verify.py` is the second implementation, +written from the extension's text and sharing no code with `wai-rs`: it gives every case +the same outcome, renders every binding itself, and requires the same coverage. Pass = an +exit status of 0 from each. diff --git a/wai/live-conformance/events/vectors.json b/wai/live-conformance/events/vectors.json new file mode 100644 index 000000000..10c8fcd9c --- /dev/null +++ b/wai/live-conformance/events/vectors.json @@ -0,0 +1,1792 @@ +{ + "corpus": "wai.live.events", + "extension": "extensions/live-events.md", + "t0_unix_us": 1792108800000000, + "pt0_ms": 10000, + "principals": { + "authority": "6ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b", + "host": "6ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e", + "alice": "c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93", + "bob": "b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765", + "carol": "07122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139", + "moderator": "24e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed44389" + }, + "rooms": { + "main": "994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31", + "other": "58a1ba0add8243923508c73998bf334d7db0e3035fa4ebd1e6e993b13f058273" + }, + "policies": { + "default": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "authority": "5745503101fe1f7f00000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "chat_only": "574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "slow": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4010300000040420f00000000000100000040420f0000000000" + }, + "vectors": [ + { + "name": "kind_meta", + "about": "meta (§4.2): an empty payload, an anchored one, and one of exactly the default bound of 1024 bytes", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000001000062b00ccd7e486829c12dcdcb17bba6d53ab7a5c949f37194f0f6edd89e807998b24a796062694908c96cf6c0cce6a49b91a64fd87715c50d5b73d67a10d2500c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000b102d74538244c25c31a06f317c58e54610630f6fec8cb6b180ccaa7bc7275bc80841e000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb6000000000000000030000000000000000114007363656e653d696e74726f3b63616d6572613d32fd66d347c694492ffd7a5792a6aceceb20ce5cae2d7ec5a66ca3d7209df351b9510874861b9dc8ed477d5058341c24804a1b8d5a0b61952994b03dc5381d2d0c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000009725cf16dc3a60b603115720e2c20167f7d7731b6f684a47542fe6037907dfe1c0c62d00000000000001000400070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f95595206fadfc9e70714f7f0ab9b801826122546dd6895839bb11c33e5c2250613aae4d7f73588e2c780bb2abbadefbff36297882dce024550f52cdced5e96f0f" + ], + "outcome": "accept", + "digests": [ + "b102d74538244c25c31a06f317c58e54610630f6fec8cb6b180ccaa7bc7275bc", + "9725cf16dc3a60b603115720e2c20167f7d7731b6f684a47542fe6037907dfe1", + "05bb58535d832d838df41a582f5954f31f35abf17911ded6691858e15b5a43f8" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAEAAGKwDM1-SGgpwS3Nyxe7ptU6t6XJSfNxlPD27diegHmYskp5YGJpSQjJbPbAzOakm5GmT9h3FcUNW3PWehDSUAw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"b102d74538244c25c31a06f317c58e54610630f6fec8cb6b180ccaa7bc7275bc\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAEAAGKwDM1-SGgpwS3Nyxe7ptU6t6XJSfNxlPD27diegHmYskp5YGJpSQjJbPbAzOakm5GmT9h3FcUNW3PWehDSUAw\"", + "emsg": "000000ee656d736701000000000003e80000000000002af800000000b102d74575726e3a7761693a6576656e743a31006d657461005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000001000062b00ccd7e486829c12dcdcb17bba6d53ab7a5c949f37194f0f6edd89e807998b24a796062694908c96cf6c0cce6a49b91a64fd87715c50d5b73d67a10d2500c" + }, + { + "msf": "{\"l\":[0,48],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAACxAtdFOCRMJcMaBvMXxY5UYQYw9v7Iy2sYDMqnvHJ1vICEHgAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAAwAAAAAAAAAAEUAHNjZW5lPWludHJvO2NhbWVyYT0y_WbTR8aUSS_9eleSpqzs6yDOXK4tfsWmbKPXIJ3zUblRCHSGG53I7Ud9UFg0HCSAShuNWgthlSmUsD3FOB0tDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"9725cf16dc3a60b603115720e2c20167f7d7731b6f684a47542fe6037907dfe1\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAACxAtdFOCRMJcMaBvMXxY5UYQYw9v7Iy2sYDMqnvHJ1vICEHgAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAAwAAAAAAAAAAEUAHNjZW5lPWludHJvO2NhbWVyYT0y_WbTR8aUSS_9eleSpqzs6yDOXK4tfsWmbKPXIJ3zUblRCHSGG53I7Ud9UFg0HCSAShuNWgthlSmUsD3FOB0tDA\"", + "emsg": "00000132656d736701000000000003e80000000000002ee0000000009725cf1675726e3a7761693a6576656e743a31006d657461005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000b102d74538244c25c31a06f317c58e54610630f6fec8cb6b180ccaa7bc7275bc80841e000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb6000000000000000030000000000000000114007363656e653d696e74726f3b63616d6572613d32fd66d347c694492ffd7a5792a6aceceb20ce5cae2d7ec5a66ca3d7209df351b9510874861b9dc8ed477d5058341c24804a1b8d5a0b61952994b03dc5381d2d0c" + }, + { + "msf": "{\"t\":1792108803000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACXJc8W3DpgtgMRVyDiwgFn99dzG29oSkdUL-YDeQff4cDGLQAAAAAAAAEABAAHDhUcIyoxOD9GTVRbYmlwd36FjJOaoaivtr3Ey9LZ4Ofu9fwDChEYHyYtNDtCSVBXXmVsc3qBiI-WnaSrsrnAx87V3OPq8fj_Bg0UGyIpMDc-RUxTWmFob3Z9hIuSmaCnrrW8w8rR2N_m7fT7AgkQFx4lLDM6QUhPVl1ka3J5gIeOlZyjqrG4v8bN1Nvi6fD3_gUMExohKC82PURLUllgZ251fIOKkZifpq20u8LJ0Nfe5ezz-gEIDxYdJCsyOUBHTlVcY2pxeH-GjZSboqmwt77FzNPa4ejv9v0ECxIZICcuNTxDSlFYX2ZtdHuCiZCXnqWss7rByM_W3eTr8vkABw4VHCMqMTg_Rk1UW2JpcHd-hYyTmqGor7a9xMvS2eDn7vX8AwoRGB8mLTQ7QklQV15lbHN6gYiPlp2kq7K5wMfO1dzj6vH4_wYNFBsiKTA3PkVMU1phaG92fYSLkpmgp661vMPK0djf5u30-wIJEBceJSwzOkFIT1ZdZGtyeYCHjpWco6qxuL_GzdTb4unw9_4FDBMaISgvNj1ES1JZYGdudXyDipGYn6attLvCydDX3uXs8_oBCA8WHSQrMjlAR05VXGNqcXh_ho2Um6KpsLe-xczT2uHo7_b9BAsSGSAnLjU8Q0pRWF9mbXR7gomQl56lrLO6wcjP1t3k6_L5AAcOFRwjKjE4P0ZNVFtiaXB3foWMk5qhqK-2vcTL0tng5-71_AMKERgfJi00O0JJUFdeZWxzeoGIj5adpKuyucDHztXc4-rx-P8GDRQbIikwNz5FTFNaYWhvdn2Ei5KZoKeutbzDytHY3-bt9PsCCRAXHiUsMzpBSE9WXWRrcnmAh46VnKOqsbi_xs3U2-Lp8Pf-BQwTGiEoLzY9REtSWWBnbnV8g4qRmJ-mrbS7wsnQ197l7PP6AQgPFh0kKzI5QEdOVVxjanF4f4aNlJuiqbC3vsXM09rh6O_2_QQLEhkgJy41PENKUVhfZm10e4KJkJeepayzusHIz9bd5Ovy-QAHDhUcIyoxOD9GTVRbYmlwd36FjJOaoaivtr3Ey9LZ4Ofu9fwDChEYHyYtNDtCSVBXXmVsc3qBiI-WnaSrsrnAx87V3OPq8fj_Bg0UGyIpMDc-RUxTWmFob3Z9hIuSmaCnrrW8w8rR2N_m7fT7AgkQFx4lLDM6QUhPVl1ka3J5gIeOlZyjqrG4v8bN1Nvi6fD3_gUMExohKC82PURLUllgZ251fIOKkZifpq20u8LJ0Nfe5ezz-gEIDxYdJCsyOUBHTlVcY2pxeH-GjZSboqmwt77FzNPa4ejv9v0ECxIZICcuNTxDSlFYX2ZtdHuCiZCXnqWss7rByM_W3eTr8vlVlSBvrfyecHFPfwq5uAGCYSJUbdaJWDm7EcM-XCJQYTquTX9zWI4seAuyq7re-_82KXiC3OAkVQ9Szc7V6W8P\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"05bb58535d832d838df41a582f5954f31f35abf17911ded6691858e15b5a43f8\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACXJc8W3DpgtgMRVyDiwgFn99dzG29oSkdUL-YDeQff4cDGLQAAAAAAAAEABAAHDhUcIyoxOD9GTVRbYmlwd36FjJOaoaivtr3Ey9LZ4Ofu9fwDChEYHyYtNDtCSVBXXmVsc3qBiI-WnaSrsrnAx87V3OPq8fj_Bg0UGyIpMDc-RUxTWmFob3Z9hIuSmaCnrrW8w8rR2N_m7fT7AgkQFx4lLDM6QUhPVl1ka3J5gIeOlZyjqrG4v8bN1Nvi6fD3_gUMExohKC82PURLUllgZ251fIOKkZifpq20u8LJ0Nfe5ezz-gEIDxYdJCsyOUBHTlVcY2pxeH-GjZSboqmwt77FzNPa4ejv9v0ECxIZICcuNTxDSlFYX2ZtdHuCiZCXnqWss7rByM_W3eTr8vkABw4VHCMqMTg_Rk1UW2JpcHd-hYyTmqGor7a9xMvS2eDn7vX8AwoRGB8mLTQ7QklQV15lbHN6gYiPlp2kq7K5wMfO1dzj6vH4_wYNFBsiKTA3PkVMU1phaG92fYSLkpmgp661vMPK0djf5u30-wIJEBceJSwzOkFIT1ZdZGtyeYCHjpWco6qxuL_GzdTb4unw9_4FDBMaISgvNj1ES1JZYGdudXyDipGYn6attLvCydDX3uXs8_oBCA8WHSQrMjlAR05VXGNqcXh_ho2Um6KpsLe-xczT2uHo7_b9BAsSGSAnLjU8Q0pRWF9mbXR7gomQl56lrLO6wcjP1t3k6_L5AAcOFRwjKjE4P0ZNVFtiaXB3foWMk5qhqK-2vcTL0tng5-71_AMKERgfJi00O0JJUFdeZWxzeoGIj5adpKuyucDHztXc4-rx-P8GDRQbIikwNz5FTFNaYWhvdn2Ei5KZoKeutbzDytHY3-bt9PsCCRAXHiUsMzpBSE9WXWRrcnmAh46VnKOqsbi_xs3U2-Lp8Pf-BQwTGiEoLzY9REtSWWBnbnV8g4qRmJ-mrbS7wsnQ197l7PP6AQgPFh0kKzI5QEdOVVxjanF4f4aNlJuiqbC3vsXM09rh6O_2_QQLEhkgJy41PENKUVhfZm10e4KJkJeepayzusHIz9bd5Ovy-QAHDhUcIyoxOD9GTVRbYmlwd36FjJOaoaivtr3Ey9LZ4Ofu9fwDChEYHyYtNDtCSVBXXmVsc3qBiI-WnaSrsrnAx87V3OPq8fj_Bg0UGyIpMDc-RUxTWmFob3Z9hIuSmaCnrrW8w8rR2N_m7fT7AgkQFx4lLDM6QUhPVl1ka3J5gIeOlZyjqrG4v8bN1Nvi6fD3_gUMExohKC82PURLUllgZ251fIOKkZifpq20u8LJ0Nfe5ezz-gEIDxYdJCsyOUBHTlVcY2pxeH-GjZSboqmwt77FzNPa4ejv9v0ECxIZICcuNTxDSlFYX2ZtdHuCiZCXnqWss7rByM_W3eTr8vlVlSBvrfyecHFPfwq5uAGCYSJUbdaJWDm7EcM-XCJQYTquTX9zWI4seAuyq7re-_82KXiC3OAkVQ9Szc7V6W8P\"", + "emsg": "000004ee656d736701000000000003e800000000000032c80000000005bb585375726e3a7761693a6576656e743a31006d657461005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000009725cf16dc3a60b603115720e2c20167f7d7731b6f684a47542fe6037907dfe1c0c62d00000000000001000400070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f900070e151c232a31383f464d545b626970777e858c939aa1a8afb6bdc4cbd2d9e0e7eef5fc030a11181f262d343b424950575e656c737a81888f969da4abb2b9c0c7ced5dce3eaf1f8ff060d141b222930373e454c535a61686f767d848b9299a0a7aeb5bcc3cad1d8dfe6edf4fb020910171e252c333a41484f565d646b727980878e959ca3aab1b8bfc6cdd4dbe2e9f0f7fe050c131a21282f363d444b525960676e757c838a91989fa6adb4bbc2c9d0d7dee5ecf3fa01080f161d242b323940474e555c636a71787f868d949ba2a9b0b7bec5ccd3dae1e8eff6fd040b121920272e353c434a51585f666d747b828990979ea5acb3bac1c8cfd6dde4ebf2f95595206fadfc9e70714f7f0ab9b801826122546dd6895839bb11c33e5c2250613aae4d7f73588e2c780bb2abbadefbff36297882dce024550f52cdced5e96f0f" + } + ] + }, + { + "name": "kind_cue", + "about": "cue (§4.3): an anchored splice out with a planned duration and its splice_insert() section, the splice back in with the actual duration, a chapter with no SCTE-35 message, a chapter carrying a time_signal() section, and a break carrying an opaque SCTE 35-2 message", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000006b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6005a62020000000000022a00026500000030750000011e00fc301b00000000000000fff00a05000000657f5f0001000000000578591113e7fd439bc60bf056814c10a0b4ee10af0b07c2ada7eaf195b3c8f7db1367f4daf6294150dc21cbd9876112804571d90ffa31f0804d0617edbdf3c86f7c320a", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000008a63d5ccd8fa1b9916e4132ca3f0341a269ea7d57802d8d47d1b97b3bdcdf8a540a5ae020000000000020a000366000000c0d401000001806c6271f9ee7cc8a58326738cf445f9d7f072705ecbdafef54a2c20e419aae7e9250c96d78ed6ff313dcd94ebd2a8c95ff2c69bfc9f7c7f52557f5682360d", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e030000000000000064d6d4d06d13e1191ff0d5df524daed37fa6c33a9e3a8662d8b852d73ca53ce980f0fa020000000000022100036700000000000000011500fc301200000000000000fff001067f000031c853bcf618c2eebc82db2b1a2257560e92eb700244fd19e912f2950948dc304fec84e1b9fe24aa2a78b53cb6c33a586f91b67bcf8d4731078bb6bbef1df5be7777a808", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0400000000000000edbf32e54dfc2333add11ecd0974c3f450a00b6e86498977dcd51418fac79199c03b470300000000000224000468000000983a000002180056d94bd9440e623638f78b8a1cde4ad1d59e4ae5a52ffbda242b2aed0a0700e63ef8ea73c7f25e554419c62c0a07ef99c2046c32b32943fefcfc7ab9bef11b77956b60d65a0934636a87f661d695240f9e6623fc58ac3305" + ], + "outcome": "accept", + "digests": [ + "6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6", + "8a63d5ccd8fa1b9916e4132ca3f0341a269ea7d57802d8d47d1b97b3bdcdf8a5", + "64d6d4d06d13e1191ff0d5df524daed37fa6c33a9e3a8662d8b852d73ca53ce9", + "edbf32e54dfc2333add11ecd0974c3f450a00b6e86498977dcd51418fac79199", + "c835d627aa5f35b6b8599eead697fac8edded0c681fc475109fbd312d8baf7bf" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"l\":[0,240],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "emsg": "0000014c656d736701000000000003e80000000000004e20000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c" + }, + { + "msf": "{\"t\":1792108840000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAABrRqMJkUmRXnjBt47CdS0Lvu1OU8bEtaUiWojlen7j1gBaYgIAAAAAAAIqAAJlAAAAMHUAAAEeAPwwGwAAAAAAAAD_8AoFAAAAZX9fAAEAAAAABXhZERPn_UObxgvwVoFMEKC07hCvCwfCrafq8ZWzyPfbE2f02vYpQVDcIcvZh2ESgEVx2Q_6MfCATQYX7b3zyG98Mgo\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8a63d5ccd8fa1b9916e4132ca3f0341a269ea7d57802d8d47d1b97b3bdcdf8a5\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:40.000Z\",DURATION=30.000,SCTE35-IN=0xFC301B00000000000000FFF00A05000000657F5F00010000000005785911,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAABrRqMJkUmRXnjBt47CdS0Lvu1OU8bEtaUiWojlen7j1gBaYgIAAAAAAAIqAAJlAAAAMHUAAAEeAPwwGwAAAAAAAAD_8AoFAAAAZX9fAAEAAAAABXhZERPn_UObxgvwVoFMEKC07hCvCwfCrafq8ZWzyPfbE2f02vYpQVDcIcvZh2ESgEVx2Q_6MfCATQYX7b3zyG98Mgo\"", + "emsg": "00000117656d736701000000000003e8000000000000c350000075308a63d5cc75726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000006b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6005a62020000000000022a00026500000030750000011e00fc301b00000000000000fff00a05000000657f5f0001000000000578591113e7fd439bc60bf056814c10a0b4ee10af0b07c2ada7eaf195b3c8f7db1367f4daf6294150dc21cbd9876112804571d90ffa31f0804d0617edbdf3c86f7c320a" + }, + { + "msf": "{\"t\":1792108845000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACKY9XM2PobmRbkEyyj8DQaJp6n1XgC2NR9G5ezvc34pUClrgIAAAAAAAIKAANmAAAAwNQBAAABgGxicfnufMilgyZzjPRF-dfwcnBey9r-9UosIOQZqufpJQyW147W_zE9zZTr0qjJX_LGm_yffH9SVX9WgjYN\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"64d6d4d06d13e1191ff0d5df524daed37fa6c33a9e3a8662d8b852d73ca53ce9\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:45.000Z\",DURATION=120.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACKY9XM2PobmRbkEyyj8DQaJp6n1XgC2NR9G5ezvc34pUClrgIAAAAAAAIKAANmAAAAwNQBAAABgGxicfnufMilgyZzjPRF-dfwcnBey9r-9UosIOQZqufpJQyW147W_zE9zZTr0qjJX_LGm_yffH9SVX9WgjYN\"", + "emsg": "000000f7656d736701000000000003e8000000000000d6d80001d4c064d6d4d075726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000008a63d5ccd8fa1b9916e4132ca3f0341a269ea7d57802d8d47d1b97b3bdcdf8a540a5ae020000000000020a000366000000c0d401000001806c6271f9ee7cc8a58326738cf445f9d7f072705ecbdafef54a2c20e419aae7e9250c96d78ed6ff313dcd94ebd2a8c95ff2c69bfc9f7c7f52557f5682360d" + }, + { + "msf": "{\"t\":1792108850000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAABk1tTQbRPhGR_w1d9STa7Tf6bDOp46hmLYuFLXPKU86YDw-gIAAAAAAAIhAANnAAAAAAAAAAEVAPwwEgAAAAAAAAD_8AEGfwAAMchTvPYYwu68gtsrGiJXVg6S63ACRP0Z6RLylQlI3DBP7IThuf4kqip4tTy2wzpYb5G2e8-NRzEHi7a77x31vnd3qAg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"edbf32e54dfc2333add11ecd0974c3f450a00b6e86498977dcd51418fac79199\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:50.000Z\",SCTE35-CMD=0xFC301200000000000000FFF001067F000031C853BC,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAABk1tTQbRPhGR_w1d9STa7Tf6bDOp46hmLYuFLXPKU86YDw-gIAAAAAAAIhAANnAAAAAAAAAAEVAPwwEgAAAAAAAAD_8AEGfwAAMchTvPYYwu68gtsrGiJXVg6S63ACRP0Z6RLylQlI3DBP7IThuf4kqip4tTy2wzpYb5G2e8-NRzEHi7a77x31vnd3qAg\"", + "emsg": "0000010e656d736701000000000003e8000000000000ea60ffffffffedbf32e575726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e030000000000000064d6d4d06d13e1191ff0d5df524daed37fa6c33a9e3a8662d8b852d73ca53ce980f0fa020000000000022100036700000000000000011500fc301200000000000000fff001067f000031c853bcf618c2eebc82db2b1a2257560e92eb700244fd19e912f2950948dc304fec84e1b9fe24aa2a78b53cb6c33a586f91b67bcf8d4731078bb6bbef1df5be7777a808" + }, + { + "msf": "{\"t\":1792108855000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAADtvzLlTfwjM63RHs0JdMP0UKALboZJiXfc1RQY-seRmcA7RwMAAAAAAAIkAARoAAAAmDoAAAIYAFbZS9lEDmI2OPeLihzeStHVnkrlpS_72iQrKu0KBwDmPvjqc8fyXlVEGcYsCgfvmcIEbDKzKUP-_Px6ub7xG3eVa2DWWgk0Y2qH9mHWlSQPnmYj_FisMwU\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"c835d627aa5f35b6b8599eead697fac8edded0c681fc475109fbd312d8baf7bf\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:55.000Z\",PLANNED-DURATION=15.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAADtvzLlTfwjM63RHs0JdMP0UKALboZJiXfc1RQY-seRmcA7RwMAAAAAAAIkAARoAAAAmDoAAAIYAFbZS9lEDmI2OPeLihzeStHVnkrlpS_72iQrKu0KBwDmPvjqc8fyXlVEGcYsCgfvmcIEbDKzKUP-_Px6ub7xG3eVa2DWWgk0Y2qH9mHWlSQPnmYj_FisMwU\"", + "emsg": "00000111656d736701000000000003e8000000000000fde800003a98c835d62775726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0400000000000000edbf32e54dfc2333add11ecd0974c3f450a00b6e86498977dcd51418fac79199c03b470300000000000224000468000000983a000002180056d94bd9440e623638f78b8a1cde4ad1d59e4ae5a52ffbda242b2aed0a0700e63ef8ea73c7f25e554419c62c0a07ef99c2046c32b32943fefcfc7ab9bef11b77956b60d65a0934636a87f661d695240f9e6623fc58ac3305" + } + ] + }, + { + "name": "kind_chat", + "about": "chat (§4.4): ASCII, text across scripts with a character outside the Basic Multilingual Plane, exactly the default bound of 500 code points (1000 bytes), and the empty text", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030e000c0048656c6c6f2c20726f6f6d2e7521018c0d385cdd1eb0e6d27f7a48f0b562b51afc76fb5b6794ce335b1aedaedd7538ab98dd92a7e50252862ea94ef86341293bd8a981de6f2ef93d97c66000", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93010000000000000052eb27011057019fa05f50319e9e2f3072449af1da63ed07ad861617ea3e6a1c80841e0000000000000320001e00c39c6ec3af63c3b664c3a920e29c9320e697a5e69cace8aa9e20f09f8eb55cc27da35e58388b8c9469694a1da10d0ea0b33f3193396e0e592f7cada29b71f8ad483dd083af6273aa91352e6db0460eb8b52ec960e662adaccac1b5f6d10c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000b253382cfe6873b944dd48e5ca2f848313664a78d3a7ffe5e4aed3dc98798a0fc0c62d00000000000003ea03e803c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a95908c7028dec8e20f7c884f34c34a953e0f6cd2e0db0fc89d465ec3642ec8c0fa2c65e118133c6938736dbc135bc4b181510cb5d9985f1f8d3f8b7e7835b3f0c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93030000000000000096b85ad97a97088039f60fc05e3cee26cd4edb8e4508bf5245377fe71708757400093d000000000000030200000011ed819d1eecdd3e0d6a982cfc2879cf2f7c8773cebe3e511240a5e5fda45266dd3f1c2a6c8446be2943c51a5bb964d27f52fb7347a144bb29399b3b1ce24d04" + ], + "outcome": "accept", + "digests": [ + "52eb27011057019fa05f50319e9e2f3072449af1da63ed07ad861617ea3e6a1c", + "b253382cfe6873b944dd48e5ca2f848313664a78d3a7ffe5e4aed3dc98798a0f", + "96b85ad97a97088039f60fc05e3cee26cd4edb8e4508bf5245377fe717087574", + "1ea6ce872c05f7ae6424aa8e470c426a1598a76ef187fd57f186a19cdfc6ef24" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMOAAwASGVsbG8sIHJvb20udSEBjA04XN0esObSf3pI8LVitRr8dvtbZ5TOM1sa7a7ddTirmN2Sp-UCUoYuqU74Y0EpO9ipgd5vLvk9l8ZgAA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"52eb27011057019fa05f50319e9e2f3072449af1da63ed07ad861617ea3e6a1c\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMOAAwASGVsbG8sIHJvb20udSEBjA04XN0esObSf3pI8LVitRr8dvtbZ5TOM1sa7a7ddTirmN2Sp-UCUoYuqU74Y0EpO9ipgd5vLvk9l8ZgAA\"", + "emsg": "000000fc656d736701000000000003e80000000000002af80000000052eb270175726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030e000c0048656c6c6f2c20726f6f6d2e7521018c0d385cdd1eb0e6d27f7a48f0b562b51afc76fb5b6794ce335b1aedaedd7538ab98dd92a7e50252862ea94ef86341293bd8a981de6f2ef93d97c66000" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABS6ycBEFcBn6BfUDGeni8wckSa8dpj7QethhYX6j5qHICEHgAAAAAAAAMgAB4Aw5xuw69jw7Zkw6kg4pyTIOaXpeacrOiqniDwn461XMJ9o15YOIuMlGlpSh2hDQ6gsz8xkzluDlkvfK2im3H4rUg90IOvYnOqkTUubbBGDri1Lslg5mKtrMrBtfbRDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"b253382cfe6873b944dd48e5ca2f848313664a78d3a7ffe5e4aed3dc98798a0f\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABS6ycBEFcBn6BfUDGeni8wckSa8dpj7QethhYX6j5qHICEHgAAAAAAAAMgAB4Aw5xuw69jw7Zkw6kg4pyTIOaXpeacrOiqniDwn461XMJ9o15YOIuMlGlpSh2hDQ6gsz8xkzluDlkvfK2im3H4rUg90IOvYnOqkTUubbBGDri1Lslg5mKtrMrBtfbRDA\"", + "emsg": "0000010e656d736701000000000003e80000000000002ee000000000b253382c75726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93010000000000000052eb27011057019fa05f50319e9e2f3072449af1da63ed07ad861617ea3e6a1c80841e0000000000000320001e00c39c6ec3af63c3b664c3a920e29c9320e697a5e69cace8aa9e20f09f8eb55cc27da35e58388b8c9469694a1da10d0ea0b33f3193396e0e592f7cada29b71f8ad483dd083af6273aa91352e6db0460eb8b52ec960e662adaccac1b5f6d10c" + }, + { + "msf": "{\"t\":1792108803000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAACyUzgs_mhzuUTdSOXKL4SDE2ZKeNOn_-XkrtPcmHmKD8DGLQAAAAAAAAPqA-gDw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqVkIxwKN7I4g98iE80w0qVPg9s0uDbD8idRl7DZC7IwPosZeEYEzxpOHNtvBNbxLGBUQy12ZhfH40_i354NbPww\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"96b85ad97a97088039f60fc05e3cee26cd4edb8e4508bf5245377fe717087574\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAACyUzgs_mhzuUTdSOXKL4SDE2ZKeNOn_-XkrtPcmHmKD8DGLQAAAAAAAAPqA-gDw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqcOpw6nDqVkIxwKN7I4g98iE80w0qVPg9s0uDbD8idRl7DZC7IwPosZeEYEzxpOHNtvBNbxLGBUQy12ZhfH40_i354NbPww\"", + "emsg": "000004d8656d736701000000000003e800000000000032c80000000096b85ad975726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000b253382cfe6873b944dd48e5ca2f848313664a78d3a7ffe5e4aed3dc98798a0fc0c62d00000000000003ea03e803c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a9c3a95908c7028dec8e20f7c884f34c34a953e0f6cd2e0db0fc89d465ec3642ec8c0fa2c65e118133c6938736dbc135bc4b181510cb5d9985f1f8d3f8b7e7835b3f0c" + }, + { + "msf": "{\"t\":1792108804000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAACWuFrZepcIgDn2D8BePO4mzU7bjkUIv1JFN3_nFwh1dAAJPQAAAAAAAAMCAAAAEe2BnR7s3T4Napgs_Ch5zy98h3POvj5REkCl5f2kUmbdPxwqbIRGvilDxRpbuWTSf1L7c0ehRLspOZs7HOJNBA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"1ea6ce872c05f7ae6424aa8e470c426a1598a76ef187fd57f186a19cdfc6ef24\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAACWuFrZepcIgDn2D8BePO4mzU7bjkUIv1JFN3_nFwh1dAAJPQAAAAAAAAMCAAAAEe2BnR7s3T4Napgs_Ch5zy98h3POvj5REkCl5f2kUmbdPxwqbIRGvilDxRpbuWTSf1L7c0ehRLspOZs7HOJNBA\"", + "emsg": "000000f0656d736701000000000003e800000000000036b0000000001ea6ce8775726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93030000000000000096b85ad97a97088039f60fc05e3cee26cd4edb8e4508bf5245377fe71708757400093d000000000000030200000011ed819d1eecdd3e0d6a982cfc2879cf2f7c8773cebe3e511240a5e5fda45266dd3f1c2a6c8446be2943c51a5bb964d27f52fb7347a144bb29399b3b1ce24d04" + } + ] + }, + { + "name": "kind_reaction", + "about": "reaction (§4.5): standalone reactions exactly one window apart (the default rate of one per second), reactions targeting a chat event and one retracting, which the standalone rate does not count", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003060004006e696365c689cab61d4b14b2ab107dd46012b04f8b62debaf14a473daf42f5c6e4e726420131faf6bdb125fbff56807f30dd28db1a1ee9eedeec657d8f6a1ba9a51b3b04", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a804f1200000000000004040001010000fb580f38a33be3a33396fc4cd20d3b7501d7236a53b4910bfbef8d5ab6897d91d447cdc792a0d3b3f6c0bf4cde2f113373f1a9685a4160c3f933837bc67d520f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9302000000000000005a4db20df3a36ca3323b5df1d5eb81ad3ba87c3910aad97b55f2dbfc112f726420d61300000000000004240001030001561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a8f2e7de683ec9166b5bea36dc409f324b780f6490cee53e99a610e6c1b89a658186d6f870905054e40b4ebcfdadcb665f35641c6021edd8f204a43679c8acf0c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300000000000000788174d766cb50e18385920d650fe9eb3db7583a2473e54c269c03e05267c50ec0912100000000000004040003010000630fee2818aa212365e85231e87d01f486084e458917f014d1ea20a081c3b41fbec505bfa66080059bb44b97e2d04574701ae15ebbf9192413fae5294297600b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9304000000000000007e29a8c76a42b1bb582b165e5330b5de00e4b01a82cd814895d7bf4ebaf1fcc5a0252600000000000004240001030003561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a80896a735ceddcac4f168c26e2d6b9b2a9192d7cc2436c66bd65547652436f96ede2d90906a0354df705df604b21280eb90ebab66e0c5bd97628db9cbfda830f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93050000000000000086efbf695ef6cfff2c102cbd9a7430599e2110ea68c4d8947c78ca2e9057ee1d00d43000000000000004040004010000d75b0925403f4825257a49b09b05f295f7849ca7300c1e680c53293270b99ab01c3b79c494749a1b4dd5569701a96916978e4eaf40fc3500a06d3f2e5ab02e0b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930600000000000000b94deefa68c46665e0a0b7ea3889a37511a95b0ab3d768edde80444b650362ebe09c4100000000000004040005c8000012fee850bc1d3eafa034bcec2b9699280eb5f58649de68bb73d47ff4ac96c6cba114efdd8b115453e11925840dcbfb61db91b507c76c4d6bdf1b13ad69d2b50a" + ], + "outcome": "accept", + "digests": [ + "561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a", + "5a4db20df3a36ca3323b5df1d5eb81ad3ba87c3910aad97b55f2dbfc112f7264", + "788174d766cb50e18385920d650fe9eb3db7583a2473e54c269c03e05267c50e", + "7e29a8c76a42b1bb582b165e5330b5de00e4b01a82cd814895d7bf4ebaf1fcc5", + "86efbf695ef6cfff2c102cbd9a7430599e2110ea68c4d8947c78ca2e9057ee1d", + "b94deefa68c46665e0a0b7ea3889a37511a95b0ab3d768edde80444b650362eb", + "0b47f47e933d7446d2474f0c1ce5d817702bee9aa082b5cfb6fdbde5d75fc708" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMGAAQAbmljZcaJyrYdSxSyqxB91GASsE-LYt668UpHPa9C9cbk5yZCATH69r2xJfv_VoB_MN0o2xoe6e7e7GV9j2obqaUbOwQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMGAAQAbmljZcaJyrYdSxSyqxB91GASsE-LYt668UpHPa9C9cbk5yZCATH69r2xJfv_VoB_MN0o2xoe6e7e7GV9j2obqaUbOwQ\"", + "emsg": "000000f4656d736701000000000003e80000000000002af8000000005618534575726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003060004006e696365c689cab61d4b14b2ab107dd46012b04f8b62debaf14a473daf42f5c6e4e726420131faf6bdb125fbff56807f30dd28db1a1ee9eedeec657d8f6a1ba9a51b3b04" + }, + { + "msf": "{\"t\":1792108801200,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeoBPEgAAAAAAAAQEAAEBAAD7WA84ozvjozOW_EzSDTt1AdcjalO0kQv7741atol9kdRHzceSoNOz9sC_TN4vETNz8aloWkFgw_kzg3vGfVIP\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"5a4db20df3a36ca3323b5df1d5eb81ad3ba87c3910aad97b55f2dbfc112f7264\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.200Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeoBPEgAAAAAAAAQEAAEBAAD7WA84ozvjozOW_EzSDTt1AdcjalO0kQv7741atol9kdRHzceSoNOz9sC_TN4vETNz8aloWkFgw_kzg3vGfVIP\"", + "emsg": "000000f6656d736701000000000003e80000000000002bc0000000005a4db20d75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a804f1200000000000004040001010000fb580f38a33be3a33396fc4cd20d3b7501d7236a53b4910bfbef8d5ab6897d91d447cdc792a0d3b3f6c0bf4cde2f113373f1a9685a4160c3f933837bc67d520f" + }, + { + "msf": "{\"t\":1792108801300,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAABaTbIN86NsozI7XfHV64GtO6h8ORCq2XtV8tv8ES9yZCDWEwAAAAAAAAQkAAEDAAFWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeo8ufeaD7JFmtb6jbcQJ8yS3gPZJDO5T6ZphDmwbiaZYGG1vhwkFBU5AtOvP2ty2ZfNWQcYCHt2PIEpDZ5yKzww\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"788174d766cb50e18385920d650fe9eb3db7583a2473e54c269c03e05267c50e\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.300Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAABaTbIN86NsozI7XfHV64GtO6h8ORCq2XtV8tv8ES9yZCDWEwAAAAAAAAQkAAEDAAFWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeo8ufeaD7JFmtb6jbcQJ8yS3gPZJDO5T6ZphDmwbiaZYGG1vhwkFBU5AtOvP2ty2ZfNWQcYCHt2PIEpDZ5yKzww\"", + "emsg": "00000116656d736701000000000003e80000000000002c2400000000788174d775726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9302000000000000005a4db20df3a36ca3323b5df1d5eb81ad3ba87c3910aad97b55f2dbfc112f726420d61300000000000004240001030001561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a8f2e7de683ec9166b5bea36dc409f324b780f6490cee53e99a610e6c1b89a658186d6f870905054e40b4ebcfdadcb665f35641c6021edd8f204a43679c8acf0c" + }, + { + "msf": "{\"t\":1792108802200,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAAB4gXTXZstQ4YOFkg1lD-nrPbdYOiRz5UwmnAPgUmfFDsCRIQAAAAAAAAQEAAMBAABjD-4oGKohI2XoUjHofQH0hghORYkX8BTR6iCggcO0H77FBb-mYIAFm7RLl-LQRXRwGuFeu_kZJBP65SlCl2AL\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"7e29a8c76a42b1bb582b165e5330b5de00e4b01a82cd814895d7bf4ebaf1fcc5\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.200Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAAB4gXTXZstQ4YOFkg1lD-nrPbdYOiRz5UwmnAPgUmfFDsCRIQAAAAAAAAQEAAMBAABjD-4oGKohI2XoUjHofQH0hghORYkX8BTR6iCggcO0H77FBb-mYIAFm7RLl-LQRXRwGuFeu_kZJBP65SlCl2AL\"", + "emsg": "000000f6656d736701000000000003e80000000000002fa8000000007e29a8c775726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300000000000000788174d766cb50e18385920d650fe9eb3db7583a2473e54c269c03e05267c50ec0912100000000000004040003010000630fee2818aa212365e85231e87d01f486084e458917f014d1ea20a081c3b41fbec505bfa66080059bb44b97e2d04574701ae15ebbf9192413fae5294297600b" + }, + { + "msf": "{\"t\":1792108802500,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAAAAAAAAAB-KajHakKxu1grFl5TMLXeAOSwGoLNgUiV179OuvH8xaAlJgAAAAAAAAQkAAEDAANWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeoCJanNc7dysTxaMJuLWubKpGS18wkNsZr1lVHZSQ2-W7eLZCQagNU33Bd9gSyEoDrkOurZuDFvZdijbnL_agw8\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"86efbf695ef6cfff2c102cbd9a7430599e2110ea68c4d8947c78ca2e9057ee1d\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.500Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAAAAAAAAAB-KajHakKxu1grFl5TMLXeAOSwGoLNgUiV179OuvH8xaAlJgAAAAAAAAQkAAEDAANWGFNFG8H056l8fl9SQnkjU3tWOKE4-QQDhk9uEfsjeoCJanNc7dysTxaMJuLWubKpGS18wkNsZr1lVHZSQ2-W7eLZCQagNU33Bd9gSyEoDrkOurZuDFvZdijbnL_agw8\"", + "emsg": "00000116656d736701000000000003e800000000000030d40000000086efbf6975726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9304000000000000007e29a8c76a42b1bb582b165e5330b5de00e4b01a82cd814895d7bf4ebaf1fcc5a0252600000000000004240001030003561853451bc1f4e7a97c7e5f52427923537b5638a138f90403864f6e11fb237a80896a735ceddcac4f168c26e2d6b9b2a9192d7cc2436c66bd65547652436f96ede2d90906a0354df705df604b21280eb90ebab66e0c5bd97628db9cbfda830f" + }, + { + "msf": "{\"t\":1792108803200,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQAAAAAAAACG779pXvbP_ywQLL2adDBZniEQ6mjE2JR8eMoukFfuHQDUMAAAAAAAAAQEAAQBAADXWwklQD9IJSV6SbCbBfKV94ScpzAMHmgMUykycLmasBw7ecSUdJobTdVWlwGpaRaXjk6vQPw1AKBtPy5asC4L\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"b94deefa68c46665e0a0b7ea3889a37511a95b0ab3d768edde80444b650362eb\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.200Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQAAAAAAAACG779pXvbP_ywQLL2adDBZniEQ6mjE2JR8eMoukFfuHQDUMAAAAAAAAAQEAAQBAADXWwklQD9IJSV6SbCbBfKV94ScpzAMHmgMUykycLmasBw7ecSUdJobTdVWlwGpaRaXjk6vQPw1AKBtPy5asC4L\"", + "emsg": "000000f6656d736701000000000003e8000000000000339000000000b94deefa75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93050000000000000086efbf695ef6cfff2c102cbd9a7430599e2110ea68c4d8947c78ca2e9057ee1d00d43000000000000004040004010000d75b0925403f4825257a49b09b05f295f7849ca7300c1e680c53293270b99ab01c3b79c494749a1b4dd5569701a96916978e4eaf40fc3500a06d3f2e5ab02e0b" + }, + { + "msf": "{\"t\":1792108804300,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBgAAAAAAAAC5Te76aMRmZeCgt-o4iaN1EalbCrPXaO3egERLZQNi6-CcQQAAAAAAAAQEAAXIAAAS_uhQvB0-r6A0vOwrlpkoDrX1hkneaLtz1H_0rJbGy6EU792LEVRT4RklhA3L-2HbkbUHx2xNa98bE61p0rUK\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"0b47f47e933d7446d2474f0c1ce5d817702bee9aa082b5cfb6fdbde5d75fc708\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.300Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBgAAAAAAAAC5Te76aMRmZeCgt-o4iaN1EalbCrPXaO3egERLZQNi6-CcQQAAAAAAAAQEAAXIAAAS_uhQvB0-r6A0vOwrlpkoDrX1hkneaLtz1H_0rJbGy6EU792LEVRT4RklhA3L-2HbkbUHx2xNa98bE61p0rUK\"", + "emsg": "000000f6656d736701000000000003e800000000000037dc000000000b47f47e75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930600000000000000b94deefa68c46665e0a0b7ea3889a37511a95b0ab3d768edde80444b650362ebe09c4100000000000004040005c8000012fee850bc1d3eafa034bcec2b9699280eb5f58649de68bb73d47ff4ac96c6cba114efdd8b115453e11925840dcbfb61db91b507c76c4d6bdf1b13ad69d2b50a" + } + ] + }, + { + "name": "kind_poll", + "about": "poll_open, vote, poll_close (§4.6, §7): three voters, one changing its vote, a vote after the close and a vote for a poll no one opened (neither counted), a close stating the tally the replay reaches, and a second poll left open", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000527000a0057686174206e6578743f030600456e636f726509004e65787420736f6e670500427265616b6399d15c1a7af52f9147b3f6e416d7290727ec856349c4bc5d18aedb5cb522ee9ba909087597fe57b430501d3548839dd9cbd19ec6b0de9e1b3a124a0eab1903", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b0076a0633ee96103e80e413a2cd2e66772ad5106a80d11a38698006076c3fe507bacf3cb92811f10765423bc78aae053e5645d939cd6cf95ab91f4c603b1436807", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d776500000000000000000000000000000000000000000000000000000000000000000000000000000000c0c62d0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b01f24b612305de58924a3be632ff790ff53f57f6ec88a1814f6f632baaa5b088d18659217b8d77e5b9f681a502258e8c578e4349bc846651e97daf27809b1a6e00", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f3201390000000000000000000000000000000000000000000000000000000000000000000000000000000000093d0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b018112e2776f9ca681c159e985c2d30fe265dea55ee6d3115421f309b90b5471a2f28296ddc5bc465cb19e714406819874c83619452350392406a337adeab69701", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000009e9cf6d2cca18d68b6cbac93cf7218780120b495e289abf42c364f38d7f9ad09404b4c0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b027d83282808a7a5b6b350463571cbf9f466490b72e3a5fa2aa5fef2c32713bddda7d5d26a734fda45391dd1e6fb2d3dadbd1cb7639f6cde4b44bac3cdb8b77f07", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b808d5b000000000000051f0013005374617920666f72207175657374696f6e733f02030059657302004e6fdcadfd98dfca6caa2254ad6c567a4ab48779939ddf86a8969cff93164056af65170c36e1c653c9383e69672a8bf427e53e4a398da5bbbd56c44e4daacc9d9e0e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139010000000000000048d37bdfa872c27d85b695acc90fd69c9b313c5cdea73a515b4fcbc1a25b2d3ac0cf6a000000000000062100b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d3400948769f3e7ef57443ff06a3de688e9833a058f547f9a0a7dc1622e8e3161f0c6a546b058627886e9e5e9de69bdbfc3cc03a3f8a7ce0bde8ec51fc73f53287d0b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d3400127a000000000000072d003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b03000000000200000001000000accc9cadcfc90c1f08f52fb5aa032a0a61bba68a0db8c251369195eec2a0eafcbc71d203d549a33ae894d3855aeae294937b0af5842da7cb3e8269fb5ca9b709", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650100000000000000871d72f084cb13cbf1d84311ef6c63d08b2ae2420ceb0b07ca924e92c22b5ead4054890000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b005d3870a054b4fcf120b1c63deb00a5c26fb6864f57b6cdd0c70a29a4a840109fd6837d6ccd5ac39083afeda25af6e18081779c8516908ff6b1720b598fca660d", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000154353649c54eb5d9e239641c11ad6504d1558fd0e352bef10ea9e56127193688096980000000000000621002a840c9971ebcdf928fa26d13ad23a84893dba494b2cfb9b6780ad4a14d3c9e6005350d3e36720a31b6aa1eca36b3a86b1e3e395999512e488a69c45b50905e9eb567acdd80dd97f2a0806a775b76f796e7593c1505bb87dfeeaa0837ec1eed30e" + ], + "outcome": "accept", + "digests": [ + "3772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b", + "9e9cf6d2cca18d68b6cbac93cf7218780120b495e289abf42c364f38d7f9ad09", + "871d72f084cb13cbf1d84311ef6c63d08b2ae2420ceb0b07ca924e92c22b5ead", + "48d37bdfa872c27d85b695acc90fd69c9b313c5cdea73a515b4fcbc1a25b2d3a", + "154353649c54eb5d9e239641c11ad6504d1558fd0e352bef10ea9e5612719368", + "b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d34", + "20fc328f20ff260b50d02fb5376f964afcffc1e9eb4d96c52f32b2a61e99d537", + "09da2c78991e747a11e54efd57dbec36cfe30f0c19caeea25f31246b3ae9694c", + "8d45caa5356b97a715da217d8b37c3abe548d57be5d6db2b1bab1f66c0540b47", + "745c16c8a253c2e6d5acfa36643367ed25aa6e29a790f608a102e18da2e8f94a" + ], + "tally": { + "state_hash": "efc999f9b01f8419459d79e5769f35dae4c59e6946b15819affc00e1e8f0069d", + "polls": [ + { + "poll": "3772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b", + "open": false, + "counts": [ + 0, + 2, + 1 + ] + }, + { + "poll": "b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d34", + "open": true, + "counts": [ + 1, + 0 + ] + } + ] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAUnAAoAV2hhdCBuZXh0PwMGAEVuY29yZQkATmV4dCBzb25nBQBCcmVha2OZ0VwaevUvkUez9uQW1ykHJ-yFY0nEvF0YrttctSLum6kJCHWX_le0MFAdNUiDndnL0Z7GsN6eGzoSSg6rGQM\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"3772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAUnAAoAV2hhdCBuZXh0PwMGAEVuY29yZQkATmV4dCBzb25nBQBCcmVha2OZ0VwaevUvkUez9uQW1ykHJ-yFY0nEvF0YrttctSLum6kJCHWX_le0MFAdNUiDndnL0Z7GsN6eGzoSSg6rGQM\"", + "emsg": "0000011a656d736701000000000003e80000000000002af8000000003772ecf775726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000527000a0057686174206e6578743f030600456e636f726509004e65787420736f6e670500427265616b6399d15c1a7af52f9147b3f6e416d7290727ec856349c4bc5d18aedb5cb522ee9ba909087597fe57b430501d3548839dd9cbd19ec6b0de9e1b3a124a0eab1903" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAHagYz7pYQPoDkE6LNLmZ3KtUQaoDRGjhpgAYHbD_lB7rPPLkoEfEHZUI7x4quBT5WRdk5zWz5WrkfTGA7FDaAc\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"9e9cf6d2cca18d68b6cbac93cf7218780120b495e289abf42c364f38d7f9ad09\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAHagYz7pYQPoDkE6LNLmZ3KtUQaoDRGjhpgAYHbD_lB7rPPLkoEfEHZUI7x4quBT5WRdk5zWz5WrkfTGA7FDaAc\"", + "emsg": "0000010f656d736701000000000003e80000000000002ee0000000009e9cf6d275726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b0076a0633ee96103e80e413a2cd2e66772ad5106a80d11a38698006076c3fe507bacf3cb92811f10765423bc78aae053e5645d939cd6cf95ab91f4c603b1436807" + }, + { + "msf": "{\"t\":1792108803000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDGLQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAfJLYSMF3liSSjvmMv95D_U_V_bsiKGBT29jK6qlsIjRhlkhe4135bn2gaUCJY6MV45DSbyEZlHpfa8ngJsabgA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"871d72f084cb13cbf1d84311ef6c63d08b2ae2420ceb0b07ca924e92c22b5ead\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDGLQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAfJLYSMF3liSSjvmMv95D_U_V_bsiKGBT29jK6qlsIjRhlkhe4135bn2gaUCJY6MV45DSbyEZlHpfa8ngJsabgA\"", + "emsg": "0000010f656d736701000000000003e800000000000032c800000000871d72f075726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d776500000000000000000000000000000000000000000000000000000000000000000000000000000000c0c62d0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b01f24b612305de58924a3be632ff790ff53f57f6ec88a1814f6f632baaa5b088d18659217b8d77e5b9f681a502258e8c578e4349bc846651e97daf27809b1a6e00" + }, + { + "msf": "{\"t\":1792108804000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJPQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAYES4ndvnKaBwVnphcLTD-Jl3qVe5tMRVCHzCbkLVHGi8oKW3cW8RlyxnnFEBoGYdMg2GUUjUDkkBqM3req2lwE\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"48d37bdfa872c27d85b695acc90fd69c9b313c5cdea73a515b4fcbc1a25b2d3a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJPQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAYES4ndvnKaBwVnphcLTD-Jl3qVe5tMRVCHzCbkLVHGi8oKW3cW8RlyxnnFEBoGYdMg2GUUjUDkkBqM3req2lwE\"", + "emsg": "0000010f656d736701000000000003e800000000000036b00000000048d37bdf75726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f3201390000000000000000000000000000000000000000000000000000000000000000000000000000000000093d0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b018112e2776f9ca681c159e985c2d30fe265dea55ee6d3115421f309b90b5471a2f28296ddc5bc465cb19e714406819874c83619452350392406a337adeab69701" + }, + { + "msf": "{\"t\":1792108805000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAACenPbSzKGNaLbLrJPPchh4ASC0leKJq_QsNk841_mtCUBLTAAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAn2DKCgIp6W2s1BGNXHL-fRmSQty46X6KqX-8sMnE73dp9XSanNP2kU5HdHm-y09rb0ct2OfbN5LRLrDzbi3fwc\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"154353649c54eb5d9e239641c11ad6504d1558fd0e352bef10ea9e5612719368\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAACenPbSzKGNaLbLrJPPchh4ASC0leKJq_QsNk841_mtCUBLTAAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAn2DKCgIp6W2s1BGNXHL-fRmSQty46X6KqX-8sMnE73dp9XSanNP2kU5HdHm-y09rb0ct2OfbN5LRLrDzbi3fwc\"", + "emsg": "0000010f656d736701000000000003e80000000000003a98000000001543536475726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000009e9cf6d2cca18d68b6cbac93cf7218780120b495e289abf42c364f38d7f9ad09404b4c0000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b027d83282808a7a5b6b350463571cbf9f466490b72e3a5fa2aa5fef2c32713bddda7d5d26a734fda45391dd1e6fb2d3dadbd1cb7639f6cde4b44bac3cdb8b77f07" + }, + { + "msf": "{\"t\":1792108806000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAA3cuz3dGThImOsFkeYXVZuiPE1aHe9Q-sFjjd5CvDWG4CNWwAAAAAAAAUfABMAU3RheSBmb3IgcXVlc3Rpb25zPwIDAFllcwIATm_crf2Y38psqiJUrWxWekq0h3mTnd-GqJac_5MWQFavZRcMNuHGU8k4PmlnKov0J-U-SjmNpbu9VsROTarMnZ4O\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d34\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAA3cuz3dGThImOsFkeYXVZuiPE1aHe9Q-sFjjd5CvDWG4CNWwAAAAAAAAUfABMAU3RheSBmb3IgcXVlc3Rpb25zPwIDAFllcwIATm_crf2Y38psqiJUrWxWekq0h3mTnd-GqJac_5MWQFavZRcMNuHGU8k4PmlnKov0J-U-SjmNpbu9VsROTarMnZ4O\"", + "emsg": "00000112656d736701000000000003e80000000000003e8000000000b03a29ca75726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b808d5b000000000000051f0013005374617920666f72207175657374696f6e733f02030059657302004e6fdcadfd98dfca6caa2254ad6c567a4ab48779939ddf86a8969cff93164056af65170c36e1c653c9383e69672a8bf427e53e4a398da5bbbd56c44e4daacc9d9e0e" + }, + { + "msf": "{\"t\":1792108807000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AQAAAAAAAABI03vfqHLCfYW2lazJD9acmzE8XN6nOlFbT8vBolstOsDPagAAAAAAAAYhALA6KcoiMZo-2HejzCUtKXM0KVAxKoGDH3oglqeocp00AJSHafPn71dEP_BqPeaI6YM6BY9Uf5oKfcFiLo4xYfDGpUawWGJ4hunl6d5pvb_DzAOj-KfOC96OxR_HP1MofQs\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"20fc328f20ff260b50d02fb5376f964afcffc1e9eb4d96c52f32b2a61e99d537\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:07.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AQAAAAAAAABI03vfqHLCfYW2lazJD9acmzE8XN6nOlFbT8vBolstOsDPagAAAAAAAAYhALA6KcoiMZo-2HejzCUtKXM0KVAxKoGDH3oglqeocp00AJSHafPn71dEP_BqPeaI6YM6BY9Uf5oKfcFiLo4xYfDGpUawWGJ4hunl6d5pvb_DzAOj-KfOC96OxR_HP1MofQs\"", + "emsg": "0000010f656d736701000000000003e800000000000042680000000020fc328f75726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139010000000000000048d37bdfa872c27d85b695acc90fd69c9b313c5cdea73a515b4fcbc1a25b2d3ac0cf6a000000000000062100b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d3400948769f3e7ef57443ff06a3de688e9833a058f547f9a0a7dc1622e8e3161f0c6a546b058627886e9e5e9de69bdbfc3cc03a3f8a7ce0bde8ec51fc73f53287d0b" + }, + { + "msf": "{\"t\":1792108808000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACwOinKIjGaPth3o8wlLSlzNClQMSqBgx96IJanqHKdNAASegAAAAAAAActADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAwAAAAACAAAAAQAAAKzMnK3PyQwfCPUvtaoDKgphu6aKDbjCUTaRle7CoOr8vHHSA9VJozrolNOFWurilJN7CvWELafLPoJp-1yptwk\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"09da2c78991e747a11e54efd57dbec36cfe30f0c19caeea25f31246b3ae9694c\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:08.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACwOinKIjGaPth3o8wlLSlzNClQMSqBgx96IJanqHKdNAASegAAAAAAAActADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAwAAAAACAAAAAQAAAKzMnK3PyQwfCPUvtaoDKgphu6aKDbjCUTaRle7CoOr8vHHSA9VJozrolNOFWurilJN7CvWELafLPoJp-1yptwk\"", + "emsg": "00000121656d736701000000000003e800000000000046500000000009da2c7875726e3a7761693a6576656e743a3100706f6c6c5f636c6f7365005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000b03a29ca22319a3ed877a3cc252d2973342950312a81831f7a2096a7a8729d3400127a000000000000072d003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b03000000000200000001000000accc9cadcfc90c1f08f52fb5aa032a0a61bba68a0db8c251369195eec2a0eafcbc71d203d549a33ae894d3855aeae294937b0af5842da7cb3e8269fb5ca9b709" + }, + { + "msf": "{\"t\":1792108809000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAQAAAAAAAACHHXLwhMsTy_HYQxHvbGPQiyriQgzrCwfKkk6SwiterUBUiQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAF04cKBUtPzxILHGPesApcJvtoZPV7bN0McKKaSoQBCf1oN9bM1aw5CDr-2iWvbhgIF3nIUWkI_2sXILWY_KZg0\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8d45caa5356b97a715da217d8b37c3abe548d57be5d6db2b1bab1f66c0540b47\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:09.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAQAAAAAAAACHHXLwhMsTy_HYQxHvbGPQiyriQgzrCwfKkk6SwiterUBUiQAAAAAAAAYhADdy7Pd0ZOEiY6wWR5hdVm6I8TVod71D6wWON3kK8NYbAF04cKBUtPzxILHGPesApcJvtoZPV7bN0McKKaSoQBCf1oN9bM1aw5CDr-2iWvbhgIF3nIUWkI_2sXILWY_KZg0\"", + "emsg": "0000010f656d736701000000000003e80000000000004a38000000008d45caa575726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650100000000000000871d72f084cb13cbf1d84311ef6c63d08b2ae2420ceb0b07ca924e92c22b5ead4054890000000000000621003772ecf77464e12263ac1647985d566e88f1356877bd43eb058e37790af0d61b005d3870a054b4fcf120b1c63deb00a5c26fb6864f57b6cdd0c70a29a4a840109fd6837d6ccd5ac39083afeda25af6e18081779c8516908ff6b1720b598fca660d" + }, + { + "msf": "{\"t\":1792108810000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAAAVQ1NknFTrXZ4jlkHBGtZQTRVY_Q41K-8Q6p5WEnGTaICWmAAAAAAAAAYhACqEDJlx6835KPom0TrSOoSJPbpJSyz7m2eArUoU08nmAFNQ0-NnIKMbaqHso2s6hrHj45WZlRLkiKacRbUJBenrVnrN2A3ZfyoIBqd1t295bnWTwVBbuH3-6qCDfsHu0w4\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"745c16c8a253c2e6d5acfa36643367ed25aa6e29a790f608a102e18da2e8f94a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAAAVQ1NknFTrXZ4jlkHBGtZQTRVY_Q41K-8Q6p5WEnGTaICWmAAAAAAAAAYhACqEDJlx6835KPom0TrSOoSJPbpJSyz7m2eArUoU08nmAFNQ0-NnIKMbaqHso2s6hrHj45WZlRLkiKacRbUJBenrVnrN2A3ZfyoIBqd1t295bnWTwVBbuH3-6qCDfsHu0w4\"", + "emsg": "0000010f656d736701000000000003e80000000000004e2000000000745c16c875726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000154353649c54eb5d9e239641c11ad6504d1558fd0e352bef10ea9e56127193688096980000000000000621002a840c9971ebcdf928fa26d13ad23a84893dba494b2cfb9b6780ad4a14d3c9e6005350d3e36720a31b6aa1eca36b3a86b1e3e395999512e488a69c45b50905e9eb567acdd80dd97f2a0806a775b76f796e7593c1505bb87dfeeaa0837ec1eed30e" + } + ] + }, + { + "name": "kind_marker", + "about": "marker (§4.8): an anchored positive marker, a negative one with an attachment digest, and a neutral one with no text", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000780000000000000008130001000000010b006f6e207468652062656174007dadcd2045f15c294d494aa5ffb5b9e21f82b4b863f5084a075dd3fb5fd1802714476ae10089befff08df966adc7d7ca5c111735316f83ee5473f1544494e10e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000c64020291cda00c72b79bd7c433feb3b606900be81627a848b8b52f80f49c926001bb700000000000008360002000000020e00666c617420696e20626172203132015b5763df843f295bb7aed195458a053d734b77409278a434d2cdc995c5f98d39a1f223ef560448a61a34baf44cfd1e56f54911cbb12317639789697c74d616a56c9b6d82e2f272da62e029721ca809bbe10b33fd3e1eac0b514ed5e4135a2c0f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000eac65f4878b7b91ae20c063d2b0f3319ec199bffa0719d652dd104cbe696abc9002d3101000000000008080003000000000000002ccef4153c7ffccb3a8c5736b9c5444ed76c0ea7318de12073015d9a0f1d486b2ee07c33697c12cacdef10f83dff1e970e32e2b3a4aeb62a2ea3bc9ddade2a04" + ], + "outcome": "accept", + "digests": [ + "c64020291cda00c72b79bd7c433feb3b606900be81627a848b8b52f80f49c926", + "eac65f4878b7b91ae20c063d2b0f3319ec199bffa0719d652dd104cbe696abc9", + "3ca0e64d8f011bd615587038bc5ccdcb988659f1fa203db17358623046f079b6" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"l\":[0,120],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBLTAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAB4AAAAAAAAAAgTAAEAAAABCwBvbiB0aGUgYmVhdAB9rc0gRfFcKU1JSqX_tbniH4K0uGP1CEoHXdP7X9GAJxRHauEAib7_8I35Zq3H18pcERc1MW-D7lRz8VRElOEO\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"c64020291cda00c72b79bd7c433feb3b606900be81627a848b8b52f80f49c926\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBLTAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAB4AAAAAAAAAAgTAAEAAAABCwBvbiB0aGUgYmVhdAB9rc0gRfFcKU1JSqX_tbniH4K0uGP1CEoHXdP7X9GAJxRHauEAib7_8I35Zq3H18pcERc1MW-D7lRz8VRElOEO\"", + "emsg": "00000133656d736701000000000003e80000000000003a9800000000c640202975726e3a7761693a6576656e743a31006d61726b6572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000780000000000000008130001000000010b006f6e207468652062656174007dadcd2045f15c294d494aa5ffb5b9e21f82b4b863f5084a075dd3fb5fd1802714476ae10089befff08df966adc7d7ca5c111735316f83ee5473f1544494e10e" + }, + { + "msf": "{\"t\":1792108812000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAADGQCApHNoAxyt5vXxDP-s7YGkAvoFieoSLi1L4D0nJJgAbtwAAAAAAAAg2AAIAAAACDgBmbGF0IGluIGJhciAxMgFbV2PfhD8pW7eu0ZVFigU9c0t3QJJ4pDTSzcmVxfmNOaHyI-9WBEimGjS69Ez9Hlb1SRHLsSMXY5eJaXx01halbJttguLyctpi4ClyHKgJu-ELM_0-HqwLUU7V5BNaLA8\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"eac65f4878b7b91ae20c063d2b0f3319ec199bffa0719d652dd104cbe696abc9\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:12.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAADGQCApHNoAxyt5vXxDP-s7YGkAvoFieoSLi1L4D0nJJgAbtwAAAAAAAAg2AAIAAAACDgBmbGF0IGluIGJhciAxMgFbV2PfhD8pW7eu0ZVFigU9c0t3QJJ4pDTSzcmVxfmNOaHyI-9WBEimGjS69Ez9Hlb1SRHLsSMXY5eJaXx01halbJttguLyctpi4ClyHKgJu-ELM_0-HqwLUU7V5BNaLA8\"", + "emsg": "00000126656d736701000000000003e800000000000055f000000000eac65f4875726e3a7761693a6576656e743a31006d61726b6572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000c64020291cda00c72b79bd7c433feb3b606900be81627a848b8b52f80f49c926001bb700000000000008360002000000020e00666c617420696e20626172203132015b5763df843f295bb7aed195458a053d734b77409278a434d2cdc995c5f98d39a1f223ef560448a61a34baf44cfd1e56f54911cbb12317639789697c74d616a56c9b6d82e2f272da62e029721ca809bbe10b33fd3e1eac0b514ed5e4135a2c0f" + }, + { + "msf": "{\"t\":1792108820000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAADqxl9IeLe5GuIMBj0rDzMZ7Bmb_6BxnWUt0QTL5paryQAtMQEAAAAAAAgIAAMAAAAAAAAALM70FTx__Ms6jFc2ucVETtdsDqcxjeEgcwFdmg8dSGsu4HwzaXwSys3vEPg9_x6XDjLis6Sutiouo7yd2t4qBA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"3ca0e64d8f011bd615587038bc5ccdcb988659f1fa203db17358623046f079b6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:20.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAADqxl9IeLe5GuIMBj0rDzMZ7Bmb_6BxnWUt0QTL5paryQAtMQEAAAAAAAgIAAMAAAAAAAAALM70FTx__Ms6jFc2ucVETtdsDqcxjeEgcwFdmg8dSGsu4HwzaXwSys3vEPg9_x6XDjLis6Sutiouo7yd2t4qBA\"", + "emsg": "000000f8656d736701000000000003e80000000000007530000000003ca0e64d75726e3a7761693a6576656e743a31006d61726b6572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000eac65f4878b7b91ae20c063d2b0f3319ec199bffa0719d652dd104cbe696abc9002d3101000000000008080003000000000000002ccef4153c7ffccb3a8c5736b9c5444ed76c0ea7318de12073015d9a0f1d486b2ee07c33697c12cacdef10f83dff1e970e32e2b3a4aeb62a2ea3bc9ddade2a04" + } + ] + }, + { + "name": "kind_control", + "about": "control (§4.9): every command, sent to one target principal: recording started with a count-in, zoom, mute on, a layer request, mute off, recording stopped", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301a00f0000e285603ec796a1d2e89c9a67307850902942bd82b98956dfc76a2927fa64560dd27b322bf3326e5ee17735738ce7a443a423e9a7765ac3ac0674cc4d6ea02506", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000d3fcde8c8dc8d66505fb6537e9abaf5f50d4f8f5687c803b5e635d80058c3e8c80841e000000000000092500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300800100c227bc3c7645e93ba1d43975272838fe3cb76673cbcb0a7abae37635cf577304ebe52c73165c55167fed339b54cb459e95397d8c2b8bcc28e8d32c981e23ac02", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000003f43d6e41aba9199265fccd571daa69252cf6ab84bf24bb4745b06c589f6da72c0c62d000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930401d3e60b3de00eef6a5c2babd42dfdc1cc33071d0035323dc1fbc55d2a8b3498199a5308a733f0d4174aae22d1c8b46fa00fbfc7191c48800270ca4d4ef0ffd506", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0300000000000000a88fd05b6d353a97c1f3470ab128bea9176fdbde9f91984521481a4e46bade5a00093d000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9305027ecb7b8dbdbd530ae6e5dcb4730feaace31e3b567bcae8b769a828b2b3e87c49dbdb13d2da0c46c3d8e423a6b815e5d43d99d80955ce8007065b37e5ccbbcc08", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0400000000000000723fcb1aeaca90216143cbe497d59c68e23264c9f37b62a2bde722597890f7dd404b4c000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930400e37b1ddfc477fcd038f372ef2f09a5b73d1cdf09c5902cbbd676e3fff03d3ce1aa6313809553dc751026a8e8ef18e18a284862bba53aa3d51b4e15e9e378e007", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e050000000000000011f958d241e5db590c9c74593554fdd68358367f71c81bbea668e86a9bd40d21008793030000000000092100c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93026a26006afd49b6a782bf500dfc0c96d69bab7e5cff176de37e34a8bcb187760ca00b7f628728b93adf019d36a65e17100d0a0d3a179b1930ff2454cdf813d30e" + ], + "outcome": "accept", + "digests": [ + "d3fcde8c8dc8d66505fb6537e9abaf5f50d4f8f5687c803b5e635d80058c3e8c", + "3f43d6e41aba9199265fccd571daa69252cf6ab84bf24bb4745b06c589f6da72", + "a88fd05b6d353a97c1f3470ab128bea9176fdbde9f91984521481a4e46bade5a", + "723fcb1aeaca90216143cbe497d59c68e23264c9f37b62a2bde722597890f7dd", + "11f958d241e5db590c9c74593554fdd68358367f71c81bbea668e86a9bd40d21", + "aa6b299bf0e2bfe01f1ddadeb4df9366294ca61a413820c0a604fb25b1156756" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAklAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAaAPAADihWA-x5ah0uicmmcweFCQKUK9grmJVt_Haikn-mRWDdJ7MivzMm5e4Xc1c4znpEOkI-mndlrDrAZ0zE1uoCUG\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"d3fcde8c8dc8d66505fb6537e9abaf5f50d4f8f5687c803b5e635d80058c3e8c\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAklAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAaAPAADihWA-x5ah0uicmmcweFCQKUK9grmJVt_Haikn-mRWDdJ7MivzMm5e4Xc1c4znpEOkI-mndlrDrAZ0zE1uoCUG\"", + "emsg": "00000116656d736701000000000003e80000000000002af800000000d3fcde8c75726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301a00f0000e285603ec796a1d2e89c9a67307850902942bd82b98956dfc76a2927fa64560dd27b322bf3326e5ee17735738ce7a443a423e9a7765ac3ac0674cc4d6ea02506" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAADT_N6MjcjWZQX7ZTfpq69fUNT49Wh8gDteY12ABYw-jICEHgAAAAAAAAklAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwCAAQDCJ7w8dkXpO6HUOXUnKDj-PLdmc8vLCnq643Y1z1dzBOvlLHMWXFUWf-0zm1TLRZ6VOX2MK4vMKOjTLJgeI6wC\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"3f43d6e41aba9199265fccd571daa69252cf6ab84bf24bb4745b06c589f6da72\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAADT_N6MjcjWZQX7ZTfpq69fUNT49Wh8gDteY12ABYw-jICEHgAAAAAAAAklAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwCAAQDCJ7w8dkXpO6HUOXUnKDj-PLdmc8vLCnq643Y1z1dzBOvlLHMWXFUWf-0zm1TLRZ6VOX2MK4vMKOjTLJgeI6wC\"", + "emsg": "00000116656d736701000000000003e80000000000002ee0000000003f43d6e475726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0100000000000000d3fcde8c8dc8d66505fb6537e9abaf5f50d4f8f5687c803b5e635d80058c3e8c80841e000000000000092500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300800100c227bc3c7645e93ba1d43975272838fe3cb76673cbcb0a7abae37635cf577304ebe52c73165c55167fed339b54cb459e95397d8c2b8bcc28e8d32c981e23ac02" + }, + { + "msf": "{\"t\":1792108803000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAAA_Q9bkGrqRmSZfzNVx2qaSUs9quEvyS7R0WwbFifbacsDGLQAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAHT5gs94A7valwrq9Qt_cHMMwcdADUyPcH7xV0qizSYGZpTCKcz8NQXSq4i0ci0b6APv8cZHEiAAnDKTU7w_9UG\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"a88fd05b6d353a97c1f3470ab128bea9176fdbde9f91984521481a4e46bade5a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAAA_Q9bkGrqRmSZfzNVx2qaSUs9quEvyS7R0WwbFifbacsDGLQAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAHT5gs94A7valwrq9Qt_cHMMwcdADUyPcH7xV0qizSYGZpTCKcz8NQXSq4i0ci0b6APv8cZHEiAAnDKTU7w_9UG\"", + "emsg": "00000113656d736701000000000003e800000000000032c800000000a88fd05b75726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e02000000000000003f43d6e41aba9199265fccd571daa69252cf6ab84bf24bb4745b06c589f6da72c0c62d000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930401d3e60b3de00eef6a5c2babd42dfdc1cc33071d0035323dc1fbc55d2a8b3498199a5308a733f0d4174aae22d1c8b46fa00fbfc7191c48800270ca4d4ef0ffd506" + }, + { + "msf": "{\"t\":1792108804000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAACoj9BbbTU6l8HzRwqxKL6pF2_b3p-RmEUhSBpORrreWgAJPQAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQJ-y3uNvb1TCubl3LRzD-qs4x47VnvK6LdpqCiys-h8SdvbE9LaDEbD2OQjprgV5dQ9mdgJVc6ABwZbN-XMu8wI\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"723fcb1aeaca90216143cbe497d59c68e23264c9f37b62a2bde722597890f7dd\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAACoj9BbbTU6l8HzRwqxKL6pF2_b3p-RmEUhSBpORrreWgAJPQAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQJ-y3uNvb1TCubl3LRzD-qs4x47VnvK6LdpqCiys-h8SdvbE9LaDEbD2OQjprgV5dQ9mdgJVc6ABwZbN-XMu8wI\"", + "emsg": "00000113656d736701000000000003e800000000000036b000000000723fcb1a75726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0300000000000000a88fd05b6d353a97c1f3470ab128bea9176fdbde9f91984521481a4e46bade5a00093d000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9305027ecb7b8dbdbd530ae6e5dcb4730feaace31e3b567bcae8b769a828b2b3e87c49dbdb13d2da0c46c3d8e423a6b815e5d43d99d80955ce8007065b37e5ccbbcc08" + }, + { + "msf": "{\"t\":1792108805000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAAByP8sa6sqQIWFDy-SX1Zxo4jJkyfN7YqK95yJZeJD33UBLTAAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBADjex3fxHf80Djzcu8vCaW3PRzfCcWQLLvWduP_8D084apjE4CVU9x1ECao6O8Y4YooSGK7pTqj1RtOFenjeOAH\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"11f958d241e5db590c9c74593554fdd68358367f71c81bbea668e86a9bd40d21\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAAByP8sa6sqQIWFDy-SX1Zxo4jJkyfN7YqK95yJZeJD33UBLTAAAAAAAAAkiAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBADjex3fxHf80Djzcu8vCaW3PRzfCcWQLLvWduP_8D084apjE4CVU9x1ECao6O8Y4YooSGK7pTqj1RtOFenjeOAH\"", + "emsg": "00000113656d736701000000000003e80000000000003a980000000011f958d275726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0400000000000000723fcb1aeaca90216143cbe497d59c68e23264c9f37b62a2bde722597890f7dd404b4c000000000000092200c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930400e37b1ddfc477fcd038f372ef2f09a5b73d1cdf09c5902cbbd676e3fff03d3ce1aa6313809553dc751026a8e8ef18e18a284862bba53aa3d51b4e15e9e378e007" + }, + { + "msf": "{\"t\":1792108860000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAAAR-VjSQeXbWQycdFk1VP3Wg1g2f3HIG76maOhqm9QNIQCHkwMAAAAAAAkhAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAmomAGr9Sbangr9QDfwMltabq35c_xdt4340qLyxh3YMoAt_YocouTrfAZ02pl4XEA0KDToXmxkw_yRUzfgT0w4\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"aa6b299bf0e2bfe01f1ddadeb4df9366294ca61a413820c0a604fb25b1156756\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:00.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAAAR-VjSQeXbWQycdFk1VP3Wg1g2f3HIG76maOhqm9QNIQCHkwMAAAAAAAkhAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAmomAGr9Sbangr9QDfwMltabq35c_xdt4340qLyxh3YMoAt_YocouTrfAZ02pl4XEA0KDToXmxkw_yRUzfgT0w4\"", + "emsg": "00000112656d736701000000000003e8000000000001117000000000aa6b299b75726e3a7761693a6576656e743a3100636f6e74726f6c005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e050000000000000011f958d241e5db590c9c74593554fdd68358367f71c81bbea668e86a9bd40d21008793030000000000092100c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93026a26006afd49b6a782bf500dfc0c96d69bab7e5cff176de37e34a8bcb187760ca00b7f628728b93adf019d36a65e17100d0a0d3a179b1930ff2454cdf813d30e" + } + ] + }, + { + "name": "kind_caption", + "about": "caption (§4.10): human, machine and machine-reviewed origins, the latter two with a model digest, three language tags, and a caption with no stated duration", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000a1c00c40900000102656e120057656c636f6d652c2065766572796f6e652e5b1732f9c3dee4a6021e3ea1bfaf8f7068f10a4bcb4f4a2e4fe3a82532cdcb2dff9267bc6745296a71b24da3574807e6796698c35890679e98a0d8c056af7a0b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000008b5306c873ef7a863622c593f0b8f57c9fa176a264b2fdf7a94b0660cb6517b4e067350000000000000a3c00c409000002ff88cbdfe6861eceeb878843fd3219fc5966468d22bbd1d2293b9f4f16a209ff02667212004269656e76656e756520c3a020746f75732edcc70dd2252c365ce3bb66c1f022705c15d54fbd499a8570c1843936620574d86cc9ce5d51c00812752d51121d502299c4afed98a8befce917747963cdef1701", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000eed5b3f452713334d69c7b6390c0d11c29ee0004e4d8dc959e52de4152615e46808d5b0000000000000a3800d00700000382290709f501302fb773d952fb90813aefe872791c5ea3649db2c419b1142f540564652d44450b0057696c6c6b6f6d6d656e2e1ff6b00a307e023d97a10cb2b66ae19d43c23b90f10f7493a0072b4e0f6d12b9ecf12b4b8c680792eeae2323cd7c0cc7247f05663c2c8d904356494f98ac7d0e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e03000000000000009b3bb3097cb628346e7c4108c48dc2951613b66680992b974a82d7b8a835127c00127a0000000000000a15000000000001077a682d48616e740600e6ada1e8bf8eab5e82aa1addec4c415bb1013d9bb8486a7b737bb917e25048413c3588d69cd6539f43b9f7a4a54dd24a14536965ab1472d5ffc013b5115191fd261b3d73630e" + ], + "outcome": "accept", + "digests": [ + "8b5306c873ef7a863622c593f0b8f57c9fa176a264b2fdf7a94b0660cb6517b4", + "eed5b3f452713334d69c7b6390c0d11c29ee0004e4d8dc959e52de4152615e46", + "9b3bb3097cb628346e7c4108c48dc2951613b66680992b974a82d7b8a835127c", + "8b6202d8ebb2422d384a9897abf7d8c74fd79d2828a99f12e1830cb1a4c91e4a" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAocAMQJAAABAmVuEgBXZWxjb21lLCBldmVyeW9uZS5bFzL5w97kpgIePqG_r49waPEKS8tPSi5P46glMs3LLf-SZ7xnRSlqcbJNo1dIB-Z5ZpjDWJBnnpig2MBWr3oL\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8b5306c873ef7a863622c593f0b8f57c9fa176a264b2fdf7a94b0660cb6517b4\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",DURATION=2.500,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAocAMQJAAABAmVuEgBXZWxjb21lLCBldmVyeW9uZS5bFzL5w97kpgIePqG_r49waPEKS8tPSi5P46glMs3LLf-SZ7xnRSlqcbJNo1dIB-Z5ZpjDWJBnnpig2MBWr3oL\"", + "emsg": "0000010d656d736701000000000003e80000000000002af8000009c48b5306c875726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000a1c00c40900000102656e120057656c636f6d652c2065766572796f6e652e5b1732f9c3dee4a6021e3ea1bfaf8f7068f10a4bcb4f4a2e4fe3a82532cdcb2dff9267bc6745296a71b24da3574807e6796698c35890679e98a0d8c056af7a0b" + }, + { + "msf": "{\"t\":1792108803500,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAACLUwbIc-96hjYixZPwuPV8n6F2omSy_fepSwZgy2UXtOBnNQAAAAAAAAo8AMQJAAAC_4jL3-aGHs7rh4hD_TIZ_FlmRo0iu9HSKTufTxaiCf8CZnISAEJpZW52ZW51ZSDDoCB0b3VzLtzHDdIlLDZc47tmwfAicFwV1U-9SZqFcMGEOTZiBXTYbMnOXVHACBJ1LVESHVAimcSv7ZiovvzpF3R5Y83vFwE\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"eed5b3f452713334d69c7b6390c0d11c29ee0004e4d8dc959e52de4152615e46\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.500Z\",DURATION=2.500,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAACLUwbIc-96hjYixZPwuPV8n6F2omSy_fepSwZgy2UXtOBnNQAAAAAAAAo8AMQJAAAC_4jL3-aGHs7rh4hD_TIZ_FlmRo0iu9HSKTufTxaiCf8CZnISAEJpZW52ZW51ZSDDoCB0b3VzLtzHDdIlLDZc47tmwfAicFwV1U-9SZqFcMGEOTZiBXTYbMnOXVHACBJ1LVESHVAimcSv7ZiovvzpF3R5Y83vFwE\"", + "emsg": "0000012d656d736701000000000003e800000000000034bc000009c4eed5b3f475726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000008b5306c873ef7a863622c593f0b8f57c9fa176a264b2fdf7a94b0660cb6517b4e067350000000000000a3c00c409000002ff88cbdfe6861eceeb878843fd3219fc5966468d22bbd1d2293b9f4f16a209ff02667212004269656e76656e756520c3a020746f75732edcc70dd2252c365ce3bb66c1f022705c15d54fbd499a8570c1843936620574d86cc9ce5d51c00812752d51121d502299c4afed98a8befce917747963cdef1701" + }, + { + "msf": "{\"t\":1792108806000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAADu1bP0UnEzNNace2OQwNEcKe4ABOTY3JWeUt5BUmFeRoCNWwAAAAAAAAo4ANAHAAADgikHCfUBMC-3c9lS-5CBOu_ocnkcXqNknbLEGbEUL1QFZGUtREULAFdpbGxrb21tZW4uH_awCjB-Aj2XoQyytmrhnUPCO5DxD3SToAcrTg9tErns8StLjGgHku6uIyPNfAzHJH8FZjwsjZBDVklPmKx9Dg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"9b3bb3097cb628346e7c4108c48dc2951613b66680992b974a82d7b8a835127c\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.000Z\",DURATION=2.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAADu1bP0UnEzNNace2OQwNEcKe4ABOTY3JWeUt5BUmFeRoCNWwAAAAAAAAo4ANAHAAADgikHCfUBMC-3c9lS-5CBOu_ocnkcXqNknbLEGbEUL1QFZGUtREULAFdpbGxrb21tZW4uH_awCjB-Aj2XoQyytmrhnUPCO5DxD3SToAcrTg9tErns8StLjGgHku6uIyPNfAzHJH8FZjwsjZBDVklPmKx9Dg\"", + "emsg": "00000129656d736701000000000003e80000000000003e80000007d09b3bb30975726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000eed5b3f452713334d69c7b6390c0d11c29ee0004e4d8dc959e52de4152615e46808d5b0000000000000a3800d00700000382290709f501302fb773d952fb90813aefe872791c5ea3649db2c419b1142f540564652d44450b0057696c6c6b6f6d6d656e2e1ff6b00a307e023d97a10cb2b66ae19d43c23b90f10f7493a0072b4e0f6d12b9ecf12b4b8c680792eeae2323cd7c0cc7247f05663c2c8d904356494f98ac7d0e" + }, + { + "msf": "{\"t\":1792108808000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAACbO7MJfLYoNG58QQjEjcKVFhO2ZoCZK5dKgte4qDUSfAASegAAAAAAAAoVAAAAAAABB3poLUhhbnQGAOatoei_jqtegqoa3exMQVuxAT2buEhqe3N7uRfiUEhBPDWI1pzWU59DufekpU3SShRTaWWrFHLV_8ATtRFRkf0mGz1zYw4\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8b6202d8ebb2422d384a9897abf7d8c74fd79d2828a99f12e1830cb1a4c91e4a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:08.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAACbO7MJfLYoNG58QQjEjcKVFhO2ZoCZK5dKgte4qDUSfAASegAAAAAAAAoVAAAAAAABB3poLUhhbnQGAOatoei_jqtegqoa3exMQVuxAT2buEhqe3N7uRfiUEhBPDWI1pzWU59DufekpU3SShRTaWWrFHLV_8ATtRFRkf0mGz1zYw4\"", + "emsg": "00000106656d736701000000000003e80000000000004650ffffffff8b6202d875726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e03000000000000009b3bb3097cb628346e7c4108c48dc2951613b66680992b974a82d7b8a835127c00127a0000000000000a15000000000001077a682d48616e740600e6ada1e8bf8eab5e82aa1addec4c415bb1013d9bb8486a7b737bb917e25048413c3588d69cd6539f43b9f7a4a54dd24a14536965ab1472d5ffc013b5115191fd261b3d73630e" + } + ] + }, + { + "name": "kind_decision", + "about": "decision (§4.11): a moderator allows one chat event, denies another, then redacts it", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000308000600666972737421e748437f719a96e7b707865704bf6266b9417ea665d65b5db1a52320efe099207f183660f05a9dcdf26f724fd6245733a68c3ebf5a836f34d5a7143f226a120e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed4438900000000000000000000000000000000000000000000000000000000000000000000000000000000e0c8100000000000000b230001f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa000095f303b3878a6a6eba9942512f312538929d27560522d51d3957eee257a2a4e7863dc2979c9fc397e1031cb3c07c25cc1d9598e37bd161042ccac5e552b2b608", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa80841e0000000000000311000f00627579206e6f7720627579206e6f77b9a4908d19fcd3ee41e59d84eb747a35e5cfe91469b4cd74d73b406d45fcc9baf0401a6007d1e20929993ed892fe6c9869dfbeb749465e95a6ba9a56c31def0f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed443890100000000000000bc952384c0538f97cd55ecc29a5fc65c424200dc89eed4549f095ab0d3415182200b200000000000000b230002e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd6503007562f95a6e57745670f17065054a07f4a51f23a07f008f8aab8265a7162ad66a4fa8bf6eb1e75b30334f19203074a8ebf59197a31bf98cced91e8e2e3f73200c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed443890200000000000000a7d9813a369f52cd2210f827e3d790fef65707feeb07335bc662d9726186742dc091210000000000000b230003e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd6507001d7f84ad18a4f6f61813a5e4074e2ec0deb99573e46826ce0c8eff1e8afbb2b435377971527e35dc17d001fca93a2cdb161891e20885c9d5df428fa73c78de07" + ], + "outcome": "accept", + "digests": [ + "f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa", + "bc952384c0538f97cd55ecc29a5fc65c424200dc89eed4549f095ab0d3415182", + "e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd65", + "a7d9813a369f52cd2210f827e3d790fef65707feeb07335bc662d9726186742d", + "2691253fa002129dbfea5e927688c81518d2fdeaf81582edd2461e115edae1d3" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMIAAYAZmlyc3Qh50hDf3Galue3B4ZXBL9iZrlBfqZl1ltdsaUjIO_gmSB_GDZg8FqdzfJvck_WJFczpow-v1qDbzTVpxQ_ImoSDg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAMIAAYAZmlyc3Qh50hDf3Galue3B4ZXBL9iZrlBfqZl1ltdsaUjIO_gmSB_GDZg8FqdzfJvck_WJFczpow-v1qDbzTVpxQ_ImoSDg\"", + "emsg": "000000f6656d736701000000000003e80000000000002af800000000f7d6763375726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000308000600666972737421e748437f719a96e7b707865704bf6266b9417ea665d65b5db1a52320efe099207f183660f05a9dcdf26f724fd6245733a68c3ebf5a836f34d5a7143f226a120e" + }, + { + "msf": "{\"t\":1792108801100,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODIEAAAAAAAAAsjAAH31nYzu2q6jZWLTDdjCN8CCfN_epFBUQ7Q72sqoShjqgAAlfMDs4eKam66mUJRLzElOJKdJ1YFItUdOVfu4leipOeGPcKXnJ_Dl-EDHLPAfCXMHZWY43vRYQQsysXlUrK2CA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"bc952384c0538f97cd55ecc29a5fc65c424200dc89eed4549f095ab0d3415182\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.100Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODIEAAAAAAAAAsjAAH31nYzu2q6jZWLTDdjCN8CCfN_epFBUQ7Q72sqoShjqgAAlfMDs4eKam66mUJRLzElOJKdJ1YFItUdOVfu4leipOeGPcKXnJ_Dl-EDHLPAfCXMHZWY43vRYQQsysXlUrK2CA\"", + "emsg": "00000115656d736701000000000003e80000000000002b5c00000000bc95238475726e3a7761693a6576656e743a31006465636973696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed4438900000000000000000000000000000000000000000000000000000000000000000000000000000000e0c8100000000000000b230001f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa000095f303b3878a6a6eba9942512f312538929d27560522d51d3957eee257a2a4e7863dc2979c9fc397e1031cb3c07c25cc1d9598e37bd161042ccac5e552b2b608" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAAD31nYzu2q6jZWLTDdjCN8CCfN_epFBUQ7Q72sqoShjqoCEHgAAAAAAAAMRAA8AYnV5IG5vdyBidXkgbm93uaSQjRn80-5B5Z2E63R6NeXP6RRptM101ztAbUX8ybrwQBpgB9HiCSmZPtiS_myYad--t0lGXpWmuppWwx3vDw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd65\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAAD31nYzu2q6jZWLTDdjCN8CCfN_epFBUQ7Q72sqoShjqoCEHgAAAAAAAAMRAA8AYnV5IG5vdyBidXkgbm93uaSQjRn80-5B5Z2E63R6NeXP6RRptM101ztAbUX8ybrwQBpgB9HiCSmZPtiS_myYad--t0lGXpWmuppWwx3vDw\"", + "emsg": "000000ff656d736701000000000003e80000000000002ee000000000e3e3e48875726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000f7d67633bb6aba8d958b4c376308df0209f37f7a9141510ed0ef6b2aa12863aa80841e0000000000000311000f00627579206e6f7720627579206e6f77b9a4908d19fcd3ee41e59d84eb747a35e5cfe91469b4cd74d73b406d45fcc9baf0401a6007d1e20929993ed892fe6c9869dfbeb749465e95a6ba9a56c31def0f" + }, + { + "msf": "{\"t\":1792108802100,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAQAAAAAAAAC8lSOEwFOPl81V7MKaX8ZcQkIA3Inu1FSfCVqw00FRgiALIAAAAAAAAAsjAALj4-SI-wEgZ6vbzso3fioS4Xy_7J99xM-vAcwTHur9ZQMAdWL5Wm5XdFZw8XBlBUoH9KUfI6B_AI-Kq4JlpxYq1mpPqL9usedbMDNPGSAwdKjr9ZGXoxv5jM7ZHo4uP3MgDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"a7d9813a369f52cd2210f827e3d790fef65707feeb07335bc662d9726186742d\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.100Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAQAAAAAAAAC8lSOEwFOPl81V7MKaX8ZcQkIA3Inu1FSfCVqw00FRgiALIAAAAAAAAAsjAALj4-SI-wEgZ6vbzso3fioS4Xy_7J99xM-vAcwTHur9ZQMAdWL5Wm5XdFZw8XBlBUoH9KUfI6B_AI-Kq4JlpxYq1mpPqL9usedbMDNPGSAwdKjr9ZGXoxv5jM7ZHo4uP3MgDA\"", + "emsg": "00000115656d736701000000000003e80000000000002f4400000000a7d9813a75726e3a7761693a6576656e743a31006465636973696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed443890100000000000000bc952384c0538f97cd55ecc29a5fc65c424200dc89eed4549f095ab0d3415182200b200000000000000b230002e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd6503007562f95a6e57745670f17065054a07f4a51f23a07f008f8aab8265a7162ad66a4fa8bf6eb1e75b30334f19203074a8ebf59197a31bf98cced91e8e2e3f73200c" + }, + { + "msf": "{\"t\":1792108802200,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAgAAAAAAAACn2YE6Np9SzSIQ-Cfj15D-9lcH_usHM1vGYtlyYYZ0LcCRIQAAAAAAAAsjAAPj4-SI-wEgZ6vbzso3fioS4Xy_7J99xM-vAcwTHur9ZQcAHX-ErRik9vYYE6XkB04uwN65lXPkaCbODI7_Hor7srQ1N3lxUn413BfQAfypOizbFhiR4giFydXfQo-nPHjeBw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"2691253fa002129dbfea5e927688c81518d2fdeaf81582edd2461e115edae1d3\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.200Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMSTnoZh91Moq5BrbkeTsaRZT6ld3axc5h6_bKgiO1EOJAgAAAAAAAACn2YE6Np9SzSIQ-Cfj15D-9lcH_usHM1vGYtlyYYZ0LcCRIQAAAAAAAAsjAAPj4-SI-wEgZ6vbzso3fioS4Xy_7J99xM-vAcwTHur9ZQcAHX-ErRik9vYYE6XkB04uwN65lXPkaCbODI7_Hor7srQ1N3lxUn413BfQAfypOizbFhiR4giFydXfQo-nPHjeBw\"", + "emsg": "00000115656d736701000000000003e80000000000002fa8000000002691253f75726e3a7761693a6576656e743a31006465636973696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3124e7a1987dd4ca2ae41adb91e4ec691653ea57776b173987afdb2a088ed443890200000000000000a7d9813a369f52cd2210f827e3d790fef65707feeb07335bc662d9726186742dc091210000000000000b230003e3e3e488fb012067abdbceca377e2a12e17cbfec9f7dc4cfaf01cc131eeafd6507001d7f84ad18a4f6f61813a5e4074e2ec0deb99573e46826ce0c8eff1e8afbb2b435377971527e35dc17d001fca93a2cdb161891e20885c9d5df428fa73c78de07" + } + ] + }, + { + "name": "kind_take_commit", + "about": "take_commit (§4.12): opaque blobs, read for their length alone", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000c2800b38548c5461bb31a403fb72cef54db426c22d709ae17af8dea3fabfb2288798800000000000000004300946982607f16f56e0edae38d5d8196cf4b0b73c6cab1012eb6171518e9a1c0da9b3455df9a69ef1e34543a3136acad74f09c32af209d40931dc51b20ff07", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000007ddf55ff4c4b8e52f570e3afd8cb9a3e68a2383a687b0d15be7c512cb1cc073500093d0000000000000c48006b9399246e004d2c4bd716dc7a2c62568584a20245fce820e00cacc32480071069efad661fe1396a0c96fd284c8adaea5afbeae220a9565fcbc04e57be59ba8d01010101010101012d8094cda5b0eb02b23b79dfc03cae080d1fc6c80dbbf9b50eed6ae27926388a70deec1565cefb12a5e28bcf2d9408f2698590db307dd95e7a5e86e6829d3805" + ], + "outcome": "accept", + "digests": [ + "7ddf55ff4c4b8e52f570e3afd8cb9a3e68a2383a687b0d15be7c512cb1cc0735", + "4005193e9b13609564024ac2c24cffcdda3dcb5bbe797f324588fc8eded48b08" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAwoALOFSMVGG7MaQD-3LO9U20JsItcJrhevjeo_q_siiHmIAAAAAAAAAABDAJRpgmB_FvVuDtrjjV2Bls9LC3PGyrEBLrYXFRjpocDamzRV35pp7x40VDoxNqytdPCcMq8gnUCTHcUbIP8H\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"7ddf55ff4c4b8e52f570e3afd8cb9a3e68a2383a687b0d15be7c512cb1cc0735\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAwoALOFSMVGG7MaQD-3LO9U20JsItcJrhevjeo_q_siiHmIAAAAAAAAAABDAJRpgmB_FvVuDtrjjV2Bls9LC3PGyrEBLrYXFRjpocDamzRV35pp7x40VDoxNqytdPCcMq8gnUCTHcUbIP8H\"", + "emsg": "0000011d656d736701000000000003e80000000000002ee0000000007ddf55ff75726e3a7761693a6576656e743a310074616b655f636f6d6d6974005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000c2800b38548c5461bb31a403fb72cef54db426c22d709ae17af8dea3fabfb2288798800000000000000004300946982607f16f56e0edae38d5d8196cf4b0b73c6cab1012eb6171518e9a1c0da9b3455df9a69ef1e34543a3136acad74f09c32af209d40931dc51b20ff07" + }, + { + "msf": "{\"t\":1792108804000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAAB931X_TEuOUvVw46_Yy5o-aKI4Omh7DRW-fFEsscwHNQAJPQAAAAAAAAxIAGuTmSRuAE0sS9cW3HosYlaFhKICRfzoIOAMrMMkgAcQae-tZh_hOWoMlv0oTIra6lr76uIgqVZfy8BOV75Zuo0BAQEBAQEBAS2AlM2lsOsCsjt538A8rggNH8bIDbv5tQ7tauJ5JjiKcN7sFWXO-xKl4ovPLZQI8mmFkNswfdleel6G5oKdOAU\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"4005193e9b13609564024ac2c24cffcdda3dcb5bbe797f324588fc8eded48b08\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAAB931X_TEuOUvVw46_Yy5o-aKI4Omh7DRW-fFEsscwHNQAJPQAAAAAAAAxIAGuTmSRuAE0sS9cW3HosYlaFhKICRfzoIOAMrMMkgAcQae-tZh_hOWoMlv0oTIra6lr76uIgqVZfy8BOV75Zuo0BAQEBAQEBAS2AlM2lsOsCsjt538A8rggNH8bIDbv5tQ7tauJ5JjiKcN7sFWXO-xKl4ovPLZQI8mmFkNswfdleel6G5oKdOAU\"", + "emsg": "0000013d656d736701000000000003e800000000000036b0000000004005193e75726e3a7761693a6576656e743a310074616b655f636f6d6d6974005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000007ddf55ff4c4b8e52f570e3afd8cb9a3e68a2383a687b0d15be7c512cb1cc073500093d0000000000000c48006b9399246e004d2c4bd716dc7a2c62568584a20245fce820e00cacc32480071069efad661fe1396a0c96fd284c8adaea5afbeae220a9565fcbc04e57be59ba8d01010101010101012d8094cda5b0eb02b23b79dfc03cae080d1fc6c80dbbf9b50eed6ae27926388a70deec1565cefb12a5e28bcf2d9408f2698590db307dd95e7a5e86e6829d3805" + } + ] + }, + { + "name": "kind_lifecycle", + "about": "the lifecycle kinds (§4.13), authored by the room authority under a policy that permits them", + "room": "main", + "default_policy": "default", + "policies": { + "6ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b": "authority" + }, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93d39eaa721d4db82adbf4b9694bf4ba8fab604a1a148ed0d0d429833e7b2c61599e2339215f45442446dc634b5e8fd44bd5b44cb574960a2c86c9c761cde7a40c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0100000000000000633fb716922c4f1246493c7ffac907fe442e21ff5c69c28035d8de8b7de90d1040420f000000000000122500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93766964656f357e74e9f8e5515478d0160c2ce2dbdcc8826cd24e92768b38f66675f218793fad8bb3122e6e161acbc363348ea93f3a14eade7b56887c0de749ac937e266b07", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b02000000000000006c562fab785112ab3600e3909788997736641c3a0e1099a15e7e697fd73760b580841e000000000000144000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce935bbe849798f371cec3acf4e10ef93a1489694e9a9454bafd2181f853cc10f934ab3eaa257490ce7216e1b39b7828e020b4a6fdb5a679eaf98f54786b1487fc21cd14383534777541d579c6a45ad767ca74a0e3f0c1d75b1f22013ba3511feb0f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0300000000000000a070c02dc231680aec1642c6691f04eace7ca2da9f15c93c0dada9e14de1a8c4c0c62d000000000000102000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765fa91b4a97ff55f47d3a973322eb838afcf6b8273d740f31d4efafaf95eba39b542539f88c3a7345025fb4092df46ccab0de2f23da600031552b1292243f46f0c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b040000000000000051175f4d2e8fc74491556d8fa4318d559a7d8bb5cb8cc060e2e97ced455ca31200093d000000000000152500b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765766964656f9dccd196a49eacf012749c6c989a6ec5b633967eff9d7e61778c3cb1ed7fe91114d7da84579c25a578aadc0dfe6bc5945f902c12a83faf7599738089abc74807", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b05000000000000008f8cece9f675b7b4ac33c09b7cef0a87f4ee648818e2ddb98afc5f762d2c534a404b4c000000000000162500b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765617564696f7e901b27770e314f67bb878503aee07179e7312d6f9325958f5b46465fa901fc84083d879a8a5be5eb7b059754e62cb1901e88cebf133dc60392e89d2d544406", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b060000000000000094e94ec5a88ad30d67f015d39561d90386cfd0044636e8b05aa2f1d3077e8513808d5b000000000000132500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93766964656f712a8c4498aa91f2c0075dd41e70921e0667d0732ad87922145911d4984b14db20912b4126e046e79a627952a65b8b69d9dde65b4299306d8c5c1d010dea9a02", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0700000000000000eef69d127c5830f857a78c230c6cff322cce2755e2a32c985ff8d9b8f23c01dcc0cf6a000000000000112000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93ea9f3a7ebfe746d49affb4f3f9ee72b2a3da3c8c08d5ef870b799b8b306f25448a10d1cfae8a43556da520668a4aebbbf01658546e185d89eaa72fd07aa8700c" + ], + "outcome": "accept", + "digests": [ + "633fb716922c4f1246493c7ffac907fe442e21ff5c69c28035d8de8b7de90d10", + "6c562fab785112ab3600e3909788997736641c3a0e1099a15e7e697fd73760b5", + "a070c02dc231680aec1642c6691f04eace7ca2da9f15c93c0dada9e14de1a8c4", + "51175f4d2e8fc74491556d8fa4318d559a7d8bb5cb8cc060e2e97ced455ca312", + "8f8cece9f675b7b4ac33c09b7cef0a87f4ee648818e2ddb98afc5f762d2c534a", + "94e94ec5a88ad30d67f015d39561d90386cfd0044636e8b05aa2f1d3077e8513", + "eef69d127c5830f857a78c230c6cff322cce2755e2a32c985ff8d9b8f23c01dc", + "6f00adc96f28d6948efd4d3f22f09e35c46267b4f67f23d6f9b7950c7edb7a05" + ], + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "bindings": [ + { + "msf": "{\"t\":1792108800000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86T056qch1NuCrb9LlpS_S6j6tgShoUjtDQ1CmDPnssYVmeIzkhX0VEJEbcY0tej9RL1bRMtXSWCiyGycdhzeekDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"633fb716922c4f1246493c7ffac907fe442e21ff5c69c28035d8de8b7de90d10\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:00.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86T056qch1NuCrb9LlpS_S6j6tgShoUjtDQ1CmDPnssYVmeIzkhX0VEJEbcY0tej9RL1bRMtXSWCiyGycdhzeekDA\"", + "emsg": "0000010e656d736701000000000003e8000000000000271000000000633fb71675726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93d39eaa721d4db82adbf4b9694bf4ba8fab604a1a148ed0d0d429833e7b2c61599e2339215f45442446dc634b5e8fd44bd5b44cb574960a2c86c9c761cde7a40c" + }, + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AQAAAAAAAABjP7cWkixPEkZJPH_6yQf-RC4h_1xpwoA12N6LfekNEEBCDwAAAAAAABIlAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TdmlkZW81fnTp-OVRVHjQFgws4tvcyIJs0k6Sdos49mZ18hh5P62LsxIubhYay8NjNI6pPzoU6t57Voh8DedJrJN-JmsH\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"6c562fab785112ab3600e3909788997736641c3a0e1099a15e7e697fd73760b5\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AQAAAAAAAABjP7cWkixPEkZJPH_6yQf-RC4h_1xpwoA12N6LfekNEEBCDwAAAAAAABIlAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TdmlkZW81fnTp-OVRVHjQFgws4tvcyIJs0k6Sdos49mZ18hh5P62LsxIubhYay8NjNI6pPzoU6t57Voh8DedJrJN-JmsH\"", + "emsg": "00000116656d736701000000000003e80000000000002af8000000006c562fab75726e3a7761693a6576656e743a31007075626c697368005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0100000000000000633fb716922c4f1246493c7ffac907fe442e21ff5c69c28035d8de8b7de90d1040420f000000000000122500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93766964656f357e74e9f8e5515478d0160c2ce2dbdcc8826cd24e92768b38f66675f218793fad8bb3122e6e161acbc363348ea93f3a14eade7b56887c0de749ac937e266b07" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AgAAAAAAAABsVi-reFESqzYA45CXiJl3NmQcOg4QmaFefml_1zdgtYCEHgAAAAAAABRAAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TW76El5jzcc7DrPThDvk6FIlpTpqUVLr9IYH4U8wQ-TSrPqoldJDOchbhs5t4KOAgtKb9taZ56vmPVHhrFIf8Ic0UODU0d3VB1XnGpFrXZ8p0oOPwwddbHyIBO6NRH-sP\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"a070c02dc231680aec1642c6691f04eace7ca2da9f15c93c0dada9e14de1a8c4\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AgAAAAAAAABsVi-reFESqzYA45CXiJl3NmQcOg4QmaFefml_1zdgtYCEHgAAAAAAABRAAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TW76El5jzcc7DrPThDvk6FIlpTpqUVLr9IYH4U8wQ-TSrPqoldJDOchbhs5t4KOAgtKb9taZ56vmPVHhrFIf8Ic0UODU0d3VB1XnGpFrXZ8p0oOPwwddbHyIBO6NRH-sP\"", + "emsg": "00000138656d736701000000000003e80000000000002ee000000000a070c02d75726e3a7761693a6576656e743a31006772616e745f65786368616e6765005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b02000000000000006c562fab785112ab3600e3909788997736641c3a0e1099a15e7e697fd73760b580841e000000000000144000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce935bbe849798f371cec3acf4e10ef93a1489694e9a9454bafd2181f853cc10f934ab3eaa257490ce7216e1b39b7828e020b4a6fdb5a679eaf98f54786b1487fc21cd14383534777541d579c6a45ad767ca74a0e3f0c1d75b1f22013ba3511feb0f" + }, + { + "msf": "{\"t\":1792108803000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AwAAAAAAAACgcMAtwjFoCuwWQsZpHwTqznyi2p8VyTwNranhTeGoxMDGLQAAAAAAABAgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdl-pG0qX_1X0fTqXMyLrg4r89rgnPXQPMdTvr6-V66ObVCU5-Iw6c0UCX7QJLfRsyrDeLyPaYAAxVSsSkiQ_RvDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"51175f4d2e8fc74491556d8fa4318d559a7d8bb5cb8cc060e2e97ced455ca312\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AwAAAAAAAACgcMAtwjFoCuwWQsZpHwTqznyi2p8VyTwNranhTeGoxMDGLQAAAAAAABAgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdl-pG0qX_1X0fTqXMyLrg4r89rgnPXQPMdTvr6-V66ObVCU5-Iw6c0UCX7QJLfRsyrDeLyPaYAAxVSsSkiQ_RvDA\"", + "emsg": "0000010e656d736701000000000003e800000000000032c80000000051175f4d75726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0300000000000000a070c02dc231680aec1642c6691f04eace7ca2da9f15c93c0dada9e14de1a8c4c0c62d000000000000102000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765fa91b4a97ff55f47d3a973322eb838afcf6b8273d740f31d4efafaf95eba39b542539f88c3a7345025fb4092df46ccab0de2f23da600031552b1292243f46f0c" + }, + { + "msf": "{\"t\":1792108804000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BAAAAAAAAABRF19NLo_HRJFVbY-kMY1Vmn2LtcuMwGDi6XztRVyjEgAJPQAAAAAAABUlALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdldmlkZW-dzNGWpJ6s8BJ0nGyYmm7FtjOWfv-dfmF3jDyx7X_pERTX2oRXnCWleKrcDf5rxZRfkCwSqD-vdZlzgImrx0gH\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8f8cece9f675b7b4ac33c09b7cef0a87f4ee648818e2ddb98afc5f762d2c534a\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BAAAAAAAAABRF19NLo_HRJFVbY-kMY1Vmn2LtcuMwGDi6XztRVyjEgAJPQAAAAAAABUlALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdldmlkZW-dzNGWpJ6s8BJ0nGyYmm7FtjOWfv-dfmF3jDyx7X_pERTX2oRXnCWleKrcDf5rxZRfkCwSqD-vdZlzgImrx0gH\"", + "emsg": "00000117656d736701000000000003e800000000000036b0000000008f8cece975726e3a7761693a6576656e743a310074616b656f766572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b040000000000000051175f4d2e8fc74491556d8fa4318d559a7d8bb5cb8cc060e2e97ced455ca31200093d000000000000152500b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765766964656f9dccd196a49eacf012749c6c989a6ec5b633967eff9d7e61778c3cb1ed7fe91114d7da84579c25a578aadc0dfe6bc5945f902c12a83faf7599738089abc74807" + }, + { + "msf": "{\"t\":1792108805000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BQAAAAAAAACPjOzp9nW3tKwzwJt87wqH9O5kiBji3bmK_F92LSxTSkBLTAAAAAAAABYlALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlYXVkaW9-kBsndw4xT2e7h4UDruBxeecxLW-TJZWPW0ZGX6kB_IQIPYeailvl63sFl1TmLLGQHojOvxM9xgOS6J0tVEQG\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"94e94ec5a88ad30d67f015d39561d90386cfd0044636e8b05aa2f1d3077e8513\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BQAAAAAAAACPjOzp9nW3tKwzwJt87wqH9O5kiBji3bmK_F92LSxTSkBLTAAAAAAAABYlALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlYXVkaW9-kBsndw4xT2e7h4UDruBxeecxLW-TJZWPW0ZGX6kB_IQIPYeailvl63sFl1TmLLGQHojOvxM9xgOS6J0tVEQG\"", + "emsg": "00000117656d736701000000000003e80000000000003a980000000094e94ec575726e3a7761693a6576656e743a31006661696c6f766572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b05000000000000008f8cece9f675b7b4ac33c09b7cef0a87f4ee648818e2ddb98afc5f762d2c534a404b4c000000000000162500b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765617564696f7e901b27770e314f67bb878503aee07179e7312d6f9325958f5b46465fa901fc84083d879a8a5be5eb7b059754e62cb1901e88cebf133dc60392e89d2d544406" + }, + { + "msf": "{\"t\":1792108806000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BgAAAAAAAACU6U7FqIrTDWfwFdOVYdkDhs_QBEY26LBaovHTB36FE4CNWwAAAAAAABMlAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TdmlkZW9xKoxEmKqR8sAHXdQecJIeBmfQcyrYeSIUWRHUmEsU2yCRK0Em4EbnmmJ5UqZbi2nZ3eZbQpkwbYxcHQEN6poC\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"eef69d127c5830f857a78c230c6cff322cce2755e2a32c985ff8d9b8f23c01dc\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BgAAAAAAAACU6U7FqIrTDWfwFdOVYdkDhs_QBEY26LBaovHTB36FE4CNWwAAAAAAABMlAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TdmlkZW9xKoxEmKqR8sAHXdQecJIeBmfQcyrYeSIUWRHUmEsU2yCRK0Em4EbnmmJ5UqZbi2nZ3eZbQpkwbYxcHQEN6poC\"", + "emsg": "00000118656d736701000000000003e80000000000003e8000000000eef69d1275726e3a7761693a6576656e743a3100756e7075626c697368005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b060000000000000094e94ec5a88ad30d67f015d39561d90386cfd0044636e8b05aa2f1d3077e8513808d5b000000000000132500c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93766964656f712a8c4498aa91f2c0075dd41e70921e0667d0732ad87922145911d4984b14db20912b4126e046e79a627952a65b8b69d9dde65b4299306d8c5c1d010dea9a02" + }, + { + "msf": "{\"t\":1792108807000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BwAAAAAAAADu9p0SfFgw-FenjCMMbP8yLM4nVeKjLJhf-Nm48jwB3MDPagAAAAAAABEgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86T6p86fr_nRtSa_7Tz-e5ysqPaPIwI1e-HC3mbizBvJUSKENHPropDVW2lIGaKSuu78BZYVG4YXYnqpy_QeqhwDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"6f00adc96f28d6948efd4d3f22f09e35c46267b4f67f23d6f9b7950c7edb7a05\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:07.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BwAAAAAAAADu9p0SfFgw-FenjCMMbP8yLM4nVeKjLJhf-Nm48jwB3MDPagAAAAAAABEgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86T6p86fr_nRtSa_7Tz-e5ysqPaPIwI1e-HC3mbizBvJUSKENHPropDVW2lIGaKSuu78BZYVG4YXYnqpy_QeqhwDA\"", + "emsg": "0000010f656d736701000000000003e80000000000004268000000006f00adc975726e3a7761693a6576656e743a31006c65617665005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0700000000000000eef69d127c5830f857a78c230c6cff322cce2755e2a32c985ff8d9b8f23c01dcc0cf6a000000000000112000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93ea9f3a7ebfe746d49affb4f3f9ee72b2a3da3c8c08d5ef870b799b8b306f25448a10d1cfae8a43556da520668a4aebbbf01658546e185d89eaa72fd07aa8700c" + } + ] + }, + { + "name": "room_interleaved", + "about": "a room of four participants and its authority, their chains interleaved in delivery order across three one-minute groups: lifecycle, captions, chat, reactions, anchored markers and a cue, and a poll closed with the tally the replay reaches", + "room": "main", + "default_policy": "default", + "policies": { + "6ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b": "authority" + }, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001020006ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e1fb4dfa6a922cc852ba0e3371df639b6b71ba3429e95c5f2a03546fb96c4d1fe10cdeb4362bb5a8964162a0867b674f53ff57896b1e5d243c53d06ff7ea95600", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b01000000000000002887895f327bfdaff0dfe7a0029d095243da6adbb9f66c1305c59ebd90c412fd000000000000000000102000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93b147cf981201a29558ab52b608890f6db350c97cc262c6da0a78b88269cd80230e4a89b2b0fe32a87f7baf4a6729ac1acc7ed133fe9b47fd7afeaff85a7c750b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b020000000000000032431753cbcb4de8f903c527e34844217bdd1f039ad4044acf13006e23c0f81e20a107000000000000102000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650ecf708e0716242c6d2946f309f821520fff534c29271f231a241e99b6a0381f5a5c166576e765441acfc7bfe719aaefa604ff18ed449936d8feda82839a250b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000a1700b80b00000102656e0d00476f6f64206576656e696e672e49aa8f63c2b9a9469931e39b8582b2295fb240f6580de0df47cb71b67d6489b3df5f386cb17233b4847c6e7f511cf0ec833f9cbe0b8a215d1d98273d107f950d", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000060e3160000000000000308000600686920616c6c0fb2fab607d765d5dcf0c802fe423451c0de49b2d4224db832e392da48cd45d19441fb8562e8d7002605e040bdc7ad436106c84aa8463b14a41956dc0732060c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b030000000000000032b966690fada092f06f490ce0738deafb9ad101b9a412729af88f06fe8de6d280841e00000000000010200007122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139be6f7075f6a1d96804484d8bd9e7dfdc500aeb2e680b703ad4a6304b949ba09c9d8f49950d2e2c2494272b17c5819191455719a5a45cd2f8c88a84cfa27a9d06", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000031500130068656c6c6f2066726f6d20746865206261636b1deda2fc34bb8ab0bac3e5489b9a0b90259daea0d770dc8b640972921be85b294284e30c01120e0dc82472b07bea773713f25c90f2ce3a8d347dc44a7f2b0e07", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013900000000000000000000000000000000000000000000000000000000000000000000000000000000a0252600000000000004040004010000a639d5809b4f27eed3763cbcfbb7d7759ce49ece27f5de4546524346583829fb5c887abe04ede3891ce00bb4840660270e405068d34d459adb04755e0d6efa04", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000003981276b70d83c7cdea7fdb179981a1fcc959e0ab27c548d04fe8504c09202cac0c62d000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb600000000000000004800000000000000080d0001000000010500696e74726f00199f350f93021810e0b08c4aecdac5e5e35bd4a45a191fb71b59ca24fd8ffc476e4214998b420acb238acd6e9728c414978e79b8c87b86e21e14407a1d870404", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e020000000000000033f0d71cfd0619235a558134097348388543d45c32f98b1b458e9f7b72b0d667404b4c0000000000000523001000576869636820736f6e67206e6578743f02060042616c6c61640600416e7468656d8a05cc8df3cb788b80999b7f8a1968b6cf3e6d33f61c789c2feb7edd5bbf1badde3ce9dded2329c5e6c571ccca925ce2cffd326630a8138642c3711e158e2d0a", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000008d400c99761c9421179b99bd9011517b9597fb9e016eefe2afbc9bb41a0dfeae808d5b0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517012025180520f2ac5294e2fcf1a6a9c6c5a90042743a39f51840d12659deeeaa8368a07832e5a72d556b5ce500402027f2e1443763a0df797f55f3b22d7fada006", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013901000000000000000519d7ce67722abf857b595af6795a28b2e1f1bfdc65ee65e40efe8cf4339ede808d5b0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751701d72973bac079b3e92d66acd86054359db56498f1b5595184fa86531be835d05c969755aab38e1eb04763d2d06dfa8c166acfcd6677037db50ed65a201ca27104", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650100000000000000a06555b2c85e6665add6c6a5819ce55304707b4d02c78a717b6da9cd7d420a30c09a5e0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751700c755ba3e9ddb0a34e96fa742ae463e412e32e5c034202e1674a3358b8c4160de13d79dad3d6f24a5a59eaa2773c8aaff2787239d5725fc3d38136e51d082cd08", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013902000000000000001165030d3cde974b4b35f8509ea47b0a5d605c9bd64bc81c78cb52900e978d3cc0cf6a000000000000030f000d00616e7468656d20706c656173652f4555162df5095f1cd001dd7cfd1f110b9c81ac6bfa81829c56444a1b638d953f6f02d2ef0cc032c85a46720896fd230c2ce538fb2bce56c6d836d261a4b300", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000e8abc0c50ec3cf2ab7cf33e035265e7cca4b8fa26ece4c57f84800904852b63f60566c0000000000000424000103000125547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3689a8a4fda5c270e0daa420cf96b20d2c5eb1c4a96fca9e53dc5f74a56c4b9e7431a4edd5e146cdc4f8cb1a48ca374d8f869fcf311745d03fb1dc3bec929ab0d", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765020000000000000066b25ca56d98a87b8d0e9c1f5100302e3327131fc7b0881a9e9586d4f179884760566c0000000000000424000101000125547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e36481d08d1e9630c5b84b0760a7df0801906847ef15a0c8fc607d8b0697b514cdc2f34d26a898ffec0ab2f763d1211149cc96b5dd042695236ae9a324ef620e0f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e03000000000000005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751780c3c90100000000000729005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517020100000002000000993cc2f54e6047d81be562af09382ad7efc0e33bd526eb4c54483eb0555d87e9d67b5a9a14152eaa87b3f7c9ea50a233f23990c8e86663e4aad90bb1039ef30d", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e040000000000000095260ba9a539409d6f8b7b99cd0081a1de4ee17a604e1df655f807e61b9cca6480c3c9010000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000d002000000000000020a000307000000905f010000c9a9ed66a1f4946e5b862580d4caf28bd569995ba3b46b02d7c21235c9717a2ab13370f079ed37f3f2d8746e181d84ff51e5466c6c9ce029c62f91b61f5e9301", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300000000000000193237c7e347b1d494a1bc8a273e18fcf3f277e76c06b2f6d151692995f79edfc044840300000000000404000101000083dc521a57488cf42c7603642f513c98eab2d37ff26a21e5f78a7396bd2d581d4accc2098ed180a24cc4f2638cc81564895a72e488229d6f24ec0b2a68f4f20f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e05000000000000004143079bca3f1bfac36f55b4586017d1b173127268ccea53dc19d543479bb2a240c9a20300000000000a4400a00f000002d2bf82e050ac816197b536596230cab88a86a5a958401d35e58d8e39b2e3a81202656e1a0054686973206f6e652069732063616c6c656420416e7468656d2e6d86bc3527e3bc4ada31c9fa05461af1d1c7e6b3ae655ec21b51bcf642152ac9bfebb7995502f1b56162876fabf5086c6f2d295dc94caeb6c09c9cd8bd213203", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139030000000000000025547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3800bb20300000000000306000400f09f8eb61fa0e18bb3ae33099ca6ed33b942104385bbb1920a0f8ffc4551c2ffa0efe34a6b7d278d86a6a87da2d2090dd3472d5e04129afb1fb597867a297af5b106df09", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650300000000000000ddd7f60422f72e693fd4c8fcea8f14a3989a624580509336472918cd832f1936800bb203000000000004040004010000040007e9e4c3a7d6246fcbbc084ef27ec0a160aa32a317374ec2ac532a2d328a3bcdcd647d7dc573bdeddaac229acb6f034f919f23777ae2e5b492d5044f6b0f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93040000000000000014eeaaba6836186c4df1a582dda3145161bdff96ff0704ec1801d95db96f96a6c04dc103000000000004040004010000fbb0929b43c34dda832b04dc42ad19ab91bd1342df2609f87fa7450a250f63409afbebbc1b3ce878581d6220f297f8512dae552d08a729d21570a28e9bddf907", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0600000000000000b5fa0dfc43cc93a23d53546ce8fbfeb8b6f87634a4644f2e49428683a9a31de50090d0030000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb601000000000000006000000000000000080e000200000001060063686f727573004cd9c9a1a134dc5ae3af781fbc1316272353ed92480c2bdaf1d1238a7e65175dae0d043c0635974b187172e398e0377fcca4acf37e28213d45c2f3ab95ecb606", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b040000000000000008f8b71ac18d8e7820b6be75b73c3623e237a5b2abffae59e2d8b6add90a16b6804a5d050000000000112000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765ac667f864303272dbfd2c8e59325fdf79096c7c5823f993f19d102e8537550dbaf8b3f2b2954e33ee2ee539b199cc65cd94c8b850f2945be7d205393e585b001", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0700000000000000280ad051383cd7d9e164ef14e2b7f0c164d7c49ac4313f900f2b4efc6851dce6ff0d27070000000000030b0009006c61737420736f6e6775b7c8bf8fa64eb842114a8edc29f51b084ba7b48bc1a0a482650287a6592ec1fb6fd7e41d563584861ed8aeb6d72d3537b7ea23d31a8a140ff468b84b383809", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e080000000000000016f55f87e1786b727bbfb7e17d1ffa6642eafd9c8eb9e30fc4fba1864f534160000e270700000000000a1400d00700000102656e0a005468616e6b20796f7521859bfc4bec2c645215935bb3efc63e4fbe962fed53c10e0162ddc8565cb21dd95da09b6a3bc47d3dcf1c71be0e99f8bf1831a2cd28826b852463987e3d0a2301", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9305000000000000004c97d83020b9a16f60e2b32e4741bab04e4c976dd23f92915f53f5b47e0ae1ae4050360700000000000307000500627261766f0a51f75ea6ee8df22786ec9dce5b4429aa42c460417f2cfcffed64b4c5fd0f999d09b821c751ce3fd87c9c09fe7e72c4fc3d4798ec8bcfa816e8240d1805da0e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013904000000000000004896a1e1c65fecba9e8aff6ff4c9bdbcea431a6285f9f5e94c5f54b31ecc50f1405036070000000000040400010300003adf16ed59535b111cfd115dd79983008a4a77e6e511ca2e8013f86d21bc5522f70bf00712a6c5c405b3cc1bb10320f5fa97dee9c864fd8c7d14da2f535f4e08", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b05000000000000002affe8118ac27644f0ca3e8b5049a974e753da2323b9f1b93ee075da8c0bc60840597307000000000011200007122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013980ac117cca22beb9e65476d370b7bfbf8b657d9e29693b082211d3f16efea9955bcbf094147dd801e4d35983030ca6dcfe87749f87776e3a0a76a2a8ee1cd70a" + ], + "outcome": "accept", + "digests": [ + "2887895f327bfdaff0dfe7a0029d095243da6adbb9f66c1305c59ebd90c412fd", + "32431753cbcb4de8f903c527e34844217bdd1f039ad4044acf13006e23c0f81e", + "32b966690fada092f06f490ce0738deafb9ad101b9a412729af88f06fe8de6d2", + "3981276b70d83c7cdea7fdb179981a1fcc959e0ab27c548d04fe8504c09202ca", + "8d400c99761c9421179b99bd9011517b9597fb9e016eefe2afbc9bb41a0dfeae", + "08f8b71ac18d8e7820b6be75b73c3623e237a5b2abffae59e2d8b6add90a16b6", + "a06555b2c85e6665add6c6a5819ce55304707b4d02c78a717b6da9cd7d420a30", + "0519d7ce67722abf857b595af6795a28b2e1f1bfdc65ee65e40efe8cf4339ede", + "33f0d71cfd0619235a558134097348388543d45c32f98b1b458e9f7b72b0d667", + "5f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517", + "e8abc0c50ec3cf2ab7cf33e035265e7cca4b8fa26ece4c57f84800904852b63f", + "1165030d3cde974b4b35f8509ea47b0a5d605c9bd64bc81c78cb52900e978d3c", + "66b25ca56d98a87b8d0e9c1f5100302e3327131fc7b0881a9e9586d4f1798847", + "25547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3", + "193237c7e347b1d494a1bc8a273e18fcf3f277e76c06b2f6d151692995f79edf", + "ddd7f60422f72e693fd4c8fcea8f14a3989a624580509336472918cd832f1936", + "95260ba9a539409d6f8b7b99cd0081a1de4ee17a604e1df655f807e61b9cca64", + "4143079bca3f1bfac36f55b4586017d1b173127268ccea53dc19d543479bb2a2", + "14eeaaba6836186c4df1a582dda3145161bdff96ff0704ec1801d95db96f96a6", + "b5fa0dfc43cc93a23d53546ce8fbfeb8b6f87634a4644f2e49428683a9a31de5", + "4896a1e1c65fecba9e8aff6ff4c9bdbcea431a6285f9f5e94c5f54b31ecc50f1", + "5a6b11fe73bf0d2850503022f52125ec1942675ded3ab8eee9170faaa43a2397", + "4c97d83020b9a16f60e2b32e4741bab04e4c976dd23f92915f53f5b47e0ae1ae", + "280ad051383cd7d9e164ef14e2b7f0c164d7c49ac4313f900f2b4efc6851dce6", + "2affe8118ac27644f0ca3e8b5049a974e753da2323b9f1b93ee075da8c0bc608", + "16f55f87e1786b727bbfb7e17d1ffa6642eafd9c8eb9e30fc4fba1864f534160", + "5e265657abcfb840ca5a78862c82cf04d2220fd53f62fdf4622c661f437053ca", + "6d054dcd9f995d40766a3ee4e08a5c9082d537da1324ca9ac5e90ae4ac8919b9", + "5a9df56a498d6151c4363d3a4614e613e10a73d71ee13aa98377276d216f0325", + "443a6168949972c9d61494bda354c351b78811f0af8a3fe06eaf76b028936c1f" + ], + "tally": { + "state_hash": "0008e69a5622f80bc5329d4bb65326721554b656fe36e8005f2a030c3eea6776", + "polls": [ + { + "poll": "5f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517", + "open": false, + "counts": [ + 1, + 2 + ] + } + ] + }, + "bindings": [ + { + "msf": "{\"t\":1792108800000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgAGul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-H7TfpqkizIUroOM3HfY5trcbo0KelcXyoDVG-5bE0f4QzetDYrtaiWQWKghntnT1P_V4lrHl0kPFPQb_fqlWAA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"2887895f327bfdaff0dfe7a0029d095243da6adbb9f66c1305c59ebd90c412fd\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:00.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgAGul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-H7TfpqkizIUroOM3HfY5trcbo0KelcXyoDVG-5bE0f4QzetDYrtaiWQWKghntnT1P_V4lrHl0kPFPQb_fqlWAA\"", + "emsg": "0000010e656d736701000000000003e80000000000002710000000002887895f75726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001020006ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e1fb4dfa6a922cc852ba0e3371df639b6b71ba3429e95c5f2a03546fb96c4d1fe10cdeb4362bb5a8964162a0867b674f53ff57896b1e5d243c53d06ff7ea95600" + }, + { + "msf": "{\"t\":1792108800000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AQAAAAAAAAAoh4lfMnv9r_Df56ACnQlSQ9pq27n2bBMFxZ69kMQS_QAAAAAAAAAAABAgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TsUfPmBIBopVYq1K2CIkPbbNQyXzCYsbaCni4gmnNgCMOSomysP4yqH97r0pnKawazH7RM_6bR_16_q_4Wnx1Cw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"32431753cbcb4de8f903c527e34844217bdd1f039ad4044acf13006e23c0f81e\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:00.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AQAAAAAAAAAoh4lfMnv9r_Df56ACnQlSQ9pq27n2bBMFxZ69kMQS_QAAAAAAAAAAABAgAMKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TsUfPmBIBopVYq1K2CIkPbbNQyXzCYsbaCni4gmnNgCMOSomysP4yqH97r0pnKawazH7RM_6bR_16_q_4Wnx1Cw\"", + "emsg": "0000010e656d736701000000000003e80000000000002710000000003243175375726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b01000000000000002887895f327bfdaff0dfe7a0029d095243da6adbb9f66c1305c59ebd90c412fd000000000000000000102000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93b147cf981201a29558ab52b608890f6db350c97cc262c6da0a78b88269cd80230e4a89b2b0fe32a87f7baf4a6729ac1acc7ed133fe9b47fd7afeaff85a7c750b" + }, + { + "msf": "{\"t\":1792108800500,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AgAAAAAAAAAyQxdTy8tN6PkDxSfjSEQhe90fA5rUBErPEwBuI8D4HiChBwAAAAAAABAgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlDs9wjgcWJCxtKUbzCfghUg__U0wpJx8jGiQembagOB9aXBZldudlRBrPx7_nGarvpgT_GO1EmTbY_tqCg5olCw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"32b966690fada092f06f490ce0738deafb9ad101b9a412729af88f06fe8de6d2\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:00.500Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AgAAAAAAAAAyQxdTy8tN6PkDxSfjSEQhe90fA5rUBErPEwBuI8D4HiChBwAAAAAAABAgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlDs9wjgcWJCxtKUbzCfghUg__U0wpJx8jGiQembagOB9aXBZldudlRBrPx7_nGarvpgT_GO1EmTbY_tqCg5olCw\"", + "emsg": "0000010e656d736701000000000003e800000000000029040000000032b9666975726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b020000000000000032431753cbcb4de8f903c527e34844217bdd1f039ad4044acf13006e23c0f81e20a107000000000000102000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650ecf708e0716242c6d2946f309f821520fff534c29271f231a241e99b6a0381f5a5c166576e765441acfc7bfe719aaefa604ff18ed449936d8feda82839a250b" + }, + { + "msf": "{\"t\":1792108801000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAoXALgLAAABAmVuDQBHb29kIGV2ZW5pbmcuSaqPY8K5qUaZMeObhYKyKV-yQPZYDeDfR8txtn1kibPfXzhssXIztIR8bn9RHPDsgz-cvguKIV0dmCc9EH-VDQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"3981276b70d83c7cdea7fdb179981a1fcc959e0ab27c548d04fe8504c09202ca\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.000Z\",DURATION=3.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBCDwAAAAAAAAoXALgLAAABAmVuDQBHb29kIGV2ZW5pbmcuSaqPY8K5qUaZMeObhYKyKV-yQPZYDeDfR8txtn1kibPfXzhssXIztIR8bn9RHPDsgz-cvguKIV0dmCc9EH-VDQ\"", + "emsg": "00000108656d736701000000000003e80000000000002af800000bb83981276b75726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000a1700b80b00000102656e0d00476f6f64206576656e696e672e49aa8f63c2b9a9469931e39b8582b2295fb240f6580de0df47cb71b67d6489b3df5f386cb17233b4847c6e7f511cf0ec833f9cbe0b8a215d1d98273d107f950d" + }, + { + "msf": "{\"t\":1792108801500,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDjFgAAAAAAAAMIAAYAaGkgYWxsD7L6tgfXZdXc8MgC_kI0UcDeSbLUIk24MuOS2kjNRdGUQfuFYujXACYF4EC9x61DYQbISqhGOxSkGVbcBzIGDA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8d400c99761c9421179b99bd9011517b9597fb9e016eefe2afbc9bb41a0dfeae\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.500Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDjFgAAAAAAAAMIAAYAaGkgYWxsD7L6tgfXZdXc8MgC_kI0UcDeSbLUIk24MuOS2kjNRdGUQfuFYujXACYF4EC9x61DYQbISqhGOxSkGVbcBzIGDA\"", + "emsg": "000000f6656d736701000000000003e80000000000002cec000000008d400c9975726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000060e3160000000000000308000600686920616c6c0fb2fab607d765d5dcf0c802fe423451c0de49b2d4224db832e392da48cd45d19441fb8562e8d7002605e040bdc7ad436106c84aa8463b14a41956dc0732060c" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AwAAAAAAAAAyuWZpD62gkvBvSQzgc43q-5rRAbmkEnKa-I8G_o3m0oCEHgAAAAAAABAgAAcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5vm9wdfah2WgESE2L2eff3FAK6y5oC3A61KYwS5SboJydj0mVDS4sJJQnKxfFgZGRRVcZpaRc0vjIioTPonqdBg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"08f8b71ac18d8e7820b6be75b73c3623e237a5b2abffae59e2d8b6add90a16b6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7AwAAAAAAAAAyuWZpD62gkvBvSQzgc43q-5rRAbmkEnKa-I8G_o3m0oCEHgAAAAAAABAgAAcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5vm9wdfah2WgESE2L2eff3FAK6y5oC3A61KYwS5SboJydj0mVDS4sJJQnKxfFgZGRRVcZpaRc0vjIioTPonqdBg\"", + "emsg": "0000010e656d736701000000000003e80000000000002ee00000000008f8b71a75726e3a7761693a6576656e743a31006a6f696e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b030000000000000032b966690fada092f06f490ce0738deafb9ad101b9a412729af88f06fe8de6d280841e00000000000010200007122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139be6f7075f6a1d96804484d8bd9e7dfdc500aeb2e680b703ad4a6304b949ba09c9d8f49950d2e2c2494272b17c5819191455719a5a45cd2f8c88a84cfa27a9d06" + }, + { + "msf": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAMVABMAaGVsbG8gZnJvbSB0aGUgYmFjax3tovw0u4qwusPlSJuaC5Alna6g13Dci2QJcpIb6FspQoTjDAESDg3IJHKwe-p3NxPyXJDyzjqNNH3ESn8rDgc\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"a06555b2c85e6665add6c6a5819ce55304707b4d02c78a717b6da9cd7d420a30\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEHgAAAAAAAAMVABMAaGVsbG8gZnJvbSB0aGUgYmFjax3tovw0u4qwusPlSJuaC5Alna6g13Dci2QJcpIb6FspQoTjDAESDg3IJHKwe-p3NxPyXJDyzjqNNH3ESn8rDgc\"", + "emsg": "00000103656d736701000000000003e80000000000002ee000000000a06555b275726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000031500130068656c6c6f2066726f6d20746865206261636b1deda2fc34bb8ab0bac3e5489b9a0b90259daea0d770dc8b640972921be85b294284e30c01120e0dc82472b07bea773713f25c90f2ce3a8d347dc44a7f2b0e07" + }, + { + "msf": "{\"t\":1792108802500,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAlJgAAAAAAAAQEAAQBAACmOdWAm08n7tN2PLz7t9d1nOSezif13kVGUkNGWDgp-1yIer4E7eOJHOALtIQGYCcOQFBo001FmtsEdV4NbvoE\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"0519d7ce67722abf857b595af6795a28b2e1f1bfdc65ee65e40efe8cf4339ede\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:02.500Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAlJgAAAAAAAAQEAAQBAACmOdWAm08n7tN2PLz7t9d1nOSezif13kVGUkNGWDgp-1yIer4E7eOJHOALtIQGYCcOQFBo001FmtsEdV4NbvoE\"", + "emsg": "000000f6656d736701000000000003e800000000000030d4000000000519d7ce75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013900000000000000000000000000000000000000000000000000000000000000000000000000000000a0252600000000000004040004010000a639d5809b4f27eed3763cbcfbb7d7759ce49ece27f5de4546524346583829fb5c887abe04ede3891ce00bb4840660270e405068d34d459adb04755e0d6efa04" + }, + { + "msf": "{\"l\":[0,72],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAA5gSdrcNg8fN6n_bF5mBofzJWeCrJ8VI0E_oUEwJICysDGLQAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAABIAAAAAAAAAAgNAAEAAAABBQBpbnRybwAZnzUPkwIYEOCwjErs2sXl41vUpFoZH7cbWcok_Y_8R25CFJmLQgrLI4rNbpcoxBSXjnm4yHuG4h4UQHodhwQE\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"33f0d71cfd0619235a558134097348388543d45c32f98b1b458e9f7b72b0d667\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAA5gSdrcNg8fN6n_bF5mBofzJWeCrJ8VI0E_oUEwJICysDGLQAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAABIAAAAAAAAAAgNAAEAAAABBQBpbnRybwAZnzUPkwIYEOCwjErs2sXl41vUpFoZH7cbWcok_Y_8R25CFJmLQgrLI4rNbpcoxBSXjnm4yHuG4h4UQHodhwQE\"", + "emsg": "0000012d656d736701000000000003e800000000000032c80000000033f0d71c75726e3a7761693a6576656e743a31006d61726b6572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000003981276b70d83c7cdea7fdb179981a1fcc959e0ab27c548d04fe8504c09202cac0c62d000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb600000000000000004800000000000000080d0001000000010500696e74726f00199f350f93021810e0b08c4aecdac5e5e35bd4a45a191fb71b59ca24fd8ffc476e4214998b420acb238acd6e9728c414978e79b8c87b86e21e14407a1d870404" + }, + { + "msf": "{\"t\":1792108805000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAAAz8Ncc_QYZI1pVgTQJc0g4hUPUXDL5ixtFjp97crDWZ0BLTAAAAAAAAAUjABAAV2hpY2ggc29uZyBuZXh0PwIGAEJhbGxhZAYAQW50aGVtigXMjfPLeIuAmZt_ihlots8-bTP2HHicL-t-3Vu_G63ePOnd7SMpxebFcczKklziz_0yZjCoE4ZCw3EeFY4tCg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"5f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAAAz8Ncc_QYZI1pVgTQJc0g4hUPUXDL5ixtFjp97crDWZ0BLTAAAAAAAAAUjABAAV2hpY2ggc29uZyBuZXh0PwIGAEJhbGxhZAYAQW50aGVtigXMjfPLeIuAmZt_ihlots8-bTP2HHicL-t-3Vu_G63ePOnd7SMpxebFcczKklziz_0yZjCoE4ZCw3EeFY4tCg\"", + "emsg": "00000116656d736701000000000003e80000000000003a98000000005f13d35c75726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e020000000000000033f0d71cfd0619235a558134097348388543d45c32f98b1b458e9f7b72b0d667404b4c0000000000000523001000576869636820736f6e67206e6578743f02060042616c6c61640600416e7468656d8a05cc8df3cb788b80999b7f8a1968b6cf3e6d33f61c789c2feb7edd5bbf1badde3ce9dded2329c5e6c571ccca925ce2cffd326630a8138642c3711e158e2d0a" + }, + { + "msf": "{\"t\":1792108806000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAACNQAyZdhyUIRebmb2QEVF7lZf7ngFu7-KvvJu0Gg3-roCNWwAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXASAlGAUg8qxSlOL88aapxsWpAEJ0Ojn1GEDRJlne7qqDaKB4MuWnLVVrXOUAQCAn8uFEN2Og33l_VfOyLX-toAY\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"e8abc0c50ec3cf2ab7cf33e035265e7cca4b8fa26ece4c57f84800904852b63f\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAACNQAyZdhyUIRebmb2QEVF7lZf7ngFu7-KvvJu0Gg3-roCNWwAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXASAlGAUg8qxSlOL88aapxsWpAEJ0Ojn1GEDRJlne7qqDaKB4MuWnLVVrXOUAQCAn8uFEN2Og33l_VfOyLX-toAY\"", + "emsg": "0000010f656d736701000000000003e80000000000003e8000000000e8abc0c575726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000008d400c99761c9421179b99bd9011517b9597fb9e016eefe2afbc9bb41a0dfeae808d5b0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517012025180520f2ac5294e2fcf1a6a9c6c5a90042743a39f51840d12659deeeaa8368a07832e5a72d556b5ce500402027f2e1443763a0df797f55f3b22d7fada006" + }, + { + "msf": "{\"t\":1792108806000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AQAAAAAAAAAFGdfOZ3Iqv4V7WVr2eVoosuHxv9xl7mXkDv6M9DOe3oCNWwAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAdcpc7rAebPpLWas2GBUNZ21ZJjxtVlRhPqGUxvoNdBclpdVqrOOHrBHY9LQbfqMFmrPzWZ3A321DtZaIByicQQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"1165030d3cde974b4b35f8509ea47b0a5d605c9bd64bc81c78cb52900e978d3c\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AQAAAAAAAAAFGdfOZ3Iqv4V7WVr2eVoosuHxv9xl7mXkDv6M9DOe3oCNWwAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAdcpc7rAebPpLWas2GBUNZ21ZJjxtVlRhPqGUxvoNdBclpdVqrOOHrBHY9LQbfqMFmrPzWZ3A321DtZaIByicQQ\"", + "emsg": "0000010f656d736701000000000003e80000000000003e80000000001165030d75726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013901000000000000000519d7ce67722abf857b595af6795a28b2e1f1bfdc65ee65e40efe8cf4339ede808d5b0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751701d72973bac079b3e92d66acd86054359db56498f1b5595184fa86531be835d05c969755aab38e1eb04763d2d06dfa8c166acfcd6677037db50ed65a201ca27104" + }, + { + "msf": "{\"t\":1792108806200,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAQAAAAAAAACgZVWyyF5mZa3WxqWBnOVTBHB7TQLHinF7banNfUIKMMCaXgAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAMdVuj6d2wo06W-nQq5GPkEuMuXANCAuFnSjNYuMQWDeE9edrT1vJKWlnqonc8iq_yeHI51XJfw9OBNuUdCCzQg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"66b25ca56d98a87b8d0e9c1f5100302e3327131fc7b0881a9e9586d4f1798847\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:06.200Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAQAAAAAAAACgZVWyyF5mZa3WxqWBnOVTBHB7TQLHinF7banNfUIKMMCaXgAAAAAAAAYhAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAMdVuj6d2wo06W-nQq5GPkEuMuXANCAuFnSjNYuMQWDeE9edrT1vJKWlnqonc8iq_yeHI51XJfw9OBNuUdCCzQg\"", + "emsg": "0000010f656d736701000000000003e80000000000003f480000000066b25ca575726e3a7761693a6576656e743a3100766f7465005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650100000000000000a06555b2c85e6665add6c6a5819ce55304707b4d02c78a717b6da9cd7d420a30c09a5e0000000000000621005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751700c755ba3e9ddb0a34e96fa742ae463e412e32e5c034202e1674a3358b8c4160de13d79dad3d6f24a5a59eaa2773c8aaff2787239d5725fc3d38136e51d082cd08" + }, + { + "msf": "{\"t\":1792108807000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AgAAAAAAAAARZQMNPN6XS0s1-FCepHsKXWBcm9ZLyBx4y1KQDpeNPMDPagAAAAAAAAMPAA0AYW50aGVtIHBsZWFzZS9FVRYt9QlfHNAB3Xz9HxELnIGsa_qBgpxWREobY42VP28C0u8MwDLIWkZyCJb9Iwws5Tj7K85Wxtg20mGkswA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"25547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:07.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AgAAAAAAAAARZQMNPN6XS0s1-FCepHsKXWBcm9ZLyBx4y1KQDpeNPMDPagAAAAAAAAMPAA0AYW50aGVtIHBsZWFzZS9FVRYt9QlfHNAB3Xz9HxELnIGsa_qBgpxWREobY42VP28C0u8MwDLIWkZyCJb9Iwws5Tj7K85Wxtg20mGkswA\"", + "emsg": "000000fd656d736701000000000003e800000000000042680000000025547a0875726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013902000000000000001165030d3cde974b4b35f8509ea47b0a5d605c9bd64bc81c78cb52900e978d3cc0cf6a000000000000030f000d00616e7468656d20706c656173652f4555162df5095f1cd001dd7cfd1f110b9c81ac6bfa81829c56444a1b638d953f6f02d2ef0cc032c85a46720896fd230c2ce538fb2bce56c6d836d261a4b300" + }, + { + "msf": "{\"t\":1792108807100,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAADoq8DFDsPPKrfPM-A1Jl58ykuPom7OTFf4SACQSFK2P2BWbAAAAAAAAAQkAAEDAAElVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh42iaik_aXCcODapCDPlrINLF6xxKlvyp5T3F90pWxLnnQxpO3V4UbNxPjLGkjKN02Php_PMRdF0D-x3Dvskpqw0\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"193237c7e347b1d494a1bc8a273e18fcf3f277e76c06b2f6d151692995f79edf\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:07.100Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAgAAAAAAAADoq8DFDsPPKrfPM-A1Jl58ykuPom7OTFf4SACQSFK2P2BWbAAAAAAAAAQkAAEDAAElVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh42iaik_aXCcODapCDPlrINLF6xxKlvyp5T3F90pWxLnnQxpO3V4UbNxPjLGkjKN02Php_PMRdF0D-x3Dvskpqw0\"", + "emsg": "00000116656d736701000000000003e800000000000042cc00000000193237c775726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000e8abc0c50ec3cf2ab7cf33e035265e7cca4b8fa26ece4c57f84800904852b63f60566c0000000000000424000103000125547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3689a8a4fda5c270e0daa420cf96b20d2c5eb1c4a96fca9e53dc5f74a56c4b9e7431a4edd5e146cdc4f8cb1a48ca374d8f869fcf311745d03fb1dc3bec929ab0d" + }, + { + "msf": "{\"t\":1792108807100,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAgAAAAAAAABmslylbZioe40OnB9RADAuMycTH8ewiBqelYbU8XmIR2BWbAAAAAAAAAQkAAEBAAElVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh42SB0I0eljDFuEsHYKffCAGQaEfvFaDI_GB9iwaXtRTNwvNNJqiY_-wKsvdj0SERScyWtd0EJpUjaumjJO9iDg8\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"ddd7f60422f72e693fd4c8fcea8f14a3989a624580509336472918cd832f1936\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:07.100Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAgAAAAAAAABmslylbZioe40OnB9RADAuMycTH8ewiBqelYbU8XmIR2BWbAAAAAAAAAQkAAEBAAElVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh42SB0I0eljDFuEsHYKffCAGQaEfvFaDI_GB9iwaXtRTNwvNNJqiY_-wKsvdj0SERScyWtd0EJpUjaumjJO9iDg8\"", + "emsg": "00000116656d736701000000000003e800000000000042cc00000000ddd7f60475726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765020000000000000066b25ca56d98a87b8d0e9c1f5100302e3327131fc7b0881a9e9586d4f179884760566c0000000000000424000101000125547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e36481d08d1e9630c5b84b0760a7df0801906847ef15a0c8fc607d8b0697b514cdc2f34d26a898ffec0ab2f763d1211149cc96b5dd042695236ae9a324ef620e0f" + }, + { + "msf": "{\"t\":1792108830000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAABfE9Ncz72eoM7c1Oj12CyVm5JYuMP9nhy0ORthlrx1F4DDyQEAAAAAAAcpAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAgEAAAACAAAAmTzC9U5gR9gb5WKvCTgq1-_A4zvVJutMVEg-sFVdh-nWe1qaFBUuqoez98nqUKIz8jmQyOhmY-Sq2QuxA57zDQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"95260ba9a539409d6f8b7b99cd0081a1de4ee17a604e1df655f807e61b9cca64\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:30.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAABfE9Ncz72eoM7c1Oj12CyVm5JYuMP9nhy0ORthlrx1F4DDyQEAAAAAAAcpAF8T01zPvZ6gztzU6PXYLJWbkli4w_2eHLQ5G2GWvHUXAgEAAAACAAAAmTzC9U5gR9gb5WKvCTgq1-_A4zvVJutMVEg-sFVdh-nWe1qaFBUuqoez98nqUKIz8jmQyOhmY-Sq2QuxA57zDQ\"", + "emsg": "0000011d656d736701000000000003e80000000000009c400000000095260ba975726e3a7761693a6576656e743a3100706f6c6c5f636c6f7365005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e03000000000000005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc751780c3c90100000000000729005f13d35ccfbd9ea0cedcd4e8f5d82c959b9258b8c3fd9e1cb4391b6196bc7517020100000002000000993cc2f54e6047d81be562af09382ad7efc0e33bd526eb4c54483eb0555d87e9d67b5a9a14152eaa87b3f7c9ea50a233f23990c8e86663e4aad90bb1039ef30d" + }, + { + "msf": "{\"l\":[0,720],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAACVJguppTlAnW-Le5nNAIGh3k7hemBOHfZV-AfmG5zKZIDDyQEAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADQAgAAAAAAAAIKAAMHAAAAkF8BAADJqe1mofSUbluGJYDUyvKL1WmZW6O0awLXwhI1yXF6KrEzcPB57Tfz8th0bhgdhP9R5UZsbJzgKcYvkbYfXpMB\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"4143079bca3f1bfac36f55b4586017d1b173127268ccea53dc19d543479bb2a2\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:30.000Z\",DURATION=90.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAACVJguppTlAnW-Le5nNAIGh3k7hemBOHfZV-AfmG5zKZIDDyQEAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADQAgAAAAAAAAIKAAMHAAAAkF8BAADJqe1mofSUbluGJYDUyvKL1WmZW6O0awLXwhI1yXF6KrEzcPB57Tfz8th0bhgdhP9R5UZsbJzgKcYvkbYfXpMB\"", + "emsg": "00000127656d736701000000000003e80000000000009c4000015f904143079b75726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e040000000000000095260ba9a539409d6f8b7b99cd0081a1de4ee17a604e1df655f807e61b9cca6480c3c9010000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000d002000000000000020a000307000000905f010000c9a9ed66a1f4946e5b862580d4caf28bd569995ba3b46b02d7c21235c9717a2ab13370f079ed37f3f2d8746e181d84ff51e5466c6c9ce029c62f91b61f5e9301" + }, + { + "msf": "{\"t\":1792108859000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAAAZMjfH40ex1JShvIonPhj88_J352wGsvbRUWkplfee38BEhAMAAAAAAAQEAAEBAACD3FIaV0iM9Cx2A2QvUTyY6rLTf_JqIeX3inOWvS1YHUrMwgmO0YCiTMTyY4zIFWSJWnLkiCKdbyTsCypo9PIP\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"14eeaaba6836186c4df1a582dda3145161bdff96ff0704ec1801d95db96f96a6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:59.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAwAAAAAAAAAZMjfH40ex1JShvIonPhj88_J352wGsvbRUWkplfee38BEhAMAAAAAAAQEAAEBAACD3FIaV0iM9Cx2A2QvUTyY6rLTf_JqIeX3inOWvS1YHUrMwgmO0YCiTMTyY4zIFWSJWnLkiCKdbyTsCypo9PIP\"", + "emsg": "000000f6656d736701000000000003e80000000000010d880000000014eeaaba75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300000000000000193237c7e347b1d494a1bc8a273e18fcf3f277e76c06b2f6d151692995f79edfc044840300000000000404000101000083dc521a57488cf42c7603642f513c98eab2d37ff26a21e5f78a7396bd2d581d4accc2098ed180a24cc4f2638cc81564895a72e488229d6f24ec0b2a68f4f20f" + }, + { + "msf": "{\"t\":1792108861000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAABBQwebyj8b-sNvVbRYYBfRsXMScmjM6lPcGdVDR5uyokDJogMAAAAAAApEAKAPAAAC0r-C4FCsgWGXtTZZYjDKuIqGpalYQB015Y2OObLjqBICZW4aAFRoaXMgb25lIGlzIGNhbGxlZCBBbnRoZW0ubYa8NSfjvEraMcn6BUYa8dHH5rOuZV7CG1G89kIVKsm_67eZVQLxtWFih2-r9Qhsby0pXclMrrbAnJzYvSEyAw\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"b5fa0dfc43cc93a23d53546ce8fbfeb8b6f87634a4644f2e49428683a9a31de5\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:01.000Z\",DURATION=4.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAABBQwebyj8b-sNvVbRYYBfRsXMScmjM6lPcGdVDR5uyokDJogMAAAAAAApEAKAPAAAC0r-C4FCsgWGXtTZZYjDKuIqGpalYQB015Y2OObLjqBICZW4aAFRoaXMgb25lIGlzIGNhbGxlZCBBbnRoZW0ubYa8NSfjvEraMcn6BUYa8dHH5rOuZV7CG1G89kIVKsm_67eZVQLxtWFih2-r9Qhsby0pXclMrrbAnJzYvSEyAw\"", + "emsg": "00000135656d736701000000000003e8000000000001155800000fa0b5fa0dfc75726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e05000000000000004143079bca3f1bfac36f55b4586017d1b173127268ccea53dc19d543479bb2a240c9a20300000000000a4400a00f000002d2bf82e050ac816197b536596230cab88a86a5a958401d35e58d8e39b2e3a81202656e1a0054686973206f6e652069732063616c6c656420416e7468656d2e6d86bc3527e3bc4ada31c9fa05461af1d1c7e6b3ae655ec21b51bcf642152ac9bfebb7995502f1b56162876fabf5086c6f2d295dc94caeb6c09c9cd8bd213203" + }, + { + "msf": "{\"t\":1792108862000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AwAAAAAAAAAlVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh44ALsgMAAAAAAAMGAAQA8J-Oth-g4YuzrjMJnKbtM7lCEEOFu7GSCg-P_EVRwv-g7-NKa30njYamqH2i0gkN00ctXgQSmvsftZeGeil69bEG3wk\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"4896a1e1c65fecba9e8aff6ff4c9bdbcea431a6285f9f5e94c5f54b31ecc50f1\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5AwAAAAAAAAAlVHoIKwcHlo_av3gu7BIRgG8v3kZBRJV8JPef9Ibh44ALsgMAAAAAAAMGAAQA8J-Oth-g4YuzrjMJnKbtM7lCEEOFu7GSCg-P_EVRwv-g7-NKa30njYamqH2i0gkN00ctXgQSmvsftZeGeil69bEG3wk\"", + "emsg": "000000f4656d736701000000000003e80000000000011940000000004896a1e175726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f320139030000000000000025547a082b0707968fdabf782eec1211806f2fde464144957c24f79ff486e1e3800bb20300000000000306000400f09f8eb61fa0e18bb3ae33099ca6ed33b942104385bbb1920a0f8ffc4551c2ffa0efe34a6b7d278d86a6a87da2d2090dd3472d5e04129afb1fb597867a297af5b106df09" + }, + { + "msf": "{\"t\":1792108862000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAwAAAAAAAADd1_YEIvcuaT_UyPzqjxSjmJpiRYBQkzZHKRjNgy8ZNoALsgMAAAAAAAQEAAQBAAAEAAfp5MOn1iRvy7wITvJ-wKFgqjKjFzdOwqxTKi0yijvNzWR9fcVzve3arCKay28DT5GfI3d64uW0ktUET2sP\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"5a6b11fe73bf0d2850503022f52125ec1942675ded3ab8eee9170faaa43a2397\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:02.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMbZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlAwAAAAAAAADd1_YEIvcuaT_UyPzqjxSjmJpiRYBQkzZHKRjNgy8ZNoALsgMAAAAAAAQEAAQBAAAEAAfp5MOn1iRvy7wITvJ-wKFgqjKjFzdOwqxTKi0yijvNzWR9fcVzve3arCKay28DT5GfI3d64uW0ktUET2sP\"", + "emsg": "000000f6656d736701000000000003e80000000000011940000000005a6b11fe75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d77650300000000000000ddd7f60422f72e693fd4c8fcea8f14a3989a624580509336472918cd832f1936800bb203000000000004040004010000040007e9e4c3a7d6246fcbbc084ef27ec0a160aa32a317374ec2ac532a2d328a3bcdcd647d7dc573bdeddaac229acb6f034f919f23777ae2e5b492d5044f6b0f" + }, + { + "msf": "{\"t\":1792108863000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAAAAAAAAAAU7qq6aDYYbE3xpYLdoxRRYb3_lv8HBOwYAdlduW-WpsBNwQMAAAAAAAQEAAQBAAD7sJKbQ8NN2oMrBNxCrRmrkb0TQt8mCfh_p0UKJQ9jQJr767wbPOh4WB1iIPKX-FEtrlUtCKcp0hVwoo6b3fkH\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"4c97d83020b9a16f60e2b32e4741bab04e4c976dd23f92915f53f5b47e0ae1ae\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:03.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBAAAAAAAAAAU7qq6aDYYbE3xpYLdoxRRYb3_lv8HBOwYAdlduW-WpsBNwQMAAAAAAAQEAAQBAAD7sJKbQ8NN2oMrBNxCrRmrkb0TQt8mCfh_p0UKJQ9jQJr767wbPOh4WB1iIPKX-FEtrlUtCKcp0hVwoo6b3fkH\"", + "emsg": "000000f6656d736701000000000003e80000000000011d28000000004c97d83075726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93040000000000000014eeaaba6836186c4df1a582dda3145161bdff96ff0704ec1801d95db96f96a6c04dc103000000000004040004010000fbb0929b43c34dda832b04dc42ad19ab91bd1342df2609f87fa7450a250f63409afbebbc1b3ce878581d6220f297f8512dae552d08a729d21570a28e9bddf907" + }, + { + "msf": "{\"l\":[1,96],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BgAAAAAAAAC1-g38Q8yToj1TVGzo-_64tvh2NKRkTy5JQoaDqaMd5QCQ0AMAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AQAAAAAAAABgAAAAAAAAAAgOAAIAAAABBgBjaG9ydXMATNnJoaE03Frjr3gfvBMWJyNT7ZJIDCva8dEjin5lF12uDQQ8BjWXSxhxcuOY4Dd_zKSs834oIT1FwvOrley2Bg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"280ad051383cd7d9e164ef14e2b7f0c164d7c49ac4313f900f2b4efc6851dce6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:04.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BgAAAAAAAAC1-g38Q8yToj1TVGzo-_64tvh2NKRkTy5JQoaDqaMd5QCQ0AMAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AQAAAAAAAABgAAAAAAAAAAgOAAIAAAABBgBjaG9ydXMATNnJoaE03Frjr3gfvBMWJyNT7ZJIDCva8dEjin5lF12uDQQ8BjWXSxhxcuOY4Dd_zKSs834oIT1FwvOrley2Bg\"", + "emsg": "0000012e656d736701000000000003e8000000000001211000000000280ad05175726e3a7761693a6576656e743a31006d61726b6572005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0600000000000000b5fa0dfc43cc93a23d53546ce8fbfeb8b6f87634a4644f2e49428683a9a31de50090d0030000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb601000000000000006000000000000000080e000200000001060063686f727573004cd9c9a1a134dc5ae3af781fbc1316272353ed92480c2bdaf1d1238a7e65175dae0d043c0635974b187172e398e0377fcca4acf37e28213d45c2f3ab95ecb606" + }, + { + "msf": "{\"t\":1792108890000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BAAAAAAAAAAI-LcawY2OeCC2vnW3PDYj4jelsqv_rlni2Lat2QoWtoBKXQUAAAAAABEgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlrGZ_hkMDJy2_0sjlkyX995CWx8WCP5k_GdEC6FN1UNuviz8rKVTjPuLuU5sZnMZc2UyLhQ8pRb59IFOT5YWwAQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"2affe8118ac27644f0ca3e8b5049a974e753da2323b9f1b93ee075da8c0bc608\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:30.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BAAAAAAAAAAI-LcawY2OeCC2vnW3PDYj4jelsqv_rlni2Lat2QoWtoBKXQUAAAAAABEgALZuxFF-bdrpgao_R1Qi_LMGnZahP479yzzha9hhDXdlrGZ_hkMDJy2_0sjlkyX995CWx8WCP5k_GdEC6FN1UNuviz8rKVTjPuLuU5sZnMZc2UyLhQ8pRb59IFOT5YWwAQ\"", + "emsg": "0000010f656d736701000000000003e800000000000186a0000000002affe81175726e3a7761693a6576656e743a31006c65617665005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b040000000000000008f8b71ac18d8e7820b6be75b73c3623e237a5b2abffae59e2d8b6add90a16b6804a5d050000000000112000b66ec4517e6ddae981aa3f475422fcb3069d96a13f8efdcb3ce16bd8610d7765ac667f864303272dbfd2c8e59325fdf79096c7c5823f993f19d102e8537550dbaf8b3f2b2954e33ee2ee539b199cc65cd94c8b850f2945be7d205393e585b001" + }, + { + "msf": "{\"t\":1792108919999,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BwAAAAAAAAAoCtBRODzX2eFk7xTit_DBZNfEmsQxP5APK078aFHc5v8NJwcAAAAAAAMLAAkAbGFzdCBzb25ndbfIv4-mTrhCEUqO3Cn1GwhLp7SLwaCkgmUCh6ZZLsH7b9fkHVY1hIYe2K621y01N7fqI9MaihQP9Gi4Szg4CQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"16f55f87e1786b727bbfb7e17d1ffa6642eafd9c8eb9e30fc4fba1864f534160\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:59.999Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BwAAAAAAAAAoCtBRODzX2eFk7xTit_DBZNfEmsQxP5APK078aFHc5v8NJwcAAAAAAAMLAAkAbGFzdCBzb25ndbfIv4-mTrhCEUqO3Cn1GwhLp7SLwaCkgmUCh6ZZLsH7b9fkHVY1hIYe2K621y01N7fqI9MaihQP9Gi4Szg4CQ\"", + "emsg": "000000f9656d736701000000000003e8000000000001fbcf0000000016f55f8775726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0700000000000000280ad051383cd7d9e164ef14e2b7f0c164d7c49ac4313f900f2b4efc6851dce6ff0d27070000000000030b0009006c61737420736f6e6775b7c8bf8fa64eb842114a8edc29f51b084ba7b48bc1a0a482650287a6592ec1fb6fd7e41d563584861ed8aeb6d72d3537b7ea23d31a8a140ff468b84b383809" + }, + { + "msf": "{\"t\":1792108920000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-CAAAAAAAAAAW9V-H4Xhrcnu_t-F9H_pmQur9nI654w_E-6GGT1NBYAAOJwcAAAAAAAoUANAHAAABAmVuCgBUaGFuayB5b3UhhZv8S-wsZFIVk1uz78Y-T76WL-1TwQ4BYt3IVlyyHdldoJtqO8R9Pc8ccb4Omfi_GDGizSiCa4UkY5h-PQojAQ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"5e265657abcfb840ca5a78862c82cf04d2220fd53f62fdf4622c661f437053ca\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:02:00.000Z\",DURATION=2.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-CAAAAAAAAAAW9V-H4Xhrcnu_t-F9H_pmQur9nI654w_E-6GGT1NBYAAOJwcAAAAAAAoUANAHAAABAmVuCgBUaGFuayB5b3UhhZv8S-wsZFIVk1uz78Y-T76WL-1TwQ4BYt3IVlyyHdldoJtqO8R9Pc8ccb4Omfi_GDGizSiCa4UkY5h-PQojAQ\"", + "emsg": "00000105656d736701000000000003e8000000000001fbd0000007d05e26565775726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e080000000000000016f55f87e1786b727bbfb7e17d1ffa6642eafd9c8eb9e30fc4fba1864f534160000e270700000000000a1400d00700000102656e0a005468616e6b20796f7521859bfc4bec2c645215935bb3efc63e4fbe962fed53c10e0162ddc8565cb21dd95da09b6a3bc47d3dcf1c71be0e99f8bf1831a2cd28826b852463987e3d0a2301" + }, + { + "msf": "{\"t\":1792108921000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQAAAAAAAABMl9gwILmhb2Disy5HQbqwTkyXbdI_kpFfU_W0fgrhrkBQNgcAAAAAAAMHAAUAYnJhdm8KUfdepu6N8ieG7J3OW0QpqkLEYEF_LPz_7WS0xf0PmZ0JuCHHUc4_2HycCf5-csT8PUeY7IvPqBboJA0YBdoO\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"6d054dcd9f995d40766a3ee4e08a5c9082d537da1324ca9ac5e90ae4ac8919b9\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:02:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TBQAAAAAAAABMl9gwILmhb2Disy5HQbqwTkyXbdI_kpFfU_W0fgrhrkBQNgcAAAAAAAMHAAUAYnJhdm8KUfdepu6N8ieG7J3OW0QpqkLEYEF_LPz_7WS0xf0PmZ0JuCHHUc4_2HycCf5-csT8PUeY7IvPqBboJA0YBdoO\"", + "emsg": "000000f5656d736701000000000003e8000000000001ffb8000000006d054dcd75726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9305000000000000004c97d83020b9a16f60e2b32e4741bab04e4c976dd23f92915f53f5b47e0ae1ae4050360700000000000307000500627261766f0a51f75ea6ee8df22786ec9dce5b4429aa42c460417f2cfcffed64b4c5fd0f999d09b821c751ce3fd87c9c09fe7e72c4fc3d4798ec8bcfa816e8240d1805da0e" + }, + { + "msf": "{\"t\":1792108921000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5BAAAAAAAAABIlqHhxl_sup6K_2_0yb286kMaYoX59elMX1SzHsxQ8UBQNgcAAAAAAAQEAAEDAAA63xbtWVNbERz9EV3XmYMAikp35uURyi6AE_htIbxVIvcL8AcSpsXEBbPMG7EDIPX6l97pyGT9jH0U2i9TX04I\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"5a9df56a498d6151c4363d3a4614e613e10a73d71ee13aa98377276d216f0325\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:02:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMQcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5BAAAAAAAAABIlqHhxl_sup6K_2_0yb286kMaYoX59elMX1SzHsxQ8UBQNgcAAAAAAAQEAAEDAAA63xbtWVNbERz9EV3XmYMAikp35uURyi6AE_htIbxVIvcL8AcSpsXEBbPMG7EDIPX6l97pyGT9jH0U2i9TX04I\"", + "emsg": "000000f6656d736701000000000003e8000000000001ffb8000000005a9df56a75726e3a7761693a6576656e743a31007265616374696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3107122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013904000000000000004896a1e1c65fecba9e8aff6ff4c9bdbcea431a6285f9f5e94c5f54b31ecc50f1405036070000000000040400010300003adf16ed59535b111cfd115dd79983008a4a77e6e511ca2e8013f86d21bc5522f70bf00712a6c5c405b3cc1bb10320f5fa97dee9c864fd8c7d14da2f535f4e08" + }, + { + "msf": "{\"t\":1792108925000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BQAAAAAAAAAq_-gRisJ2RPDKPotQSal051PaIyO58bk-4HXajAvGCEBZcwcAAAAAABEgAAcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5gKwRfMoivrnmVHbTcLe_v4tlfZ4paTsIIhHT8W7-qZVby_CUFH3YAeTTWYMDDKbc_od0n4d3bjoKdqKo7hzXCg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"443a6168949972c9d61494bda354c351b78811f0af8a3fe06eaf76b028936c1f\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:02:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWrG-FthLvmD2-5KzH6PH28SDaxNOT9e85wy7o6SJ7U7BQAAAAAAAAAq_-gRisJ2RPDKPotQSal051PaIyO58bk-4HXajAvGCEBZcwcAAAAAABEgAAcSL5Wo4nwzRtLddHuTjgHKm92hBB3cg7QUWIpPMgE5gKwRfMoivrnmVHbTcLe_v4tlfZ4paTsIIhHT8W7-qZVby_CUFH3YAeTTWYMDDKbc_od0n4d3bjoKdqKo7hzXCg\"", + "emsg": "0000010f656d736701000000000003e80000000000020f5800000000443a616875726e3a7761693a6576656e743a31006c65617665005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b05000000000000002affe8118ac27644f0ca3e8b5049a974e753da2323b9f1b93ee075da8c0bc60840597307000000000011200007122f95a8e27c3346d2dd747b938e01ca9bdda1041ddc83b414588a4f32013980ac117cca22beb9e65476d370b7bfbf8b657d9e29693b082211d3f16efea9955bcbf094147dd801e4d35983030ca6dcfe87749f87776e3a0a76a2a8ee1cd70a" + } + ] + }, + { + "name": "join_set_repeats", + "about": "a host's track over three one-minute groups (§8.1) as a continuous subscriber receives it: the first object of groups 1 and 2 repeats the join set (§8.2: the open poll and the caption still showing), which the subscriber already holds and ignores as duplicates (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c000000000000030c000a00646f6f7273206f70656ed62e3d1a5b1db825f610304e78663894825ea0811d744d8683a64e19642001895452d63288edb1f2d350c4a087edb7aea8775f3bae2560d121a329e3389dfd05", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae380f0fa0200000000000a1f00983a00000102656e15005468616e6b20796f7520666f7220636f6d696e672e7442b2b6d8eaecdd3d7f140f09f3e19299695f82aad70fd3489b9bede13688cc9cea4151a92a8fa45c6d70d3c07ec05a29a72826dc5be4630e27ae8ef0325d09", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e030000000000000029a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8c03b47030000000000030a0008006f6e65206d6f7265161c29dcd9ac55c074d5876db21d492598eeb45a9f906e2e47cc02f2a44f19cb6e8ebe8eeac1f9a4e2444ea7af9e81259b9dd5402f1127b2c99522c63acdbc09", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae380f0fa0200000000000a1f00983a00000102656e15005468616e6b20796f7520666f7220636f6d696e672e7442b2b6d8eaecdd3d7f140f09f3e19299695f82aad70fd3489b9bede13688cc9cea4151a92a8fa45c6d70d3c07ec05a29a72826dc5be4630e27ae8ef0325d09", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e04000000000000002c82f31270471d24ec0d28967cd9b34d6481d9d5737b43b84f1dfba06d7abb6e40c9a20300000000000107007363656e653d322f9ac0660939754ed489306f4af1ead980746a920cc17d831ea18e31415b97806f2e59927abc4377f4047d5a38b9e41dd9d115f9e90244865953a907c00d9503", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e05000000000000008f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770801d2c0400000000000a1200e80300000102656e08004e6578742075702e44deba642f1dc28b2f08edfc08464bf4ed403f76c8418bc42f4aa45e5ebf765e4e9c0e54a930bd12e20e9192b59f9ba80bc7de4b75631f3c767d70ef1f0bf108", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e060000000000000058e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e405036070000000000072900acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3020000000000000000376a8ba5d1c3dab98b3bb78a190a6eb2bee18ef56615bdda15949a8bf3c242cb1d28c38db9f1241774c45bb75e0cbee76ee673e6b7b4efd06f3ce93141ae5d0a" + ], + "outcome": "accept", + "digests": [ + "31a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f5", + "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "29a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8", + "2c82f31270471d24ec0d28967cd9b34d6481d9d5737b43b84f1dfba06d7abb6e", + "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "29a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8", + "8f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770", + "58e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e", + "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "bd116bbae8a975f24801cfa3c62bc9eeb4801c82b0b7ec133229352044726b82" + ], + "tally": { + "state_hash": "df35448c35bc2a9bf00fbdd00103cfd0274efaab27ecaf67b724ba7638278232", + "polls": [ + { + "poll": "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "open": false, + "counts": [ + 0, + 0 + ] + } + ] + }, + "bindings": [ + { + "msf": "{\"t\":1792108805000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBLTAAAAAAAAAMMAAoAZG9vcnMgb3BlbtYuPRpbHbgl9hAwTnhmOJSCXqCBHXRNhoOmThlkIAGJVFLWMojtsfLTUMSgh-23rqh3XzuuJWDRIaMp4zid_QU\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"31a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f5\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:05.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBLTAAAAAAAAAMMAAoAZG9vcnMgb3BlbtYuPRpbHbgl9hAwTnhmOJSCXqCBHXRNhoOmThlkIAGJVFLWMojtsfLTUMSgh-23rqh3XzuuJWDRIaMp4zid_QU\"", + "emsg": "000000fa656d736701000000000003e80000000000003a980000000031a9d9fe75726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c000000000000030c000a00646f6f7273206f70656ed62e3d1a5b1db825f610304e78663894825ea0811d744d8683a64e19642001895452d63288edb1f2d350c4a087edb7aea8775f3bae2560d121a329e3389dfd05" + }, + { + "msf": "{\"t\":1792108810000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"", + "emsg": "00000113656d736701000000000003e80000000000004e2000000000acecf75575726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204" + }, + { + "msf": "{\"t\":1792108850000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACs7PdVKSJ6596EeMGH8fwaKBMmnRwkyyw4-IxRQ6GK44Dw-gIAAAAAAAofAJg6AAABAmVuFQBUaGFuayB5b3UgZm9yIGNvbWluZy50QrK22Ors3T1_FA8J8-GSmWlfgqrXD9NIm5vt4TaIzJzqQVGpKo-kXG1w08B-wFoppygm3FvkYw4nro7wMl0J\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"29a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:50.000Z\",DURATION=15.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACs7PdVKSJ6596EeMGH8fwaKBMmnRwkyyw4-IxRQ6GK44Dw-gIAAAAAAAofAJg6AAABAmVuFQBUaGFuayB5b3UgZm9yIGNvbWluZy50QrK22Ors3T1_FA8J8-GSmWlfgqrXD9NIm5vt4TaIzJzqQVGpKo-kXG1w08B-wFoppygm3FvkYw4nro7wMl0J\"", + "emsg": "00000110656d736701000000000003e8000000000000ea6000003a9829a5a9f375726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae380f0fa0200000000000a1f00983a00000102656e15005468616e6b20796f7520666f7220636f6d696e672e7442b2b6d8eaecdd3d7f140f09f3e19299695f82aad70fd3489b9bede13688cc9cea4151a92a8fa45c6d70d3c07ec05a29a72826dc5be4630e27ae8ef0325d09" + }, + { + "msf": "{\"t\":1792108855000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAAAppanzRP1yqopDLZnGyNAGwXZX_xwxQwYF4HdyxTbZ2MA7RwMAAAAAAAMKAAgAb25lIG1vcmUWHCnc2axVwHTVh22yHUklmO60Wp-Qbi5HzALypE8Zy26Ovo7qwfmk4kROp6-egSWbndVALxEnssmVIsY6zbwJ\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"2c82f31270471d24ec0d28967cd9b34d6481d9d5737b43b84f1dfba06d7abb6e\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:55.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AwAAAAAAAAAppanzRP1yqopDLZnGyNAGwXZX_xwxQwYF4HdyxTbZ2MA7RwMAAAAAAAMKAAgAb25lIG1vcmUWHCnc2axVwHTVh22yHUklmO60Wp-Qbi5HzALypE8Zy26Ovo7qwfmk4kROp6-egSWbndVALxEnssmVIsY6zbwJ\"", + "emsg": "000000f8656d736701000000000003e8000000000000fde8000000002c82f31275726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e030000000000000029a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8c03b47030000000000030a0008006f6e65206d6f7265161c29dcd9ac55c074d5876db21d492598eeb45a9f906e2e47cc02f2a44f19cb6e8ebe8eeac1f9a4e2444ea7af9e81259b9dd5402f1127b2c99522c63acdbc09" + }, + { + "msf": "{\"t\":1792108810000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"", + "emsg": "00000113656d736701000000000003e80000000000004e2000000000acecf75575726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204" + }, + { + "msf": "{\"t\":1792108850000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACs7PdVKSJ6596EeMGH8fwaKBMmnRwkyyw4-IxRQ6GK44Dw-gIAAAAAAAofAJg6AAABAmVuFQBUaGFuayB5b3UgZm9yIGNvbWluZy50QrK22Ors3T1_FA8J8-GSmWlfgqrXD9NIm5vt4TaIzJzqQVGpKo-kXG1w08B-wFoppygm3FvkYw4nro7wMl0J\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"29a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:50.000Z\",DURATION=15.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AgAAAAAAAACs7PdVKSJ6596EeMGH8fwaKBMmnRwkyyw4-IxRQ6GK44Dw-gIAAAAAAAofAJg6AAABAmVuFQBUaGFuayB5b3UgZm9yIGNvbWluZy50QrK22Ors3T1_FA8J8-GSmWlfgqrXD9NIm5vt4TaIzJzqQVGpKo-kXG1w08B-wFoppygm3FvkYw4nro7wMl0J\"", + "emsg": "00000110656d736701000000000003e8000000000000ea6000003a9829a5a9f375726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae380f0fa0200000000000a1f00983a00000102656e15005468616e6b20796f7520666f7220636f6d696e672e7442b2b6d8eaecdd3d7f140f09f3e19299695f82aad70fd3489b9bede13688cc9cea4151a92a8fa45c6d70d3c07ec05a29a72826dc5be4630e27ae8ef0325d09" + }, + { + "msf": "{\"t\":1792108861000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAAAsgvMScEcdJOwNKJZ82bNNZIHZ1XN7Q7hPHfugbXq7bkDJogMAAAAAAAEHAHNjZW5lPTIvmsBmCTl1TtSJMG9K8erZgHRqkgzBfYMeoY4xQVuXgG8uWZJ6vEN39AR9Wji55B3Z0RX56QJEhllTqQfADZUD\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"8f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BAAAAAAAAAAsgvMScEcdJOwNKJZ82bNNZIHZ1XN7Q7hPHfugbXq7bkDJogMAAAAAAAEHAHNjZW5lPTIvmsBmCTl1TtSJMG9K8erZgHRqkgzBfYMeoY4xQVuXgG8uWZJ6vEN39AR9Wji55B3Z0RX56QJEhllTqQfADZUD\"", + "emsg": "000000f5656d736701000000000003e80000000000011558000000008f4b4c4375726e3a7761693a6576656e743a31006d657461005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e04000000000000002c82f31270471d24ec0d28967cd9b34d6481d9d5737b43b84f1dfba06d7abb6e40c9a20300000000000107007363656e653d322f9ac0660939754ed489306f4af1ead980746a920cc17d831ea18e31415b97806f2e59927abc4377f4047d5a38b9e41dd9d115f9e90244865953a907c00d9503" + }, + { + "msf": "{\"t\":1792108870000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAACPS0xDPXxiRXcouva_rR60SzlPa-p_dqT1zGysq0bHcIAdLAQAAAAAAAoSAOgDAAABAmVuCABOZXh0IHVwLkTeumQvHcKLLwjt_AhGS_TtQD92yEGLxC9KpF5ev3ZeTpwOVKkwvRLiDpGStZ-bqAvH3kt1Yx88dn1w7x8L8Qg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"58e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:01:10.000Z\",DURATION=1.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BQAAAAAAAACPS0xDPXxiRXcouva_rR60SzlPa-p_dqT1zGysq0bHcIAdLAQAAAAAAAoSAOgDAAABAmVuCABOZXh0IHVwLkTeumQvHcKLLwjt_AhGS_TtQD92yEGLxC9KpF5ev3ZeTpwOVKkwvRLiDpGStZ-bqAvH3kt1Yx88dn1w7x8L8Qg\"", + "emsg": "00000103656d736701000000000003e80000000000013880000003e858e5711f75726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e05000000000000008f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770801d2c0400000000000a1200e80300000102656e08004e6578742075702e44deba642f1dc28b2f08edfc08464bf4ed403f76c8418bc42f4aa45e5ebf765e4e9c0e54a930bd12e20e9192b59f9ba80bc7de4b75631f3c767d70ef1f0bf108" + }, + { + "msf": "{\"t\":1792108810000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAAAxqdn-dTFHDyIobz3jmdTkAI6NfeCPUcGbXkqHZ8Ao9YCWmAAAAAAAAAUgAA4ARmF2b3VyaXRlIHNldD8CBQBGaXJzdAYAU2Vjb25kZplyz6A-AvN9js1vo8rqAx53Q3u4UGMxAJyNZS_JFQ4udAWgldMRIHOOlDWjh2NwrTmLVvyIcroHIZ3pI9oyBA\"", + "emsg": "00000113656d736701000000000003e80000000000004e2000000000acecf75575726e3a7761693a6576656e743a3100706f6c6c5f6f70656e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204" + }, + { + "msf": "{\"t\":1792108921000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BgAAAAAAAABY5XEfLkOylZY1Evk6uz9PO0tFe08ojL1djEJeC-qnjkBQNgcAAAAAAAcpAKzs91UpInrn3oR4wYfx_BooEyadHCTLLDj4jFFDoYrjAgAAAAAAAAAAN2qLpdHD2rmLO7eKGQpusr7hjvVmFb3aFZSai_PCQssdKMONufEkF3TEW7deDL7nbuZz5re079BvPOkxQa5dCg\"}}", + "daterange": "#EXT-X-DATERANGE:ID=\"bd116bbae8a975f24801cfa3c62bc9eeb4801c82b0b7ec133229352044726b82\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:02:01.000Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-BgAAAAAAAABY5XEfLkOylZY1Evk6uz9PO0tFe08ojL1djEJeC-qnjkBQNgcAAAAAAAcpAKzs91UpInrn3oR4wYfx_BooEyadHCTLLDj4jFFDoYrjAgAAAAAAAAAAN2qLpdHD2rmLO7eKGQpusr7hjvVmFb3aFZSai_PCQssdKMONufEkF3TEW7deDL7nbuZz5re079BvPOkxQa5dCg\"", + "emsg": "0000011d656d736701000000000003e8000000000001ffb800000000bd116bba75726e3a7761693a6576656e743a3100706f6c6c5f636c6f7365005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e060000000000000058e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e405036070000000000072900acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3020000000000000000376a8ba5d1c3dab98b3bb78a190a6eb2bee18ef56615bdda15949a8bf3c242cb1d28c38db9f1241774c45bb75e0cbee76ee673e6b7b4efd06f3ce93141ae5d0a" + } + ] + }, + { + "name": "joiner_mid_stream", + "about": "the same track as a subscriber joining at group 1 receives it: the join set, then the group's events; it reports what it does not hold, seq 0 before its first record and seq 3 between the join set and the group's events, as gaps (§6.2), not as corruption", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0200000000000000acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae380f0fa0200000000000a1f00983a00000102656e15005468616e6b20796f7520666f7220636f6d696e672e7442b2b6d8eaecdd3d7f140f09f3e19299695f82aad70fd3489b9bede13688cc9cea4151a92a8fa45c6d70d3c07ec05a29a72826dc5be4630e27ae8ef0325d09", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e04000000000000002c82f31270471d24ec0d28967cd9b34d6481d9d5737b43b84f1dfba06d7abb6e40c9a20300000000000107007363656e653d322f9ac0660939754ed489306f4af1ead980746a920cc17d831ea18e31415b97806f2e59927abc4377f4047d5a38b9e41dd9d115f9e90244865953a907c00d9503", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e05000000000000008f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770801d2c0400000000000a1200e80300000102656e08004e6578742075702e44deba642f1dc28b2f08edfc08464bf4ed403f76c8418bc42f4aa45e5ebf765e4e9c0e54a930bd12e20e9192b59f9ba80bc7de4b75631f3c767d70ef1f0bf108", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000031a9d9fe7531470f22286f3de399d4e4008e8d7de08f51c19b5e4a8767c028f58096980000000000000520000e004661766f7572697465207365743f020500466972737406005365636f6e64669972cfa03e02f37d8ecd6fa3caea031e77437bb8506331009c8d652fc9150e2e7405a095d31120738e9435a3876370ad398b56fc8872ba07219de923da3204", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e060000000000000058e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e405036070000000000072900acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3020000000000000000376a8ba5d1c3dab98b3bb78a190a6eb2bee18ef56615bdda15949a8bf3c242cb1d28c38db9f1241774c45bb75e0cbee76ee673e6b7b4efd06f3ce93141ae5d0a" + ], + "outcome": "gap", + "reason": "delivery_gap", + "gaps": [ + { + "principal": "6ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e", + "first": 0, + "last": 0 + }, + { + "principal": "6ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e", + "first": 3, + "last": 3 + } + ], + "digests": [ + "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "29a5a9f344fd72aa8a432d99c6c8d006c17657ff1c31430605e07772c536d9d8", + "8f4b4c433d7c62457728baf6bfad1eb44b394f6bea7f76a4f5cc6cacab46c770", + "58e5711f2e43b295963512f93abb3f4f3b4b457b4f288cbd5d8c425e0beaa78e", + "acecf75529227ae7de8478c187f1fc1a2813269d1c24cb2c38f88c5143a18ae3", + "bd116bbae8a975f24801cfa3c62bc9eeb4801c82b0b7ec133229352044726b82" + ] + }, + { + "name": "chain_gap", + "about": "a chain whose seq 2 was not delivered: seq 3 follows seq 1, a delivery gap (§6.2) the receiver reports, not a refusal", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003050003006f6e6520da10bc54dffdc931ba9a3c88a443a041bb9fa617e312fd5aa79ba4c0c80a7ffa697c3519c6f149c6c62bb0da12b756cdcb1749bbdaea29975581b66f940207", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000dbd585c0e0e2a9ad10672aa3d472c3dca4d34e743458a59c0569471e1b0936e180841e000000000000030500030074776fbebbddb6366311a98ad4ac7ec6fa29c8f4b336b93c8fc7c6580c5f062f3c79c601ade23a47110a0637ec51c8be4087432857fcb67c7bd71839257b814cc2ed0a", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930300000000000000da3e045f2d59322fb225ffa5939840a4f5159867205e13809f615ba23880cd9600093d0000000000000306000400666f75729a7ee89a8c774fc3892986078a792d0ca7e4046f3b9f50a21e16549b3444944e16cc9d1fe7a38c2fd90bcf7b5312645bbd9847b2df8fd91105ab554305ba950f" + ], + "outcome": "gap", + "reason": "delivery_gap", + "gaps": [ + { + "principal": "c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93", + "first": 2, + "last": 2 + } + ], + "digests": [ + "dbd585c0e0e2a9ad10672aa3d472c3dca4d34e743458a59c0569471e1b0936e1", + "e016eb16fcb9a218bdad51d642d4c34b1e7f020f19fdbd5f2526e75f9defc72a", + "071e35d6ad338f97fc6dc884bab9633c9319d716889c7d407c74eac5be11f634" + ] + }, + { + "name": "bad_signature", + "about": "one bit of the second event's signature flipped (§3.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003040002006f6bbae354dbf40abf8ea0433597037caf0aea039354fcb96b8786ca20efc17ea12a6acbe848c2e94ace5d8d6bc03c87836b88912b6d535bbb8a3ad48100629e4300", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93010000000000000044547d599077c3d45d34fa843cbe360e8a29b9271caa102177189e228e1d11d380841e000000000000031400120074616d706572656420696e20666c696768749865715dd099fb44accc404620799f2b369c438a8beb42aa322ebefc31d7afeb12ee0ab89bc524428cfac3ed02370542783457283b58c3bf8a4a04787295d90a" + ], + "outcome": "refuse", + "reason": "bad_signature", + "index": 1 + }, + { + "name": "forgery_key_identity", + "about": "the identity point as the principal, with (R, S) = (B, 1): a lenient verifier accepts it over any message; the key is of small order (SPEC §7 *Signatures* step 2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000308000600666f7267656458666666666666666666666666666666666666666666666666666666666666660100000000000000000000000000000000000000000000000000000000000000" + ], + "outcome": "refuse", + "reason": "bad_key", + "index": 0 + }, + { + "name": "forgery_key_identity_y_not_reduced", + "about": "the identity spelled with y = p + 1, with (R, S) = (B, 1): not the canonical encoding of its point (SPEC §7 *Signatures* step 1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000308000600666f7267656458666666666666666666666666666666666666666666666666666666666666660100000000000000000000000000000000000000000000000000000000000000" + ], + "outcome": "refuse", + "reason": "bad_key", + "index": 0 + }, + { + "name": "forgery_r_small_order", + "about": "the base point as the principal, R the identity and S = k: the equation holds and R is of small order (SPEC §7 *Signatures* step 4)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce3158666666666666666666666666666666666666666666666666666666666666660000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000308000600666f7267656401000000000000000000000000000000000000000000000000000000000000008da4e97e0d18f302d2e971e9fdd6c06886c688784e18d3bff95611b99091af0f" + ], + "outcome": "refuse", + "reason": "bad_signature", + "index": 0 + }, + { + "name": "chain_broken", + "about": "seq 1 follows seq 0, but its prev is not seq 0's digest (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003050003006f6e6520da10bc54dffdc931ba9a3c88a443a041bb9fa617e312fd5aa79ba4c0c80a7ffa697c3519c6f149c6c62bb0da12b756cdcb1749bbdaea29975581b66f940207", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000abababababababababababababababababababababababababababababababab80841e000000000000030500030074776f742a2fe60406cd726701e5526f8bb9b94d2b28e67f1dcf2bc352d92e953593bb5f5c126528bb8071224abba65b32a4a1d92eeaca35b3b4092f708ff8c1d09a06" + ], + "outcome": "refuse", + "reason": "chain_broken", + "index": 1 + }, + { + "name": "chain_broken_genesis", + "about": "seq 0 with a prev that is not 32 zero bytes (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000010101010101010101010101010101010101010101010101010101010101010140420f00000000000003070005006669727374579937ee01a4b93cf953129960b7ebc8f3e6154359e92644db81221acc50596eb9dd3e619385ca21a9bcc385c2e457a6c1e131158b9ef1082bea56fc588b490e" + ], + "outcome": "refuse", + "reason": "chain_broken", + "index": 0 + }, + { + "name": "reorder", + "about": "seq 0, seq 2, then seq 1: in stream order seq 1 arrives behind the head and is not held (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003050003006f6e6520da10bc54dffdc931ba9a3c88a443a041bb9fa617e312fd5aa79ba4c0c80a7ffa697c3519c6f149c6c62bb0da12b756cdcb1749bbdaea29975581b66f940207", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000e016eb16fcb9a218bdad51d642d4c34b1e7f020f19fdbd5f2526e75f9defc72ac0c62d00000000000003070005007468726565cf3082ef1c9061c40e3b41981576530dc77dbb185d90b7d8ac6a8f0dc838cc47d80b46fdc896bcdd75f58a472181d26935874109bc90f09e335378e4012bf401", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000dbd585c0e0e2a9ad10672aa3d472c3dca4d34e743458a59c0569471e1b0936e180841e000000000000030500030074776fbebbddb6366311a98ad4ac7ec6fa29c8f4b336b93c8fc7c6580c5f062f3c79c601ade23a47110a0637ec51c8be4087432857fcb67c7bd71839257b814cc2ed0a" + ], + "outcome": "refuse", + "reason": "seq_not_increasing", + "index": 2 + }, + { + "name": "seq_replay", + "about": "a second, different event with seq 1, after seq 1 is held (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003050003006f6e6520da10bc54dffdc931ba9a3c88a443a041bb9fa617e312fd5aa79ba4c0c80a7ffa697c3519c6f149c6c62bb0da12b756cdcb1749bbdaea29975581b66f940207", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000dbd585c0e0e2a9ad10672aa3d472c3dca4d34e743458a59c0569471e1b0936e180841e000000000000030500030074776fbebbddb6366311a98ad4ac7ec6fa29c8f4b336b93c8fc7c6580c5f062f3c79c601ade23a47110a0637ec51c8be4087432857fcb67c7bd71839257b814cc2ed0a", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000dbd585c0e0e2a9ad10672aa3d472c3dca4d34e743458a59c0569471e1b0936e180841e000000000000031700150074776f2c207361696420646966666572656e746c794d6ea49326d7278112473527794cdfa44b6acdf25cd1abad59992a3b0da7833ec89526d0824c2753bbf1dc9485a98994aea54713756bd35e8f295ba37ddd9d01" + ], + "outcome": "refuse", + "reason": "seq_replay", + "index": 2 + }, + { + "name": "time_reversed", + "about": "seq 1's t is one microsecond before seq 0's (§6.2)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9300000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c00000000000003070005006c61746572378d45fff6d415c7017e045291097021a213f231e9c2445f91dfa4e6edc7cac294ebe85795eae530eede37d09c23ea9679d4a0bdde97615798c3d26b0ae10e0b", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930100000000000000ca259616909967339a22a343a5cbe6c1a3f7f17176710282b88667ed71cb614f3f4b4c00000000000003090007006561726c696572604f9ffd4f54d54f2260af6b3a3e86d40d3e75af717b86d4646d715d99d9ad49447507bef76d7b1c44cede897072648b0ad8dbbaf61064f825773d6fca5a5108" + ], + "outcome": "refuse", + "reason": "time_reversed", + "index": 1 + }, + { + "name": "payload_too_large", + "about": "a meta payload of 1025 bytes under the default bound of 1024 (§5, §6.1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000101045a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a181d7c45bdcb54b934753a4b82bb3759418a99f4fb3c60d35ec7cbb6b3429d8cdcd36cd10f6a592c32b760fb733737066d04186247abd6710108f5df3ad4640c" + ], + "outcome": "refuse", + "reason": "payload_too_large", + "index": 0 + }, + { + "name": "kind_not_permitted", + "about": "a cue from a principal whose policy permits chat, reaction and vote only (§5, §6.1)", + "room": "main", + "default_policy": "default", + "policies": { + "c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93": "chat_only" + }, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003040002006f6bbae354dbf40abf8ea0433597037caf0aea039354fcb96b8786ca20efc17ea12a6acbe848c2e94ace5d8d6bc03c87836b88912b6d535bbb8a3ad48100629e4300", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93010000000000000044547d599077c3d45d34fa843cbe360e8a29b9271caa102177189e228e1d11d380841e000000000000020a0003010000000000000000c8052bd257ff9acc9674b92dad84782ac68cc44ed292595d4ef0369b71c28612ac6b2c7904ad2b725ba6470878322443164d916a65f6c2cef1ca6ad964dc340f" + ], + "outcome": "refuse", + "reason": "kind_not_permitted", + "index": 1 + }, + { + "name": "lifecycle_not_permitted", + "about": "a join authored by a participant under the default policy, which permits no lifecycle kind (§5)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000102000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93307fa5ceabd02c49a70506b002479152f0edc840e8840ed03fcc226e79681d9d15c440f5ce4b86b1e80f824d0598ad491924bbef1d2af81358dac2a9fb64500c" + ], + "outcome": "refuse", + "reason": "kind_not_permitted", + "index": 0 + }, + { + "name": "rate_exceeded", + "about": "a fourth event within one second under a policy of three per second (§6.3)", + "room": "main", + "default_policy": "default", + "policies": { + "c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93": "slow" + }, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000303000100618e3e7a9b873906e0811735c3a3eb57377794be244f4a0e183833158b075f94d421684ce983313d573424627e064f4941c6f866a61c6308ca7559a39af35b3408", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000008a1a49498746a1fc9b636d3e436950b0252e07c4e9bf21ff2008ae4ac56d296990d003000000000000030300010062e0758b83772acfc8dc232853d1c44c62b95d03b2f52e61067d70a4120e23720273af99332bead791da89f84d012bd4fabec10052379b65bb9debcf48d6b8640f", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930200000000000000114aaf8af2df6db23122af78a0c46b4bcf40fd978844739a698ec69f53a5658520a10700000000000003030001006322e2a293df80a0161861932cc6195db4b0aaa5b2e573e01dd86ddc2e82426e6ad3bd990cab62629e21fc478cb509b45a410c672c3c82484cff9445397cec940c", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9303000000000000000e9ec040b23038743d6d7742c4f733c046ffd0d221398f3959d373ff702cbbde3f420f000000000000030300010064c3a7622b85593a27960f2d1e28f261c3c8c5d4ad18fe595b263fd70e1e3f2c525ef365a1ed896d45a0893a330a76d425ff7b432126745e85bdde7245162ebe05" + ], + "outcome": "refuse", + "reason": "rate_exceeded", + "index": 3 + }, + { + "name": "reaction_rate_exceeded", + "about": "a second standalone reaction half a second after the first, under the default of one per second (§6.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080969800000000000004040004010000e73512f3dfc778d7701a365fb975afd171e636bb1fcccdb39ea0ddeec9014966da67e4907756642068c53b283b6e4ef43d05be24f54725c04db0efab7f084307", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93010000000000000021b14d8395a864005d715b17861488f90752ba250b4682358aca6eb5d696068da037a0000000000000040400040100008375636a8e79fe36876fb309a2ae2ed57c7888975952da2afca429e591efe8e58f53c7831ac2ca918b1e9be0c913c89d22b5199a73884b193f3978ebbee35200" + ], + "outcome": "refuse", + "reason": "rate_exceeded", + "index": 1 + }, + { + "name": "bad_utf8_overlong", + "about": "a chat text that is the overlong encoding C0 AF (§4.1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000304000200c0af6beecbe99a40d5dac5eeb5c2a1e2444ff01739659313da79cc9f15c567459a88a08ac34f30c5c295089889e815c8a5dabc697dc23726087a435e6846426f3f0b" + ], + "outcome": "refuse", + "reason": "bad_utf8", + "index": 0 + }, + { + "name": "bad_utf8_surrogate", + "about": "a chat text that encodes the surrogate U+D800 (ED A0 80) (§4.1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000305000300eda08058971c5fcc09e4bec7a0d314806e2805b44d7e46a131ff4503a62de5b3de9f2cc7a91ea718763ea1525eefe8dcad543c898f0f09dd59a03ab8628665f1d63a09" + ], + "outcome": "refuse", + "reason": "bad_utf8", + "index": 0 + }, + { + "name": "text_too_long", + "about": "a chat of 501 code points under the default of 500 (§4.1, §5)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000003f701f501616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161e6c695bce7d656762ab9c2aeedbbefcf17d3481b2c27fb003d7aa4bb0cef68c7222ece68202e15a4b80dd0eb26cf18f9470566f01dc1b62db4f3c598ac3aef0e" + ], + "outcome": "refuse", + "reason": "text_too_long", + "index": 0 + }, + { + "name": "truncated_tail", + "about": "a record missing its last ten bytes (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030b0009006375742073686f7274aceb4e99f055fbb42264adb66230622ecea2c2d0d85f0b0a72a98c5e52bd22601e39808dec3126f07b40d3b821de57aa8216abaa065b" + ], + "outcome": "refuse", + "reason": "truncated", + "index": 0 + }, + { + "name": "truncated_header", + "about": "a record cut inside its prev field (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9300000000000000000000000000000000000000000000000000000000000000" + ], + "outcome": "refuse", + "reason": "truncated", + "index": 0 + }, + { + "name": "unknown_version", + "about": "a record whose version is 2 (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563102994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030b0009006375742073686f7274aceb4e99f055fbb42264adb66230622ecea2c2d0d85f0b0a72a98c5e52bd22601e39808dec3126f07b40d3b821de57aa8216abaa065bbdb056726d8f4470f10b" + ], + "outcome": "refuse", + "reason": "unknown_version", + "index": 0 + }, + { + "name": "malformed_magic", + "about": "a record that begins WEV2 (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563201994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030b0009006375742073686f7274aceb4e99f055fbb42264adb66230622ecea2c2d0d85f0b0a72a98c5e52bd22601e39808dec3126f07b40d3b821de57aa8216abaa065bbdb056726d8f4470f10b" + ], + "outcome": "refuse", + "reason": "malformed", + "index": 0 + }, + { + "name": "malformed_trailing", + "about": "a record followed by one more byte (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030b0009006375742073686f7274aceb4e99f055fbb42264adb66230622ecea2c2d0d85f0b0a72a98c5e52bd22601e39808dec3126f07b40d3b821de57aa8216abaa065bbdb056726d8f4470f10b00" + ], + "outcome": "refuse", + "reason": "malformed", + "index": 0 + }, + { + "name": "malformed_anchor_flag", + "about": "a record whose anchor flag is 2 (§3.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000002030b0009006375742073686f7274aceb4e99f055fbb42264adb66230622ecea2c2d0d85f0b0a72a98c5e52bd22601e39808dec3126f07b40d3b821de57aa8216abaa065bbdb056726d8f4470f10b" + ], + "outcome": "refuse", + "reason": "malformed", + "index": 0 + }, + { + "name": "unknown_kind", + "about": "a signed record of kind 0x0D, which this revision does not define (§4, §6.1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000d0000679ec9be9fc92df55829ab661bb8a1c946a540aea8b938ca96f6ec1ff0b2fa4d68d4202685d12c17254ef860ed5eeef30c59267b2eb9384709c5db98afe1fc04" + ], + "outcome": "refuse", + "reason": "unknown_kind", + "index": 0 + }, + { + "name": "unknown_kind_lifecycle_reserved", + "about": "a signed record of kind 0x17, in the lifecycle range but not defined in this revision (§4.13)", + "room": "main", + "default_policy": "default", + "policies": { + "6ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b": "authority" + }, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ac6f85b612ef983dbee4acc7e8f1f6f120dac4d393f5ef39c32ee8e9227b53b0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000172000c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce93e51fd2936b3bd81be1665f447fc43f7e515b658e793977dfa78ed7fd5123b15cc6ec765bef9e09aa8937d2f9977d477484e437fbc560ac90fb1194e29778f505" + ], + "outcome": "refuse", + "reason": "unknown_kind", + "index": 0 + }, + { + "name": "wrong_room", + "about": "an event signed for another room (§6.1)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "574556310158a1ba0add8243923508c73998bf334d7db0e3035fa4ebd1e6e993b13f058273c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000030d000b0077726f6e6720706c616365931e62f567f73ec53edd4b72412e8664eb830c1797f0a7bb92af21fe4a16ab4833a57b1faf45e5dc24e06b61029cce739a7ce8a011e45ec9e1a5fa1a06f8ec04" + ], + "outcome": "refuse", + "reason": "wrong_room", + "index": 0 + }, + { + "name": "malformed_payload_cue", + "about": "a cue whose splice_info_section() states a section_length one more than it holds (§4.3)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000022a00010900000000000000011e00fc301c00000000000000fff00a05000000097fdf000100000000323563ce66d8551825508106ed2a69cb165486c4c3928f69efd4f1111eb3453757bc5503cc264caec4110100a5d7822cd4eaab12a9830244d87a26e358cf583fccdf3a02" + ], + "outcome": "refuse", + "reason": "malformed_payload", + "index": 0 + }, + { + "name": "malformed_payload_lang", + "about": "a caption whose language tag is one letter (§4.10)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000a0a00e80300000101650100781e98788d0bb0d59541f724b6e144ed5c1f61fa8af4291cca6c01dda35b4e900f7c6328f4a958e4e56cc03f9c1333d8b90792246f83faabb25c41600bde274501" + ], + "outcome": "refuse", + "reason": "malformed_payload", + "index": 0 + }, + { + "name": "malformed_payload_poll", + "about": "a poll_open with one option (§4.6)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f00000000000005110009004f6e6c79206f6e653f010300596573dc629d1f2f72e256e470f2e398a3634e0984ffab6c44a09de539a7ae92f296b0f203bb3112d8784af496dcf1b2f683c5b726918c2925675ecfff08fec15da609" + ], + "outcome": "refuse", + "reason": "malformed_payload", + "index": 0 + }, + { + "name": "tally_mismatch", + "about": "a poll_close stating counts the replay does not reach: one vote for Right, stated as one for Left (§7)", + "room": "main", + "default_policy": "default", + "policies": {}, + "events": [ + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000051e000e004c656674206f722072696768743f0204004c6566740500526967687481c5ba534af7882d17b259ef4224e1b6b04262fcf36f03933d620c79fddf2ed42e2706be4796a48227484c08934a8e12e6a8931f933dec86f803b500b0d22b04", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000080841e00000000000006210064fbeb7cd5ea1b7df2e95cae7997a4e439e91f3bced12067c2362cc2c685a3f90124b7df207a9637cdda0a52295dd47753f444fb30a6f3a757c254fd9a574a7f8575fc8c27bb0a122f927fed169599e7edf086a9f87286353ae1de68e44977070e", + "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e010000000000000064fbeb7cd5ea1b7df2e95cae7997a4e439e91f3bced12067c2362cc2c685a3f9c0c62d00000000000007290064fbeb7cd5ea1b7df2e95cae7997a4e439e91f3bced12067c2362cc2c685a3f9020100000000000000b90650815983287a35610055f9c7bfc58ef3deb8df25b492ff6d1ed271d7099eb1c3ca2784ee26052d3e1e5f857a97cb3dd106b4c15a5d0ab04e48a8c06b0000" + ], + "outcome": "refuse", + "reason": "tally_mismatch", + "index": 2 + } + ], + "policy_cases": [ + { + "name": "default", + "about": "a named policy of the vectors", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "accept" + }, + { + "name": "authority", + "about": "a named policy of the vectors", + "policy": "5745503101fe1f7f00000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "accept" + }, + { + "name": "chat_only", + "about": "a named policy of the vectors", + "policy": "574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "accept" + }, + { + "name": "slow", + "about": "a named policy of the vectors", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4010300000040420f00000000000100000040420f0000000000", + "outcome": "accept" + }, + { + "name": "truncated", + "about": "the default policy without its last byte", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000", + "outcome": "refuse", + "reason": "truncated" + }, + { + "name": "bad_magic", + "about": "a record that begins WEPX", + "policy": "5745505801fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "policy_malformed" + }, + { + "name": "unknown_version", + "about": "a record of version 2", + "policy": "5745503102fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "unknown_version" + }, + { + "name": "undefined_kind_0x0d", + "about": "kind 0x0D permitted, which this revision does not define", + "policy": "5745503101fe3f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "policy_malformed" + }, + { + "name": "undefined_kind_0x00", + "about": "kind 0x00 permitted", + "policy": "5745503101ff1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "policy_malformed" + }, + { + "name": "zero_window", + "about": "window_us 0", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000000000000000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "policy_malformed" + }, + { + "name": "zero_max_events", + "about": "max_events 0", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4010000000040420f00000000000100000040420f0000000000", + "outcome": "refuse", + "reason": "policy_malformed" + }, + { + "name": "trailing", + "about": "the default policy followed by one more byte", + "policy": "5745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000000", + "outcome": "refuse", + "reason": "policy_malformed" + } + ], + "binding_cases": [ + { + "name": "daterange_cue_out", + "about": "§8.3: a splice out with its planned duration and SCTE35-OUT", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c" + }, + { + "name": "daterange_caption", + "about": "§8.3: a caption with its DURATION", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"7c497adb549e9ff4dd08a9ae56ae2fa717af04104c88dc3265d7783e61ccf1ba\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:12.000Z\",DURATION=2.500,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AQAAAAAAAABrRqMJkUmRXnjBt47CdS0Lvu1OU8bEtaUiWojlen7j1gAbtwAAAAAAAAowAMQJAAAC0r-C4FCsgWGXtTZZYjDKuIqGpalYQB015Y2OObLjqBICZW4GAEhlbGxvLn1y5xi1ID8TI4r9syyUFHNPNcUEQFi2-6gC79qGv6h7wICeNKqAsTnHjS1l_bMppYwQwhe11xegayl3wM3G2Ao\"", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000006b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6001bb70000000000000a3000c409000002d2bf82e050ac816197b536596230cab88a86a5a958401d35e58d8e39b2e3a81202656e060048656c6c6f2e7d72e718b5203f13238afdb32c9414734f35c5044058b6fba802efda86bfa87bc0809e34aa80b139c78d2d65fdb329a58c10c217b5d717a06b2977c0cdc6d80a" + }, + { + "name": "daterange_chat", + "about": "§8.3: an event with no duration", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6d084ffde18d56a5c3fc919993c2b84747c48677c02e55a604f27a3446d01a3f\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:01.234Z\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\"", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000087d6120000000000000307000500706c61696e05fef957329f206d0db6292eb369191613362140f173ca69a7c9a08c36f834993731f7a3a141793a50df6d02d6ec4c00d4622950967a00460976c26ff9f24209" + }, + { + "name": "daterange_reordered_extra", + "about": "§8.3: the attributes in reverse order, with a client attribute this binding does not define, whose quoted value holds a comma", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:X-COM-EXAMPLE-NOTE=\"a,b\",X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\",SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,PLANNED-DURATION=30.000,START-DATE=\"2026-10-16T00:00:10.000Z\",CLASS=\"science.transaction.wai.event\",ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\"", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c" + }, + { + "name": "daterange_start_date_off", + "about": "§8.3: START-DATE one millisecond late", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.001Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_class_other", + "about": "§8.3: another CLASS", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"com.example.other\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_scte_dropped", + "about": "§8.3: the SCTE35-OUT a 35-1 out cue carries, removed", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_scte_lowercase", + "about": "§8.3: SCTE35-OUT in lowercase hexadecimal", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xfc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_duration_respelled", + "about": "§8.3: PLANNED-DURATION written 30 instead of 30.000", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_id_other", + "about": "§8.3: an ID that is not the event's digest", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"06b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "daterange_padded", + "about": "§8.3: X-WAI-EVENT with base64 padding", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA==\"", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "daterange_unterminated", + "about": "§8.3: X-WAI-EVENT's closing quote removed", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "daterange_no_event", + "about": "§8.3: no X-WAI-EVENT", + "binding": "daterange", + "input": "#EXT-X-DATERANGE:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "daterange_other_tag", + "about": "§8.3: not an EXT-X-DATERANGE tag", + "binding": "daterange", + "input": "#EXT-X-DATERANGES:ID=\"6b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6\",CLASS=\"science.transaction.wai.event\",START-DATE=\"2026-10-16T00:00:10.000Z\",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC302000000000000000FFF00F05000000657FFFFE002932E00001000000003DA3AEA8,X-WAI-EVENT=\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMWul-FwCRffyMtTEPmELzR-vCy-4IWy09xhkSdUJqo0-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICWmAAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAADwAAAAAAAAAAIvAAFlAAAAMHUAAAEjAPwwIAAAAAAAAAD_8A8FAAAAZX___gApMuAAAQAAAAA9o66o5XzxFJ_RcP5g5LamoVMlpashc8utEo59afKJxueZQ5QYQzm5zykdleoPB5egYI6vrL9oDHkAzcg48uO9cjoPDA\"", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "emsg_cue_out", + "about": "§8.4: a cue's box, event_duration its planned duration", + "binding": "emsg", + "input": "0000014c656d736701000000000003e80000000000004e20000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c" + }, + { + "name": "emsg_chat", + "about": "§8.4: a chat's box, event_duration 0", + "binding": "emsg", + "input": "000000f5656d736701000000000003e80000000000002be2000000006d084ffd75726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000087d6120000000000000307000500706c61696e05fef957329f206d0db6292eb369191613362140f173ca69a7c9a08c36f834993731f7a3a141793a50df6d02d6ec4c00d4622950967a00460976c26ff9f24209", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000087d6120000000000000307000500706c61696e05fef957329f206d0db6292eb369191613362140f173ca69a7c9a08c36f834993731f7a3a141793a50df6d02d6ec4c00d4622950967a00460976c26ff9f24209" + }, + { + "name": "emsg_caption", + "about": "§8.4: a caption's box", + "binding": "emsg", + "input": "00000121656d736701000000000003e800000000000055f0000009c47c497adb75726e3a7761693a6576656e743a310063617074696f6e005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000006b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6001bb70000000000000a3000c409000002d2bf82e050ac816197b536596230cab88a86a5a958401d35e58d8e39b2e3a81202656e060048656c6c6f2e7d72e718b5203f13238afdb32c9414734f35c5044058b6fba802efda86bfa87bc0809e34aa80b139c78d2d65fdb329a58c10c217b5d717a06b2977c0cdc6d80a", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e01000000000000006b46a3099149915e78c1b78ec2752d0bbeed4e53c6c4b5a5225a88e57a7ee3d6001bb70000000000000a3000c409000002d2bf82e050ac816197b536596230cab88a86a5a958401d35e58d8e39b2e3a81202656e060048656c6c6f2e7d72e718b5203f13238afdb32c9414734f35c5044058b6fba802efda86bfa87bc0809e34aa80b139c78d2d65fdb329a58c10c217b5d717a06b2977c0cdc6d80a" + }, + { + "name": "emsg_presentation_time_off", + "about": "§8.4: presentation_time one millisecond late", + "binding": "emsg", + "input": "0000014c656d736701000000000003e80000000000004e21000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "emsg_scheme_other", + "about": "§8.4: another scheme_id_uri", + "binding": "emsg", + "input": "0000014c656d736701000000000003e80000000000004e20000075306b46a30975726e3a6578616d706c653a783a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "emsg_value_other", + "about": "§8.4: value names another kind", + "binding": "emsg", + "input": "0000014d656d736701000000000003e80000000000004e20000075306b46a30975726e3a7761693a6576656e743a310063686174005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "emsg_timescale_other", + "about": "§8.4: timescale 90000", + "binding": "emsg", + "input": "0000014c656d73670100000000015f900000000000004e20000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "emsg_version_0", + "about": "§8.4: a version 0 box", + "binding": "emsg", + "input": "0000014c656d736700000000000003e80000000000004e20000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "emsg_size_wrong", + "about": "§8.4: a size one more than the box", + "binding": "emsg", + "input": "0000014d656d736701000000000003e80000000000004e20000075306b46a30975726e3a7761693a6576656e743a3100637565005745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce316ba5f85c0245f7f232d4c43e610bcd1faf0b2fb8216cb4f7186449d509aa8d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000809698000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb60000000000000000f000000000000000022f00016500000030750000012300fc302000000000000000fff00f05000000657ffffe002932e00001000000003da3aea8e57cf1149fd170fe60e4b6a6a15325a5ab2173cbad128e7d69f289c6e7994394184339b9cf291d95ea0f0797a0608eafacbf680c7900cdc838f2e3bd723a0f0c", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "msf_t", + "about": "§8.1: an unanchored event, indexed by t", + "binding": "msf", + "input": "{\"t\":1792108801234,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\"}}", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000087d6120000000000000307000500706c61696e05fef957329f206d0db6292eb369191613362140f173ca69a7c9a08c36f834993731f7a3a141793a50df6d02d6ec4c00d4622950967a00460976c26ff9f24209" + }, + { + "name": "msf_l", + "about": "§8.1: an anchored event, indexed by l", + "binding": "msf", + "input": "{\"l\":[0,48],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABtCE_94Y1WpcP8kZmTwrhHR8SGd8AuVaYE8no0RtAaP4CEHgAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAAwAAAAAAAAAAMKAAgAYW5jaG9yZWSHH8cal44Z3I2_xk_qS8KtEfYeRihGUEmy8ApfG1CgB-W1ednmYqI0O8_hPjjBeoZGRUZqLR_Qbo8TYFFGV7QN\"}}", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce9301000000000000006d084ffde18d56a5c3fc919993c2b84747c48677c02e55a604f27a3446d01a3f80841e000000000001e0d86db91106b9f80edff17fe3171e8ec14f9f2599c339ca4dca713b13cd3fb600000000000000003000000000000000030a000800616e63686f726564871fc71a978e19dc8dbfc64fea4bc2ad11f61e4628465049b2f00a5f1b50a007e5b579d9e662a2343bcfe13e38c17a864645466a2d1fd06e8f1360514657b40d" + }, + { + "name": "msf_respaced", + "about": "§8.1: the same record with its members reordered, whitespace, and a member this binding does not define", + "binding": "msf", + "input": "{ \"data\" : { \"note\": 1, \"wev1\" : \"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\" } ,\n \"t\" : 1792108801234 }", + "outcome": "accept", + "record": "5745563101994ce44cd8c3fa2781c7976335330a5e718019657440cb46a77db3210900ce31c2a1e8c1326f0811f77d5ef3628991d76af48f4a089e7ed08541846e351fce930000000000000000000000000000000000000000000000000000000000000000000000000000000087d6120000000000000307000500706c61696e05fef957329f206d0db6292eb369191613362140f173ca69a7c9a08c36f834993731f7a3a141793a50df6d02d6ec4c00d4622950967a00460976c26ff9f24209" + }, + { + "name": "msf_t_for_anchored", + "about": "§8.1: an anchored event indexed by t", + "binding": "msf", + "input": "{\"t\":1792108802000,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABtCE_94Y1WpcP8kZmTwrhHR8SGd8AuVaYE8no0RtAaP4CEHgAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAAwAAAAAAAAAAMKAAgAYW5jaG9yZWSHH8cal44Z3I2_xk_qS8KtEfYeRihGUEmy8ApfG1CgB-W1ednmYqI0O8_hPjjBeoZGRUZqLR_Qbo8TYFFGV7QN\"}}", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "msf_t_off", + "about": "§8.1: t one millisecond late", + "binding": "msf", + "input": "{\"t\":1792108801235,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\"}}", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "msf_t_float", + "about": "§8.1: t written as a fraction", + "binding": "msf", + "input": "{\"t\":1792108801234.0,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\"}}", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "msf_m_index", + "about": "§8.1: indexed by m, which this binding never writes", + "binding": "msf", + "input": "{\"m\":0,\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIfWEgAAAAAAAAMHAAUAcGxhaW4F_vlXMp8gbQ22KS6zaRkWEzYhQPFzymmnyaCMNvg0mTcx96OhQXk6UN9tAtbsTADUYilQlnoARgl2wm_58kIJ\"}}", + "outcome": "refuse", + "reason": "binding_mismatch" + }, + { + "name": "msf_two_indexes", + "about": "§8.1: both t and l (MSF §8.1: one index per record)", + "binding": "msf", + "input": "{\"t\":1792108801234,\"l\":[0,48],\"data\":{\"wev1\":\"V0VWMQGZTORM2MP6J4HHl2M1MwpecYAZZXRAy0anfbMhCQDOMcKh6MEybwgR931e82KJkddq9I9KCJ5-0IVBhG41H86TAQAAAAAAAABtCE_94Y1WpcP8kZmTwrhHR8SGd8AuVaYE8no0RtAaP4CEHgAAAAAAAeDYbbkRBrn4Dt_xf-MXHo7BT58lmcM5yk3KcTsTzT-2AAAAAAAAAAAwAAAAAAAAAAMKAAgAYW5jaG9yZWSHH8cal44Z3I2_xk_qS8KtEfYeRihGUEmy8ApfG1CgB-W1ednmYqI0O8_hPjjBeoZGRUZqLR_Qbo8TYFFGV7QN\"}}", + "outcome": "refuse", + "reason": "binding_malformed" + }, + { + "name": "msf_no_data", + "about": "§8.1: no data member", + "binding": "msf", + "input": "{\"t\":1792108801234}", + "outcome": "refuse", + "reason": "binding_malformed" + } + ] +} diff --git a/wai/live-conformance/live_events_verify.py b/wai/live-conformance/live_events_verify.py new file mode 100644 index 000000000..f681fe30a --- /dev/null +++ b/wai/live-conformance/live_events_verify.py @@ -0,0 +1,754 @@ +#!/usr/bin/env python3 +"""Independent verifier of the live-events corpus (extensions/live-events.md). + +Written from the extension's text. It shares no code with wai-rs, which generates the +corpus, and never runs it. It checks Ed25519 signatures with +../claim-conformance/_ed25519.py, WAI's strict rule (SPEC §7 *Signatures*) written from +RFC 8032 with the standard library, and computes BLAKE3 with +../claim-conformance/_blake3.py, written from its specification. Everything else is here: + +- the record (§3): its reader and refusals, its digest (SHA-256 without `sig`) and the + bytes its signature covers; +- every kind's payload (§4) and the text rules (§4.1); +- the policy record (§5) and every policy case; +- verification (§6): one record, each principal's chain in stream order with duplicates, + gaps and their refusals, both rates, and the outcome of a sequence; +- the poll tallies (§7): which votes count and which close closes, the feed0 records and + their state hash, and the check of a stated tally; +- the bindings (§8): the MSF record, the EXT-X-DATERANGE tag and the version 1 emsg box, + each rendered byte for byte and read back, and every binding case. + +For every vector it requires the outcome, reason, index, gaps, digests, tally and +renderings the corpus states; and of the corpus, that every kind has an accepted event +and every reason a case. + + python3 live_events_verify.py + +Exit status 0 only if every case verifies. Python 3.8 or later; standard library only. +""" +import base64 +import datetime +import hashlib +import json +import os +import re +import struct +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, os.path.join(HERE, "..", "claim-conformance")) +from _blake3 import blake3 # noqa: E402 +import _ed25519 as ED # noqa: E402 + +MAGIC = b"WEV1" +POLICY_MAGIC = b"WEP1" +SIGN_DOMAIN = b"wai:live-event\x01" +EVENT_TYPE = "urn:wai:event:1" +HLS_CLASS = "science.transaction.wai.event" +HLS_TAG = "#EXT-X-DATERANGE:" +MAX_SAFE = (1 << 53) - 1 + +# §4: the kinds and their names. +KINDS = { + 0x01: "meta", 0x02: "cue", 0x03: "chat", 0x04: "reaction", 0x05: "poll_open", + 0x06: "vote", 0x07: "poll_close", 0x08: "marker", 0x09: "control", 0x0A: "caption", + 0x0B: "decision", 0x0C: "take_commit", 0x10: "join", 0x11: "leave", 0x12: "publish", + 0x13: "unpublish", 0x14: "grant_exchange", 0x15: "takeover", 0x16: "failover", +} +LIFECYCLE = range(0x10, 0x17) + +# §9, in its order. +REASONS = [ + "truncated", "malformed", "unknown_version", "unknown_kind", "wrong_room", "bad_key", + "bad_signature", "kind_not_permitted", "payload_too_large", "malformed_payload", + "bad_utf8", "text_too_long", "seq_replay", "seq_not_increasing", "chain_broken", + "time_reversed", "delivery_gap", "rate_exceeded", "tally_mismatch", "policy_malformed", + "binding_malformed", "binding_mismatch", +] + + +class Refuse(Exception): + def __init__(self, reason): + super().__init__(reason) + self.reason = reason + + +class Reader: + """Reads fields in order; running out raises the reason the caller names.""" + + def __init__(self, b, short): + self.b, self.p, self.short = b, 0, short + + def take(self, n): + if self.p + n > len(self.b): + raise Refuse(self.short) + s = self.b[self.p:self.p + n] + self.p += n + return s + + def u8(self): + return self.take(1)[0] + + def u16(self): + return struct.unpack(" max_cp: + raise Refuse("text_too_long") + return s + + +def splice_info_section_ok(b): + """§4.3, form 1.""" + return len(b) >= 3 and b[0] == 0xFC and 3 + (((b[1] & 0x0F) << 8) | b[2]) == len(b) + + +def read_payload(kind, b, max_cp): + """§4: the payload as a dict, or Refuse.""" + m = "malformed_payload" + r = Reader(b, m) + p = {"kind": kind} + if kind in (0x01, 0x0C): + p["bytes"] = r.rest() + elif kind == 0x02: + p["type"] = r.u8() + if p["type"] not in (1, 2, 3, 4): + raise Refuse(m) + p["cue_id"], p["duration_ms"] = r.u32(), r.u32() + form = r.u8() + p["form"] = form + if form in (1, 2): + p["scte"] = r.take(r.u16()) + if form == 1 and not splice_info_section_ok(p["scte"]): + raise Refuse(m) + if form == 2 and len(p["scte"]) == 0: + raise Refuse(m) + elif form != 0: + raise Refuse(m) + elif kind == 0x03: + p["text"] = text(r, max_cp) + elif kind == 0x04: + p["type"] = r.u8() + if p["type"] not in (1, 2, 3, 4, 5): + raise Refuse(m) + p["value"] = r.u16() + if p["value"] == 0: + raise Refuse(m) + flags = r.u8() + if flags & ~0x03: + raise Refuse(m) + p["target"] = r.take(32) if flags & 1 else None + p["remove"] = bool(flags & 2) + elif kind == 0x05: + p["question"] = text(r, max_cp) + n = r.u8() + if n < 2: + raise Refuse(m) + p["options"] = [text(r, max_cp) for _ in range(n)] + elif kind == 0x06: + p["poll"], p["option"] = r.take(32), r.u8() + elif kind == 0x07: + p["poll"] = r.take(32) + n = r.u8() + if n < 2: + raise Refuse(m) + p["counts"] = [r.u32() for _ in range(n)] + elif kind == 0x08: + p["taxonomy"] = r.u32() + p["polarity"] = r.u8() + if p["polarity"] > 2: + raise Refuse(m) + p["text"] = text(r, max_cp) + has = r.u8() + if has not in (0, 1): + raise Refuse(m) + p["attachment"] = r.take(32) if has else None + elif kind == 0x09: + p["target"] = r.take(32) + c = r.u8() + p["command"] = c + if c == 1: + p["count_in_ms"] = r.u32() + elif c == 2: + pass + elif c == 3: + p["q16"] = r.u32() + if p["q16"] == 0: + raise Refuse(m) + elif c == 4: + p["on"] = r.u8() + if p["on"] not in (0, 1): + raise Refuse(m) + elif c == 5: + p["layer"] = r.u8() + else: + raise Refuse(m) + elif kind == 0x0A: + p["duration_ms"] = r.u32() + p["origin"] = r.u8() + if p["origin"] == 1: + p["model"] = None + elif p["origin"] in (2, 3): + p["model"] = r.take(32) + else: + raise Refuse(m) + lb = r.take(r.u8()) + try: + lang = lb.decode("ascii") + except UnicodeDecodeError: + raise Refuse(m) + if not (2 <= len(lang) <= 35 and LANG.fullmatch(lang)): + raise Refuse(m) + p["lang"] = lang + p["text"] = text(r, max_cp) + elif kind == 0x0B: + p["verdict"] = r.u8() + if p["verdict"] not in (1, 2, 3): + raise Refuse(m) + p["target"], p["reason"] = r.take(32), r.u16() + elif kind in LIFECYCLE: + p["subject"], p["detail"] = r.take(32), r.rest() + else: + raise Refuse("unknown_kind") + if not r.done(): + raise Refuse(m) + return p + + +# ---------------------------------------------------------------- §5 the policy + +def read_policy(b): + if len(b) < 4: + raise Refuse("truncated") + if b[:4] != POLICY_MAGIC: + raise Refuse("policy_malformed") + if len(b) < 5: + raise Refuse("truncated") + if b[4] != 1: + raise Refuse("unknown_version") + if len(b) < 65: + raise Refuse("truncated") + if len(b) > 65: + raise Refuse("policy_malformed") + kinds = b[5:37] + max_payload, max_cp, max_events, window, max_reactions, rwindow = struct.unpack("> (k % 8) & 1 and k not in KINDS: + raise Refuse("policy_malformed") + if 0 in (max_payload, max_cp, max_events, window, max_reactions, rwindow): + raise Refuse("policy_malformed") + return {"kinds": kinds, "max_payload": max_payload, "max_text_cp": max_cp, "max_events": max_events, + "window_us": window, "max_reactions": max_reactions, "reaction_window_us": rwindow} + + +def permits(policy, k): + return policy["kinds"][k // 8] >> (k % 8) & 1 == 1 + + +# ---------------------------------------------------------------- §6 verification + +class Verifier: + def __init__(self, room, default_policy, own): + self.room, self.default, self.own = room, default_policy, own + self.chains = {} # principal -> {"held": {seq: digest}, "head": (seq, digest, t) | None, "times": [], "reactions": []} + self.accepted = [] # (index, ev, payload) + self.gaps = [] + self.offered = 0 + + def offer(self, b): + index = self.offered + self.offered += 1 + ev = read_record(b) # §6.1 step 1 + if ev["kind"] not in KINDS: # step 2 + raise Refuse("unknown_kind") + if ev["room"] != self.room: # step 3 + raise Refuse("wrong_room") + bad = ED.verify(ev["principal"], SIGN_DOMAIN + ev["body"], ev["sig"]) # step 4 + if bad is not None: + raise Refuse("bad_key" if bad == "bad_key" else "bad_signature") + policy = self.own.get(ev["principal"], self.default) + if not permits(policy, ev["kind"]): # step 5 + raise Refuse("kind_not_permitted") + if len(ev["payload"]) > policy["max_payload"]: # step 6 + raise Refuse("payload_too_large") + p = read_payload(ev["kind"], ev["payload"], policy["max_text_cp"]) # step 7 + c = self.chains.setdefault(ev["principal"], {"held": {}, "head": None, "times": [], "reactions": []}) + seq, d, t = ev["seq"], ev["digest"], ev["t"] + if c["held"].get(seq) == d: # §6.2 step 1 + return "duplicate" + gap = None + if c["head"] is not None: # step 2 + hseq, hd, ht = c["head"] + if seq <= hseq: + raise Refuse("seq_replay" if seq in c["held"] else "seq_not_increasing") + if seq == hseq + 1: + if ev["prev"] != hd: + raise Refuse("chain_broken") + else: + gap = (hseq + 1, seq - 1) + if t < ht: + raise Refuse("time_reversed") + elif seq == 0: # step 3 + if ev["prev"] != bytes(32): + raise Refuse("chain_broken") + else: + gap = (0, seq - 1) + within = lambda times, w: 1 + sum(1 for f in times if t - f < w) # noqa: E731 + if within(c["times"], policy["window_us"]) > policy["max_events"]: # §6.3 + raise Refuse("rate_exceeded") + standalone = ev["kind"] == 0x04 and p["target"] is None + if standalone and within(c["reactions"], policy["reaction_window_us"]) > policy["max_reactions"]: + raise Refuse("rate_exceeded") + c["held"][seq] = d + c["head"] = (seq, d, t) + c["times"].append(t) + if standalone: + c["reactions"].append(t) + if gap: + self.gaps.append((ev["principal"], gap[0], gap[1])) + self.accepted.append((index, ev, p)) + return "accepted" + + +def run(verifier, records): + """§6.4: ("refuse", reason, index) | ("gap", gaps) | ("accept",).""" + for i, b in enumerate(records): + try: + verifier.offer(b) + except Refuse as e: + return ("refuse", e.reason, i) + if verifier.gaps: + return ("gap", list(verifier.gaps)) + bad = stated_tally_mismatch(verifier.accepted) + if bad is not None: + return ("refuse", "tally_mismatch", bad) + return ("accept",) + + +# ---------------------------------------------------------------- §7 polls + +def poll_state(accepted): + polls = {} + for _, ev, p in accepted: + if p["kind"] == 0x05: + polls[ev["digest"]] = {"author": ev["principal"], "seq": ev["seq"], "n": len(p["options"]), "t": ev["t"]} + closes = {} + for index, ev, p in accepted: + if p["kind"] == 0x07 and p["poll"] in polls and polls[p["poll"]]["author"] == ev["principal"]: + cur = closes.get(p["poll"]) + if cur is None or ev["seq"] < cur["seq"]: + closes[p["poll"]] = {"seq": ev["seq"], "t": ev["t"], "index": index, "counts": p["counts"]} + votes = {} + for _, ev, p in sorted((a for a in accepted if a[2]["kind"] == 0x06), key=lambda a: (a[1]["principal"], a[1]["seq"])): + poll = polls.get(p["poll"]) + if poll is None or p["option"] >= poll["n"] or ev["t"] < poll["t"]: + continue + close = closes.get(p["poll"]) + if close is not None and ev["t"] >= close["t"]: + continue + votes[(p["poll"], ev["principal"])] = p["option"] + return polls, votes, closes + + +def counts_of(poll_digest, poll, votes): + counts = [0] * poll["n"] + for (d, _), option in votes.items(): + if d == poll_digest: + counts[option] += 1 + return counts + + +def node_id(author, seq): + return blake3(b"wai:world-node\x01" + author + struct.pack(" MAX_SAFE: + raise Refuse("binding_malformed") + idx = '"t":%d' % ms + return '{%s,"data":{"wev1":"%s"}}' % (idx, b64url(b)) + + +def is_int(v): + return isinstance(v, int) and not isinstance(v, bool) + + +def msf_read(s, t0): + try: + o = json.loads(s) + except ValueError: + raise Refuse("binding_malformed") + if not isinstance(o, dict) or not isinstance(o.get("data"), dict) or not isinstance(o["data"].get("wev1"), str): + raise Refuse("binding_malformed") + b = b64url_read(o["data"]["wev1"]) + if b is None: + raise Refuse("binding_malformed") + ev = bound_record(b) + if sum(k in o for k in ("t", "l", "m")) != 1: + raise Refuse("binding_malformed") + want = json.loads(msf_render(b, t0)) + if "l" in want: + got = o.get("l") + ok = isinstance(got, list) and len(got) == 2 and all(is_int(x) for x in got) and got == want["l"] + else: + ok = is_int(o.get("t")) and o["t"] == want["t"] + if not ok: + raise Refuse("binding_mismatch") + del ev + return b + + +def daterange_attrs(b, t0): + """§8.3's table: (name, value as written), in order.""" + ev = bound_record(b) + a = [("ID", '"%s"' % ev["digest"].hex()), ("CLASS", '"%s"' % HLS_CLASS), + ("START-DATE", '"%s"' % iso(wallclock_ms(ev, t0)))] + p = ev["p"] + if p is not None and p["kind"] == 0x02: + if p["duration_ms"] > 0: + a.append(("PLANNED-DURATION" if p["type"] in (1, 4) else "DURATION", seconds(p["duration_ms"]))) + if p["form"] == 1: + name = {1: "SCTE35-OUT", 4: "SCTE35-OUT", 2: "SCTE35-IN"}.get(p["type"], "SCTE35-CMD") + a.append((name, "0x" + p["scte"].hex().upper())) + elif p is not None and p["duration_ms"] > 0: + a.append(("DURATION", seconds(p["duration_ms"]))) + a.append(("X-WAI-EVENT", '"%s"' % b64url(b))) + return a + + +DATERANGE_NAMES = ("ID", "CLASS", "START-DATE", "DURATION", "PLANNED-DURATION", "SCTE35-CMD", "SCTE35-OUT", "SCTE35-IN", "X-WAI-EVENT") + + +def daterange_render(b, t0): + return HLS_TAG + ",".join("%s=%s" % nv for nv in daterange_attrs(b, t0)) + + +def attribute_list(s): + """RFC 8216 §4.2, as §8.3 reads it; None when it does not read.""" + out, i = {}, 0 + while i < len(s): + m = re.match(r"[A-Z0-9-]+", s[i:]) + if not m or i + m.end() >= len(s) or s[i + m.end()] != "=": + return None + name = m.group(0) + i += m.end() + 1 + start = i + if s[i] == '"': + j = s.find('"', i + 1) + if j < 0: + return None + i = j + 1 + else: + while i < len(s) and s[i] != ",": + i += 1 + if i == start or name in out: + return None + out[name] = s[start:i] + if i < len(s): + if s[i] != "," or i + 1 == len(s): + return None + i += 1 + return out + + +def daterange_read(line, t0): + if not line.startswith(HLS_TAG): + raise Refuse("binding_malformed") + got = attribute_list(line[len(HLS_TAG):]) + if got is None or "X-WAI-EVENT" not in got: + raise Refuse("binding_malformed") + v = got["X-WAI-EVENT"] + if len(v) < 2 or v[0] != '"' or v[-1] != '"': + raise Refuse("binding_malformed") + b = b64url_read(v[1:-1]) + if b is None: + raise Refuse("binding_malformed") + want = dict(daterange_attrs(b, t0)) + for name in DATERANGE_NAMES: + if got.get(name) != want.get(name): + raise Refuse("binding_mismatch") + return b + + +def emsg_render(b, pt0): + ev = bound_record(b) + p = ev["p"] + if p is not None: + duration = p["duration_ms"] if p["duration_ms"] else 0xFFFFFFFF + else: + duration = 0 + pt = pt0 + ev["t"] // 1000 + if pt >= 1 << 64: + raise Refuse("binding_malformed") + body = struct.pack(">BBBBIQI", 1, 0, 0, 0, 1000, pt, duration) + ev["digest"][:4] + body += EVENT_TYPE.encode() + b"\x00" + KINDS[ev["kind"]].encode() + b"\x00" + b + return struct.pack(">I", 8 + len(body)) + b"emsg" + body + + +def emsg_read(box, pt0): + if len(box) < 32 or struct.unpack(">I", box[:4])[0] != len(box) or box[4:8] != b"emsg" or box[8] != 1: + raise Refuse("binding_malformed") + rest = box[32:] + z1 = rest.find(b"\x00") + z2 = rest.find(b"\x00", z1 + 1) if z1 >= 0 else -1 + if z2 < 0: + raise Refuse("binding_malformed") + b = rest[z2 + 1:] + bound_record(b) + if emsg_render(b, pt0) != box: + raise Refuse("binding_mismatch") + return b + + +def read_binding(kind, value, t0, pt0): + if kind == "daterange": + return daterange_read(value, t0) + if kind == "msf": + return msf_read(value, t0) + if kind == "emsg": + try: + box = bytes.fromhex(value) + except ValueError: + raise Refuse("binding_malformed") + return emsg_read(box, pt0) + raise Refuse("binding_malformed") + + +# ---------------------------------------------------------------- the corpus + +def main(corpus_dir): + fails = [] + st = ED._self_test() + print(("PASS" if not st else "FAIL") + " Ed25519 strict rule self-test " + ",".join(st)) + if st: + fails.append("ed25519 self-test") + with open(os.path.join(corpus_dir, "vectors.json"), encoding="utf-8") as f: + doc = json.load(f) + t0, pt0 = doc["t0_unix_us"], doc["pt0_ms"] + policies = {} + for name, h in doc["policies"].items(): + try: + policies[name] = read_policy(bytes.fromhex(h)) + except Refuse as e: + fails.append("policy %s: %s" % (name, e.reason)) + rooms = {n: bytes.fromhex(h) for n, h in doc["rooms"].items()} + kinds_accepted, reasons_seen = set(), set() + n_vec = 0 + for v in doc["vectors"]: + n_vec += 1 + name = v["name"] + own = {bytes.fromhex(k): policies[p] for k, p in v["policies"].items()} + ver = Verifier(rooms[v["room"]], policies[v["default_policy"]], own) + records = [bytes.fromhex(e) for e in v["events"]] + out = run(ver, records) + problems = [] + if out[0] != v["outcome"]: + problems.append("outcome %s, the corpus states %s" % (out, v["outcome"])) + elif out[0] == "refuse": + if (out[1], out[2]) != (v["reason"], v["index"]): + problems.append("refused %s at %d, the corpus states %s at %s" % (out[1], out[2], v["reason"], v["index"])) + elif out[0] == "gap": + gaps = [{"principal": p.hex(), "first": a, "last": z} for p, a, z in out[1]] + if gaps != v["gaps"] or v.get("reason") != "delivery_gap": + problems.append("gaps %s differ" % gaps) + if out[0] in ("accept", "gap"): + if [hashlib.sha256(read_record(r)["body"]).hexdigest() for r in records] != v["digests"]: + problems.append("digests differ") + if out[0] == "accept": + if tally(ver.accepted) != v["tally"]: + problems.append("tally %s differs" % tally(ver.accepted)) + if len(v["bindings"]) != len(records): + problems.append("not one binding entry per event") + for i, (r, bnd) in enumerate(zip(records, v["bindings"])): + rendered = {"msf": msf_render(r, t0), "daterange": daterange_render(r, t0), "emsg": emsg_render(r, pt0).hex()} + if rendered != bnd: + problems.append("event %d: a rendering differs: %s" % (i, [k for k in rendered if rendered[k] != bnd.get(k)])) + for k in ("msf", "daterange", "emsg"): + try: + if read_binding(k, bnd[k], t0, pt0) != r: + problems.append("event %d: %s reads back to other bytes" % (i, k)) + except Refuse as e: + problems.append("event %d: %s refused %s" % (i, k, e.reason)) + for _, ev, _ in ver.accepted: + kinds_accepted.add(ev["kind"]) + if v.get("reason"): + reasons_seen.add(v["reason"]) + print(("PASS" if not problems else "FAIL") + " vector %s: %s%s" % (name, out[0], "" if out[0] == "accept" else " " + str(out[1] if out[0] == "refuse" else "delivery_gap"))) + fails += ["%s: %s" % (name, p) for p in problems] + for c in doc["policy_cases"]: + try: + read_policy(bytes.fromhex(c["policy"])) + got = ("accept", None) + except Refuse as e: + got = ("refuse", e.reason) + want = (c["outcome"], c.get("reason")) + if got != want: + fails.append("policy case %s: %s, the corpus states %s" % (c["name"], got, want)) + if c.get("reason"): + reasons_seen.add(c["reason"]) + print("%s policy cases" % ("PASS" if not any(f.startswith("policy case") for f in fails) else "FAIL")) + for c in doc["binding_cases"]: + try: + got = ("accept", read_binding(c["binding"], c["input"], t0, pt0).hex()) + except Refuse as e: + got = ("refuse", e.reason) + want = (c["outcome"], c["record"] if c["outcome"] == "accept" else c.get("reason")) + if got != want: + fails.append("binding case %s: %s, the corpus states %s" % (c["name"], got, want)) + if c.get("reason"): + reasons_seen.add(c["reason"]) + print("%s binding cases" % ("PASS" if not any(f.startswith("binding case") for f in fails) else "FAIL")) + missing_kinds = sorted(KINDS[k] for k in set(KINDS) - kinds_accepted) + missing_reasons = [r for r in REASONS if r not in reasons_seen] + if missing_kinds: + fails.append("no accepted event of kind %s" % ", ".join(missing_kinds)) + if missing_reasons: + fails.append("no case refused with %s" % ", ".join(missing_reasons)) + print("%s every kind accepted and every reason exercised" % ("PASS" if not (missing_kinds or missing_reasons) else "FAIL")) + for f in fails: + print("FAIL " + f) + print(("PASS" if not fails else "FAIL") + " live-events corpus: %d vectors, every policy and binding case" % n_vec) + return 1 if fails else 0 + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("usage: live_events_verify.py ", file=sys.stderr) + sys.exit(2) + sys.exit(main(sys.argv[1])) diff --git a/wai/live-conformance/live_rooms_verify.py b/wai/live-conformance/live_rooms_verify.py new file mode 100644 index 000000000..e060da078 --- /dev/null +++ b/wai/live-conformance/live_rooms_verify.py @@ -0,0 +1,986 @@ +#!/usr/bin/env python3 +"""Independent verifier of the live-rooms corpus (extensions/live-rooms.md). + +Written from the extension's text. It shares no code with wai-rs, which generates the +corpus, and never runs it. It checks Ed25519 signatures with +../claim-conformance/_ed25519.py, WAI's strict rule (SPEC §7 *Signatures*) written from +RFC 8032 with the standard library, and computes BLAKE3 (for a key log's commitments) +with ../claim-conformance/_blake3.py. Every event is verified by the live-events corpus's +own second implementation, live_events_verify.py (live-events §6), which is likewise +written from its text alone. Everything else is here: + +- the room descriptor (§3): its reader, its field rules, its digest and signature, and the + registered publish profiles (§8), each written from §8.2's table and compared with the + record the corpus states; +- the room grant (§4): its reader and the eight checks of §4.3 in their order, its + attributes (§4.4), and its window; +- revocation (§5): the key-log head held for the descriptor's origin (jwp-receipts §7.2 + rules 1 to 3: its members, its canonical form and its root's signature), the + authority's entry, and the revoked grants and viewers; +- track naming (§6) and the lifecycle detail (§7.2), with slots, takeover and failover; +- room verification (§9): the merged order, each record's steps, the room state, the + outcome, and the `moqt` scopes of each grant (§10.2). + +For every vector it requires the outcome, reason and place, and for one that does not +refuse the room id, the gaps or the grant digests, merged order, state, tally and scopes +the corpus states; and of the corpus, that every reason of §11 refuses a vector. + + python3 live_rooms_verify.py + +Exit status 0 only if every vector verifies. Python 3.8 or later; standard library only. +""" +import hashlib +import json +import os +import re +import struct +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HERE) +sys.path.insert(0, os.path.join(HERE, "..", "claim-conformance")) +import live_events_verify as LEV # noqa: E402 +from _blake3 import blake3 # noqa: E402 +import _ed25519 as ED # noqa: E402 + +Refuse = LEV.Refuse + +DESCRIPTOR_MAGIC = b"WRD1" +GRANT_MAGIC = b"WRG1" +DESCRIPTOR_DOMAIN = b"wai:live-room\x01" +GRANT_DOMAIN = b"wai:live-room-grant\x01" +VIEWER_DOMAIN = b"wai:live-viewer\x01" +AUTHORITY = "live/room" +MAX_GRANT_S = 14 * 86400 +NO_CEILING = 2 ** 64 - 1 +MEDIA = {1: "audio", 2: "video", 3: "screen"} +MODERATE, DIRECT, COMPOSE, RECORD = 1, 2, 4, 8 +CONTROL, DECISION = 0x09, 0x0B +JOIN, LEAVE, PUBLISH, UNPUBLISH, EXCHANGE, TAKEOVER, FAILOVER = range(0x10, 0x17) + +# §11, in its order. +REASONS = [ + "descriptor_invalid", "key_log_missing", "key_log_not_held", "authority_not_listed", + "authority_revoked", "grant_invalid", "grant_too_long", "caps_exceed_role", + "grant_exceeds_room", "exchange_unlinked", "exchange_mismatch", "lifecycle_malformed", + "grant_unknown", "grant_wrong_principal", "grant_revoked", "grant_reused", + "already_present", "not_present", "participant_limit", "outside_grant_window", + "power_not_granted", "publish_not_permitted", "profile_not_granted", "already_published", + "not_published", "slot_unknown", "slot_full", "publisher_limit", "exchange_not_current", + "exchange_off_tick", "takeover_not_higher", "failover_not_standby", "failover_early", +] + + +class Reader: + """Reads fields in order; running out is `truncated` (§3.4).""" + + def __init__(self, b, p=0): + self.b, self.p = b, p + + def take(self, n): + if self.p + n > len(self.b): + raise Refuse("truncated") + s = self.b[self.p:self.p + n] + self.p += n + return s + + def u8(self): + return self.take(1)[0] + + def u16(self): + return struct.unpack("> (k % 8) & 1 == 1 + + +def within(a, b): + """Every bit of bitmap or byte `a` is set in `b`.""" + if isinstance(a, int): + return a & ~b == 0 + return all(x & ~y == 0 for x, y in zip(a, b)) + + +def lifecycle_permitted(policy): + return any(LEV.permits(policy, k) for k in range(0x10, 0x20)) + + +def powers_cover(kinds, powers): + """§3.3: decision needs moderate; control needs direct or record.""" + return (not has(kinds, DECISION) or powers & MODERATE) and (not has(kinds, CONTROL) or powers & (DIRECT | RECORD)) + + +# ---------------------------------------------------------------- §8 profiles + +def profile_bytes(name, media, codecs, layering, mode, layers, sample_rate, channels, processing): + """§8.1's record.""" + o = bytes([len(name)]) + name.encode() + bytes([media, len(codecs)]) + for c in codecs: + o += bytes([len(c)]) + c.encode() + o += bytes([layering, len(mode)]) + mode.encode() + bytes([len(layers)]) + for w, h, fps, lo, hi in layers: + o += struct.pack(" 3: + return False + if (p["layering"] == 2) != (len(p["mode"]) > 0) or (p["mode"] and not MODE.fullmatch(p["mode"])): + return False + n = len(p["layers"]) + if not 1 <= n <= 8 or (p["layering"] == 0 and n != 1): + return False + audio = p["media"] == 1 + for w, h, fps, lo, hi in p["layers"]: + if hi == 0 or lo > hi: + return False + if audio and (w, h, fps) != (0, 0, 0): + return False + if not audio and not (w and h and fps): + return False + if audio: + return p["sample_rate"] > 0 and 1 <= p["channels"] <= 8 and p["processing"] & ~0x0F == 0 + return p["sample_rate"] == 0 and p["channels"] == 0 and p["processing"] == 0 + + +# ---------------------------------------------------------------- §3 the descriptor + +def read_descriptor(b): + """§3.4, then §3.2: the descriptor, or Refuse.""" + read_head(b, DESCRIPTOR_MAGIC) + r = Reader(b, 5) + d = {"authority": r.take(32), "clock": r.take(32), "t0": r.u64(), "tick": r.u64(), "origin": r.string(), + "max_present": r.u32(), "max_publishers": r.u16(), "reval": r.u32(), "ceiling": r.take(65)} + d["roles"] = [] + for _ in range(r.u8()): + d["roles"].append({"name": r.name(), "publish": r.u8(), "subscribe": r.u8(), "max_layer": r.u8(), + "powers": r.u8(), "events": r.take(32)}) + d["slots"] = [] + for _ in range(r.u8()): + d["slots"].append({"name": r.name(), "media": r.u8(), "redundancy": r.u8(), "failover_ms": r.u32()}) + d["profiles"] = [read_profile(r) for _ in range(r.u8())] + d["review"] = (r.take(32), r.u32(), r.u8()) + d["mode"], d["retention"], d["commit_interval_ms"], d["jitter_ms"] = r.u8(), r.u16(), r.u32(), r.u32() + d["regions"] = [r.take(2) for _ in range(r.u8())] + body = b[:r.p] + d["sig"] = r.take(64) + if r.p != len(b): + raise Refuse("malformed") + if not descriptor_ok(d): + raise Refuse("descriptor_invalid") + bad = ED.verify(d["authority"], DESCRIPTOR_DOMAIN + body, d["sig"]) + if bad: + raise Refuse(bad) + d["room"] = hashlib.sha256(body).digest() + try: + d["ceiling_policy"] = LEV.read_policy(d["ceiling"]) + except Refuse: + raise Refuse("descriptor_invalid") + return d + + +def descriptor_ok(d): + """§3.4's field rules.""" + if d["tick"] == 0 or not (d["origin"] == b"" or is_token(d["origin"], 255)): + return False + if d["max_present"] == 0 or d["max_publishers"] == 0: + return False + try: + ceiling = LEV.read_policy(d["ceiling"]) + except Refuse: + return False + if lifecycle_permitted(ceiling) or not 1 <= len(d["roles"]) <= 16: + return False + names = [x["name"] for x in d["roles"]] + if len(set(names)) != len(names): + return False + for x in d["roles"]: + if not is_name(x["name"]) or x["subscribe"] > 1 or x["publish"] & ~0b111 or x["powers"] & ~0b1111: + return False + if x["subscribe"] == 0 and x["max_layer"] != 0: + return False + if not within(x["events"], ceiling["kinds"]) or not powers_cover(x["events"], x["powers"]): + return False + if len(d["slots"]) > 16 or len({s["name"] for s in d["slots"]}) != len(d["slots"]): + return False + for s in d["slots"]: + if not is_slot_name(s["name"]) or s["media"] not in MEDIA: + return False + if (s["redundancy"], s["failover_ms"] > 0) not in ((1, False), (2, True)): + return False + if len(d["profiles"]) > 16 or len({p["name"] for p in d["profiles"]}) != len(d["profiles"]): + return False + for p in d["profiles"]: + if not profile_ok(p): + return False + reg = REGISTERED.get(p["name"].decode()) + if reg is not None and reg != p["bytes"]: + return False + kinds, deadline, fallback = d["review"] + if any(kinds): + if not within(kinds, ceiling["kinds"]) or deadline == 0 or fallback not in (1, 2): + return False + elif deadline != 0 or fallback != 0: + return False + if d["mode"] > 2 or len(d["regions"]) > 16: + return False + if d["mode"] == 0: + if d["commit_interval_ms"] != 0 or d["jitter_ms"] != 0: + return False + elif d["commit_interval_ms"] == 0 or d["jitter_ms"] > d["commit_interval_ms"]: + return False + if not all(re.fullmatch(rb"[A-Z]{2}", x) for x in d["regions"]): + return False + return all(a < b for a, b in zip(d["regions"], d["regions"][1:])) + + +def is_room_key(d, k): + return k == d["authority"] or k == d["clock"] + + +# ---------------------------------------------------------------- §4 grants + +def read_attrs(b): + """§4.4: the entries, or None when they break a rule.""" + if len(b) > 1024: + return None + r = Reader(b) + out, last = [], None + try: + while r.p < len(b): + k, v = r.name(), r.string() + if not is_slot_name(k) or (last is not None and last >= k): + return None + out.append((k.decode(), v.decode("utf-8"))) + last = k + except (Refuse, UnicodeDecodeError): + return None + return out + + +def read_grant(b): + """§4.3 step 1: the grant's fields as read.""" + read_head(b, GRANT_MAGIC) + r = Reader(b, 5) + g = {"room": r.take(32), "principal": r.take(32), "prev": r.take(32), "effective": r.u64(), "nbf": r.u64(), + "exp": r.u64(), "role": r.u8(), "publish": r.u8(), "subscribe": r.u8(), "max_layer": r.u8(), + "powers": r.u8(), "precedence": r.u8(), "once": r.take(16), "viewer": r.take(16), "policy_bytes": r.take(65), + "joules": r.u64(), "funds": r.u64(), "currency": r.take(3)} + g["profiles"] = list(r.take(r.u8())) + g["origins"] = [r.name() for _ in range(r.u8())] + g["attrs"] = r.string() + g["body"] = b[:r.p] + g["sig"] = r.take(64) + if r.p != len(b): + raise Refuse("malformed") + g["digest"] = hashlib.sha256(g["body"]).digest() + return g + + +def grant_fields_ok(g, d, held): + """§4.3 step 5.""" + if g["exp"] <= g["nbf"]: + return False + if g["prev"] == bytes(32): + if g["effective"] != 0: + return False + elif g["effective"] % d["tick"] != 0: + return False + if g["role"] >= len(d["roles"]) or g["subscribe"] > 1: + return False + if g["publish"] & ~0b111 or g["powers"] & ~0b1111 or (g["subscribe"] == 0 and g["max_layer"] != 0): + return False + try: + policy = LEV.read_policy(g["policy_bytes"]) + except Refuse: + return False + if lifecycle_permitted(policy) or not powers_cover(policy["kinds"], g["powers"]): + return False + funded = g["funds"] != NO_CEILING + if funded != (g["currency"] != bytes(3)) or (funded and not re.fullmatch(rb"[A-Z]{3}", g["currency"])): + return False + media = set() + for i in g["profiles"]: + if i >= len(d["profiles"]): + return False + m = d["profiles"][i]["media"] + if m in media or not publishes(g, m): + return False + media.add(m) + if len(g["origins"]) > 8 or not all(is_token(o, 255) for o in g["origins"]): + return False + if read_attrs(g["attrs"]) is None: + return False + return all(h["digest"] != g["digest"] for h in held) + + +def publishes(g, m): + return m in MEDIA and g["publish"] >> (m - 1) & 1 == 1 + + +def check_grants(d, grants): + """§4.3 over every grant, in order: the grants, or (index, reason).""" + held = [] + for i, b in enumerate(grants): + try: + g = read_grant(b) + except Refuse as e: + return None, (i, e.reason) + bad = ED.verify(d["authority"], GRANT_DOMAIN + g["body"], g["sig"]) + if bad: + return None, (i, bad) + if g["prev"] != bytes(32): + old = next((h for h in held if h["digest"] == g["prev"]), None) + if old is None: + return None, (i, "exchange_unlinked") + if old["room"] != g["room"] or old["principal"] != g["principal"]: + return None, (i, "exchange_mismatch") + if g["room"] != d["room"]: + return None, (i, "wrong_room") + if not grant_fields_ok(g, d, held): + return None, (i, "grant_invalid") + g["policy"] = LEV.read_policy(g["policy_bytes"]) + if g["exp"] - g["nbf"] > MAX_GRANT_S: + return None, (i, "grant_too_long") + role = d["roles"][g["role"]] + if (not within(g["publish"], role["publish"]) or g["subscribe"] > role["subscribe"] + or g["max_layer"] > role["max_layer"] or not within(g["powers"], role["powers"]) + or not within(g["policy"]["kinds"], role["events"])): + return None, (i, "caps_exceed_role") + p, c = g["policy"], d["ceiling_policy"] + if (p["max_payload"] > c["max_payload"] or p["max_text_cp"] > c["max_text_cp"] + or p["max_events"] > c["max_events"] or p["window_us"] < c["window_us"] + or p["max_reactions"] > c["max_reactions"] or p["reaction_window_us"] < c["reaction_window_us"]): + return None, (i, "grant_exceeds_room") + held.append(g) + return held, None + + +def good_at(g, d, t): + """§4.3: nbf ≤ ⌊(t0 + t) / 10^6⌋ < exp.""" + return g["nbf"] <= (d["t0"] + t) // 1000000 < g["exp"] + + +def viewer_tag(g): + return None if g["viewer"] == bytes(16) else hashlib.sha256(VIEWER_DOMAIN + g["viewer"]).digest() + + +# ---------------------------------------------------------------- §5 the key log + +REVISION_MEMBERS = {"kind", "origin", "seq", "prev", "issued_at", "root", "next_root", "keys", "revoked_modules", + "grant_max_s", "status_max_age_s", "sig"} +ENTRY_MEMBERS = {"id", "key", "may_sign", "status", "until", "compromised_since"} +HEX32 = re.compile(r"[0-9a-f]{64}") +LOG_TIME = re.compile(r"[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]Z") +KEY_ID = re.compile(r"[A-Za-z0-9._-]{1,64}") +AUTH_SEG = re.compile(r"[A-Za-z0-9._-]+") + + +def no_duplicates(pairs): + keys = [k for k, _ in pairs] + if len(set(keys)) != len(keys): + raise ValueError("a member named twice") + return dict(pairs) + + +def is_int(v): + return isinstance(v, int) and not isinstance(v, bool) and 0 <= v <= 2 ** 53 - 1 + + +def commitment(k): + return blake3(b"wai:key-set-next\x01" + k) + + +def jcs(v): + """RFC 8785 over what a key-log revision holds: strings of ASCII, integers, null, arrays.""" + return json.dumps(v, sort_keys=True, separators=(",", ":"), ensure_ascii=False) + + +def entry_ok(e): + if not isinstance(e, dict) or set(e) != ENTRY_MEMBERS: + return False + if not isinstance(e["id"], str) or not KEY_ID.fullmatch(e["id"]): + return False + if not isinstance(e["key"], str) or not HEX32.fullmatch(e["key"]) or not ED.strict_key(bytes.fromhex(e["key"])): + return False + ms = e["may_sign"] + if not isinstance(ms, list) or not ms or len(set(map(str, ms))) != len(ms): + return False + for a in ms: + if not isinstance(a, str) or not 1 <= len(a) <= 128 or not all(AUTH_SEG.fullmatch(s) for s in a.split("/")): + return False + for t in ("until", "compromised_since"): + if e[t] is not None and not (isinstance(e[t], str) and LOG_TIME.fullmatch(e[t])): + return False + shape = {"active": e["until"] is None and e["compromised_since"] is None, + "retired": e["until"] is not None and e["compromised_since"] is None, + "revoked": e["compromised_since"] is not None} + return shape.get(e["status"], False) + + +def revision_ok(v): + """jwp-receipts §7.2 rule 1, as far as this verifier reads it.""" + if not isinstance(v, dict) or set(v) != REVISION_MEMBERS or v["kind"] != "wai-key-set": + return False + if not isinstance(v["origin"], str) or not is_int(v["seq"]): + return False + if (v["seq"] == 0) != (v["prev"] is None) or (v["prev"] is not None and not (isinstance(v["prev"], str) and HEX32.fullmatch(v["prev"]))): + return False + if not isinstance(v["issued_at"], str) or not LOG_TIME.fullmatch(v["issued_at"]): + return False + for k in ("root", "next_root"): + if not isinstance(v[k], str) or not HEX32.fullmatch(v[k]): + return False + root, nxt = bytes.fromhex(v["root"]), bytes.fromhex(v["next_root"]) + if nxt == commitment(root): + return False + if not isinstance(v["keys"], list) or not all(entry_ok(e) for e in v["keys"]): + return False + ids, keys = [e["id"] for e in v["keys"]], [e["key"] for e in v["keys"]] + if len(set(ids)) != len(ids) or len(set(keys)) != len(keys): + return False + if any(bytes.fromhex(k) == root or commitment(bytes.fromhex(k)) == nxt for k in keys): + return False + rm = v["revoked_modules"] + if not isinstance(rm, list) or not all(isinstance(x, str) and HEX32.fullmatch(x) for x in rm) or len(set(rm)) != len(rm): + return False + if not (is_int(v["grant_max_s"]) and 1 <= v["grant_max_s"] <= 86400): + return False + if not (is_int(v["status_max_age_s"]) and 1 <= v["status_max_age_s"] <= 3600): + return False + return isinstance(v["sig"], str) and re.fullmatch(r"[0-9a-f]{128}", v["sig"]) is not None + + +def check_key_log(d, head): + """§5: the revoked digests, or Refuse.""" + if d["origin"] == b"": + return set() + if head is None: + raise Refuse("key_log_missing") + try: + v = json.loads(head, object_pairs_hook=no_duplicates) + except ValueError: + raise Refuse("key_log_not_held") + if not revision_ok(v) or v["origin"] != d["origin"].decode(): + raise Refuse("key_log_not_held") + unsigned = {k: x for k, x in v.items() if k != "sig"} + if ED.verify(bytes.fromhex(v["root"]), b"wai:key-set\x01" + jcs(unsigned).encode(), bytes.fromhex(v["sig"])): + raise Refuse("key_log_not_held") + entry = next((e for e in v["keys"] if e["key"] == d["authority"].hex() and AUTHORITY in e["may_sign"]), None) + if entry is None: + raise Refuse("authority_not_listed") + if entry["status"] == "revoked": + raise Refuse("authority_revoked") + return {bytes.fromhex(x) for x in v["revoked_modules"]} + + +def revoked(g, revoked_set): + return g["digest"] in revoked_set or viewer_tag(g) in revoked_set + + +# ---------------------------------------------------------------- §7 lifecycle detail + +def read_detail(kind, b): + """§7.2: the detail as a dict, or Refuse("lifecycle_malformed").""" + r = Reader(b) + try: + def slot(required): + s = r.name() + if (not s and required) or (s and not is_slot_name(s)): + raise Refuse("lifecycle_malformed") + return s.decode() + + def media(): + m = r.u8() + if m not in MEDIA: + raise Refuse("lifecycle_malformed") + return m + + def layers(): + n = r.u8() + if n == 0: + raise Refuse("lifecycle_malformed") + return n + + if kind == JOIN: + x = {"grant": r.take(32)} + elif kind == LEAVE: + x = {"reason": r.u8()} + if x["reason"] not in (1, 2, 3, 4): + raise Refuse("lifecycle_malformed") + elif kind == PUBLISH: + x = {"slot": slot(False), "media": media(), "profile": r.u8()} + x["layers"] = layers() + elif kind == UNPUBLISH: + x = {"slot": slot(False), "media": media()} + elif kind == EXCHANGE: + x = {"old": r.take(32), "new": r.take(32)} + elif kind == TAKEOVER: + x = {"slot": slot(True), "media": media(), "profile": r.u8()} + x["layers"] = layers() + x["previous"] = r.take(32) + elif kind == FAILOVER: + x = {"slot": slot(True), "media": media(), "failed": r.take(32), "last_seen": r.u64()} + else: + raise Refuse("lifecycle_malformed") + except Refuse: + raise Refuse("lifecycle_malformed") + if r.p != len(b): + raise Refuse("lifecycle_malformed") + return x + + +class Room: + """The room state of §9.3 and the checks of §7.2 that move it.""" + + def __init__(self, d, grants, revoked_set): + self.d, self.grants, self.revoked = d, grants, revoked_set + self.present = {} # principal -> grant digest + self.own = {} # (principal, media) -> (profile, layers) + self.slots = [{"live": None, "standby": None} for _ in d["slots"]] # each (principal, profile, layers) + self.timeline = [] + self.used_once = set() + + def grant(self, digest): + return next((g for g in self.grants if g["digest"] == digest), None) + + def current(self, p): + return self.grant(self.present[p]) if p in self.present else None + + def slot_index(self, name, m): + return next((i for i, s in enumerate(self.d["slots"]) if s["name"].decode() == name and s["media"] == m), None) + + def publishers(self): + out = {p for p, _ in self.own} + for s in self.slots: + out |= {h[0] for h in (s["live"], s["standby"]) if h} + return out + + def may_publish(self, g, m, profile, layers): + if not publishes(g, m): + raise Refuse("publish_not_permitted") + ps = self.d["profiles"] + if not (profile < len(ps) and profile in g["profiles"] and ps[profile]["media"] == m and layers <= len(ps[profile]["layers"])): + raise Refuse("profile_not_granted") + + def limit(self): + if len(self.publishers()) > self.d["max_publishers"]: + raise Refuse("publisher_limit") + + def drop(self, p): + for s in self.slots: + if s["standby"] and s["standby"][0] == p: + s["standby"] = None + if s["live"] and s["live"][0] == p: + s["live"], s["standby"] = s["standby"], None + + def publishing(self, p): + out = [(m, v[0]) for (q, m), v in sorted(self.own.items()) if q == p] + for i, s in enumerate(self.slots): + for h in (s["live"], s["standby"]): + if h and h[0] == p: + out.append((self.d["slots"][i]["media"], h[1])) + return out + + def need_present(self, p): + g = self.current(p) + if g is None: + raise Refuse("not_present") + return g + + def slot_of(self, name, m): + i = self.slot_index(name, m) + if i is None: + raise Refuse("slot_unknown") + return i + + def apply(self, kind, subject, x, t): + if kind == JOIN: + g = self.grant(x["grant"]) + if g is None: + raise Refuse("grant_unknown") + if g["principal"] != subject: + raise Refuse("grant_wrong_principal") + if subject in self.present: + raise Refuse("already_present") + if revoked(g, self.revoked): + raise Refuse("grant_revoked") + if g["once"] != bytes(16) and g["once"] in self.used_once: + raise Refuse("grant_reused") + if not good_at(g, self.d, t): + raise Refuse("outside_grant_window") + if len(self.present) + 1 > self.d["max_present"]: + raise Refuse("participant_limit") + if g["once"] != bytes(16): + self.used_once.add(g["once"]) + self.present[subject] = g["digest"] + self.timeline.append((subject, g["digest"], t)) + elif kind == LEAVE: + self.need_present(subject) + del self.present[subject] + self.own = {k: v for k, v in self.own.items() if k[0] != subject} + self.drop(subject) + elif kind == PUBLISH: + g = self.need_present(subject) + i = None if x["slot"] == "" else self.slot_of(x["slot"], x["media"]) + self.may_publish(g, x["media"], x["profile"], x["layers"]) + held = (subject, x["profile"], x["layers"]) + if i is None: + if (subject, x["media"]) in self.own: + raise Refuse("already_published") + self.own[(subject, x["media"])] = (x["profile"], x["layers"]) + else: + s = self.slots[i] + if any(h and h[0] == subject for h in (s["live"], s["standby"])): + raise Refuse("already_published") + if s["live"] and (self.d["slots"][i]["redundancy"] < 2 or s["standby"]): + raise Refuse("slot_full") + if s["live"] is None: + s["live"] = held + else: + s["standby"] = held + self.limit() + elif kind == UNPUBLISH: + self.need_present(subject) + if x["slot"] == "": + if (subject, x["media"]) not in self.own: + raise Refuse("not_published") + del self.own[(subject, x["media"])] + else: + s = self.slots[self.slot_of(x["slot"], x["media"])] + if not any(h and h[0] == subject for h in (s["live"], s["standby"])): + raise Refuse("not_published") + if s["standby"] and s["standby"][0] == subject: + s["standby"] = None + else: + s["live"], s["standby"] = s["standby"], None + elif kind == EXCHANGE: + cur = self.need_present(subject) + if cur["digest"] != x["old"]: + raise Refuse("exchange_not_current") + g = self.grant(x["new"]) + if g is None: + raise Refuse("grant_unknown") + if g["prev"] != x["old"]: + raise Refuse("exchange_unlinked") + if t != g["effective"]: + raise Refuse("exchange_off_tick") + if revoked(g, self.revoked): + raise Refuse("grant_revoked") + if not good_at(g, self.d, t): + raise Refuse("outside_grant_window") + for m, profile in self.publishing(subject): + if not publishes(g, m): + raise Refuse("publish_not_permitted") + if profile not in g["profiles"]: + raise Refuse("profile_not_granted") + self.present[subject] = g["digest"] + self.timeline.append((subject, g["digest"], t)) + elif kind == TAKEOVER: + g = self.need_present(subject) + i = self.slot_of(x["slot"], x["media"]) + s = self.slots[i] + if not s["live"] or s["live"][0] != x["previous"]: + raise Refuse("not_published") + self.may_publish(g, x["media"], x["profile"], x["layers"]) + theirs = self.current(x["previous"]) + if subject == x["previous"] or g["precedence"] <= (theirs["precedence"] if theirs else 0): + raise Refuse("takeover_not_higher") + if s["standby"] and s["standby"][0] == subject: + s["standby"] = None + s["live"] = (subject, x["profile"], x["layers"]) + self.limit() + elif kind == FAILOVER: + self.need_present(subject) + i = self.slot_of(x["slot"], x["media"]) + s = self.slots[i] + if not s["live"] or s["live"][0] != x["failed"]: + raise Refuse("not_published") + if not s["standby"] or s["standby"][0] != subject: + raise Refuse("failover_not_standby") + if x["last_seen"] > t or t - x["last_seen"] < self.d["slots"][i]["failover_ms"] * 1000: + raise Refuse("failover_early") + s["live"], s["standby"] = s["standby"], None + + +# ---------------------------------------------------------------- §6 names, §10.2 scopes + +def render(fields, name): + """MOQT §8.8: a-z, A-Z, 0-9 and _ as themselves; every other byte as . and two hex digits.""" + def one(f): + return "".join(chr(c) if (chr(c).isascii() and chr(c).isalnum()) or c == 0x5F else ".%02x" % c for c in f.encode()) + return "-".join(one(f) for f in fields) + "--" + one(name) + + +def scopes(d, g): + """§10.2, in its order.""" + room, me = d["room"].hex(), g["principal"].hex() + out = [[[0]]] + for m in (1, 2, 3): + if publishes(g, m): + out.append([[2, 6], [room, me, MEDIA[m], None]]) + for s in d["slots"]: + if s["media"] == m: + out.append([[6], [room, "_" + s["name"].decode(), MEDIA[m], None]]) + if any(g["policy"]["kinds"]): + out.append([[2, 6], [room, me, "events", None], "0"]) + if g["subscribe"]: + out.append([[3], [room]]) + for layer in range(g["max_layer"] + 1): + out.append([[4, 7, 8], [room], str(layer)]) + return out + + +# ---------------------------------------------------------------- §9 room verification + +def authority_policy(): + """live-events §5: the default bounds, every kind permitted.""" + b = b"WEP1\x01" + bitset(LEV.KINDS) + struct.pack("", file=sys.stderr) + sys.exit(2) + sys.exit(main(sys.argv[1])) diff --git a/wai/live-conformance/rooms/README.md b/wai/live-conformance/rooms/README.md new file mode 100644 index 000000000..ae2e6652f --- /dev/null +++ b/wai/live-conformance/rooms/README.md @@ -0,0 +1,94 @@ +# live-conformance/rooms — live rooms + +The corpus of [`extensions/live-rooms.md`](../../extensions/live-rooms.md) §12: rooms, each +a signed `WRD1` descriptor, its `WRG1` grants, the head of its authority's key log, and its +principals' `WEV1` chains, with the outcome a room verifier gives them; and the records of +the registered publish profiles. + +**Room equivalence.** For each vector, a conforming room verifier given its `descriptor`, +its `grants` in order, its `key_log_head` (or none) and its `chains` (each one principal's +records in stream order) reaches the outcome the vector states (§9.4): + +- `refuse`: the `reason` and where, `at`: `["descriptor"]`, `["key_log"]`, + `["grant", i]`, or `["record", c, i]` for record `i` of chain `c`; +- `gap`: no record refused, and the `gaps` (principal, first and last seq not held), under + the code `delivery_gap`, with the `room` id and the merged `order`; +- `accept`: the `room` id; every grant's digest (`grant_digests`); the merged `order` + (§9.2), each entry `[chain, record, grant]` with the digest of the grant the record was + verified under, or `null` for a room key's record; the room `state` (§9.3); the `tally` + of the room's polls (live-events §7); and, per grant, the `moqt` scopes and `reval` + interval it maps onto (§10.2). + +A verifier that reaches another outcome, reason, place, gap, digest, order, state, tally +or scope does not conform. + +**Provenance.** Generated here: `wai_live_room_vectors gen` writes every descriptor, grant, +key-log head and record from rooms authored in code, from fixed seeds. Each key is SHA-256 +of a fixed label and the principal's index, each nonce and viewer id likewise, every time +is a constant (the rooms' `t0` is 2026-10-16T00:00:00Z), and Ed25519 signing is +deterministic (RFC 8032), so the file is the same bytes on every machine. 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 (jwp-receipts §7.2) 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). +- `registered_profiles`: each profile §8.2 registers, by `name`, with its `record` (§8.1) + in hexadecimal; a verifier compares its own table with them. +- `vectors`: each with `name`, `about`, `descriptor` and `grants` (hexadecimal), + `key_log_head` (a key-log revision's JSON text, or `null`), `chains` (lists of records + in hexadecimal), `outcome`, and as above `reason`, `at`, `room`, `gaps`, + `grant_digests`, `order`, `state`, `tally` and `moqt`. + +`state` has `present` (each principal and its grant in effect, by principal), `published` +(each own track: principal, media kind, profile name, number of layers, by principal and +media code), `slots` (each slot in the descriptor's order: its live publisher, standby, +and the live publisher's precedence), `tracks` (the rendered Full Track Names of every +track a subscriber can reach, §6.1, sorted), and `timeline` (each change of a principal's +grant in effect, with its `t`). + +Vectors: + +- accepted rooms: `lesson` (a director's remote record control of a performer, an audience + under single-use grants, review and recording policies with a region pin, a key-log + head revoking a grant and a viewer the room never admits), `broadcast` (one publisher, + viewers voting, a moderator's decision, no key log, the authority its own clock), + `takeover`, `redundant_failover` and `promote_viewer`; +- `room_gap`: a chain with a record not delivered; +- one negative control per refusal, each a single defect: the descriptor truncated, with + trailing bytes, of another version, with a flipped signature bit, with a tick of 0, + with a registered profile changed, with a role beyond the ceiling, and with a recording + policy whose jitter exceeds its commit interval; the key log + missing, of another origin, re-signed wrongly, not listing the authority, and revoking + it; a grant truncated, signed by another key, of another room, permitting a lifecycle + kind, with oversized attributes, too long, beyond its role, beyond the room's ceiling, + chained to nothing, and chained to another principal's; and in the records, a bad + signature, the wrong room, a kind not in the grant, a participant's lifecycle event, + events outside a grant's window, a principal not present, a revoked grant and a + revoked viewer, a reused single-use grant, an unknown grant, another principal's grant, + a second join, the participant limit, a malformed detail, every publish refusal, every + exchange refusal, a takeover without higher precedence, both failover refusals, a + command without its power, a grant's rate and payload bounds, and a stated tally the + replay does not reach. + +## Running + +``` +cd ../../wai-rs +cargo run --no-default-features --features live_room --bin wai_live_room_vectors -- verify ../live-conformance/rooms +cargo run --no-default-features --features live_room --bin wai_live_room_vectors -- gen ../live-conformance/rooms # regenerate +cargo test --no-default-features --features live_room --test live_room +cd ../live-conformance +python3 live_rooms_verify.py rooms +``` + +`wai_live_room_vectors verify` and `tests/live_room.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 §11 to refuse a vector and §11 to list exactly the reasons the reference reports. +`live_rooms_verify.py` is the second implementation, written from the extension's text and +sharing no code with `wai-rs`: it verifies every event with `live_events_verify.py`, the +live-events corpus's own second implementation, gives every vector the same outcome, and +requires the same coverage. Pass = an exit status of 0 from each. diff --git a/wai/live-conformance/rooms/vectors.json b/wai/live-conformance/rooms/vectors.json new file mode 100644 index 000000000..898539071 --- /dev/null +++ b/wai/live-conformance/rooms/vectors.json @@ -0,0 +1,3375 @@ +{ + "corpus": "wai.live.room", + "extension": "extensions/live-rooms.md", + "principals": { + "authority": "988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285", + "relay": "c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b", + "director": "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "performer": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "viewer_a": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "viewer_b": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "viewer_c": "5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79", + "moderator": "883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada", + "host": "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "emergency": "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "encoder_a": "044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795", + "encoder_b": "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "other_authority": "8ee179553974a07b3e660a729ebd8c0bc43012e79354ac582f044f25d2365fc7", + "log_root": "687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c", + "log_next": "92547c9441ef72da73e577a10f814456bc3169be20bc35850a79d8bda9d785a7" + }, + "registered_profiles": [ + { + "name": "speech", + "record": "067370656563680101046f707573000001000000000000100000004000000080bb0000010f" + }, + { + "name": "music", + "record": "056d757369630101046f70757300000100000000000080000000fe01000080bb00000200" + }, + { + "name": "screen", + "record": "0673637265656e03020d617630312e302e30384d2e30380b617663312e36343030323802044c31543301800738040f002c010000c4090000000000000000" + }, + { + "name": "camera-720", + "record": "0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc050000000000000000" + }, + { + "name": "camera-1080", + "record": "0b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f0000000000000000" + } + ], + "vectors": [ + { + "name": "lesson", + "about": "a lesson room under a key log: a director with remote record control (record_start with a count-in, record_stop), a performer publishing music and three camera layers, an audience under single-use grants, review and recording policies with a region pin; the head revokes a grant the room never uses and a viewer it never admits", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1e0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010058000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000008000000000000000000000000000000000000000000000000000000000000008813000001011e00d0070000f4010000024445465206ed38c0fa1d613e979732b57f94008eb1a55eef62c17d4cc0519a55fcadca5149fe09675bd77e075600a154c4ed79a1b923b9d39f2bb8f88bb953bd41478908", + "grants": [ + "57524731010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b32000000000000000000000000000000000000000000000000000000000000000057455031011e0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000000f2052a01000000ffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c651300056f7264657201003203706970040074727565fd2ce563c01a20baf2bb9ec8c2b4e86e70fa1e7019e1c94982f59c206cc65f68315ae6caecc49a5cd470e2603cc2b03c473ad944970a120ea7c713b069978b08", + "57524731010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000000c817a8040000008813000000000000455552020102011568747470733a2f2f72656c61792e6578616d706c651800086665617475726564040074727565056f7264657201003198a918ba59beba431e53229c1e55458f67de9ce703bb57afae41a338dae39deb03f81566d7afb653c8f530cb20135028f73bd703ed57583620713a9e84516900", + "57524731010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000b800e0beb7f7bcaee3025c7030bf18d573ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000effac58cc7856a7d229f4c0ceffa261292f119b2a26ab4b1a902e499d4338a74cb8aa36deb46115f481c1fa98f4810835b4f30349ab32b29e9e8448eecf0000c", + "57524731010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010000009937170712f7e2551455a908dcaf29272bc3cbe6b7589efbad4b246778b6ed84574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000077782afba6a850270011e8937be6946d1e6ad50cd63660ca06e52eb31a3e6e1b0af8cfd59844e8f64a0d5a2d02fe82f6115a2d6b40e9047b80e0fc015e216c0f", + "57524731010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000f717283fd3008940414e04645a704d4fb1163b86dc0362e286c8985c28f09315574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000005774a81e60ff1d246b9cdffc8b94374ae7e6d43a416f740a2cd5924d84f8a965728aa124a907a4aa645eff2b34212900438c1beff2059dcb2946f735473806" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[\"c43e1d0afa038c2a10ca7c5be4b1bf56ab408c91e5fda8d518b06220ecda89e2\",\"8e839d3aab0dba2a233583b942ac44a9cfb53eb910e7f53d147a33f4196cbbdd\"],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"96459a75103f13d1f9d4bdbc22f8f42ab5d61ccbb4447c935bbe90f74e8e446b2b2e27c17c3ec2cd77715854924f684e7a0cbc75a6c3d6cb5ac5c9b063055707\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040001ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7afb42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a358ec9f86a4f28d7bbfa2d4bf45b674eabfb1c15dae349881c16964b27f964e32bd8bf9b9c9ede197c4318e116a246908cf2e3f4d5fd6c7edc097a8c6dc4b160b", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b010000000000000046558912df6e69241862f8a5d4ef3ec222a57ecce0c2918fc8fa0484ca94bbcc000000000000000000104000ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9ec9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3ce3061c0cd2f278db6052773d37fde0af3eb1a66480e8d4bc046d27d5dd2e6cbf05b50e84bda1bfc3fc436020e956597878ebe0340490723c36ce7718b3bb000", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000006aab6f1cb0db6b29a13ae0a9b54b7abfcbd2bbca6c5c1c11eef03e7adb7c60be20a107000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6cdd3ae89f65c6b929a897c4158e411e7245dc1bcf2ba1d1392d8cb04e01f8a4ded66c609de04c8e8aa1bd483e896f56dc641d0953e77a7f3dbc11a13818f8106", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000271c74030bba0d8ed6561c7ff26c09ff03dd6ad35219c39069a7af6b8d58e9dcc02709000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb035d9546c8fdcffa822fe69a3cb31d8646213891bf1fc88c0acb3b4846fe4a1a92142f0d3ff6c338ea1b2b749b350793fc5589aaeb0ff0283c49041df119e1f245af87b9594d1f980bc74bdf5a8a62156742e606f8bcd5db9f789e491e85dc04", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0400000000000000c3f2416d68a4afad4f09e480e732e134246e63851a52c555fb08121fdd6bee5940420f000000000000122400ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e00010101e3957a1d5ea500ed1e2df399b00bed21e0feaeac0ea62f647ecf99c42b3627ab1b400faf15eb48fa510788b69857d3d1fbc5a18033229ea868fa3be7802af806", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0500000000000000263a6af4fc6d64e9723a32544a12932c7457e4b4b91e98ed5cbc4a595fdec7e140420f000000000000122400ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e00020203fa60cd877e575babb0187d053ba2fd4b29b7b61067ac7b67ac15b5c562c789c80dfc66401922bc01b0aaff20bcee78bc3f80c9bcedb042c73b44c16eafdc5106", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b060000000000000098b09786432e808f827d38a9a75038eb2b843b178b266484276dec97fcd1991740420f0000000000001224001ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af00010001039d5c1a5c20f30a929c0d0bac0dbe6b059fb97a61974b648928a80d2d1206378ebf63e5807b854fa4a9375960587dc5ad69478f381ba2bbf06b2d564cd16f0c", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0700000000000000105398e06cb758b86e8fb7babdc1e7df6905b43a68f0bd76a4c90307d8ec31e1001bb7000000000000112100f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb0141b4c947f7bcece4813efaf280ee2ad20bc23ac7774683cb7936d9f2f2b9c5ca20af4d923dfea05dac4f45559780609eb3a8dfa6004d5964740bd1a1515ba905" + ], + [ + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e01a00f00003a6368807f92c2af31ce94137bed241ed38b014138893cb49c8ab55cbb71a4db1f134dff9215486ffbe9408d0a77f948187c84d059508d870247de4bf8c3e10a", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af0100000000000000daf685437c8e5f30f05a1ab2e72bc9e7b4442c01e6d941fd8991824cb383fd3240548900000000000008150002000000020d007275736865642062617220313200479419d5cba80e86dc7d447c04302416f25bf219c76181aa1ec7c80b05c49f8b6e3258819850a7204d2ea4d16eefa4320c8e13e7b4647a6a0f9e897871b2630b", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af0200000000000000d8adf33701f9ae552264c949967267d3b1c043c91adfb6c6d470b362ea740dea809698000000000000092100ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e0290f6b613354a2504b0f700ff888d7b0504577789d7fb8acdc0fe778b8e952819f83b70638cd054c73c06fef012bb717110951443e442e050b573470c06b8240b", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af0300000000000000bc50ac82af16b8d848293d3b2ea2a3e6ca95c6bfbcd04ee5aaefbfdd02098cc9c0d8a70000000000000312001000616761696e2066726f6d20626172203989df68b94b71aae7d6b7ed970bae51d80d68f491730ce198192985bdb442f62a3fe3b1cb2477d95038572e84f6ca521c71c0c254b62bcb259b22c58e3eeb0f05" + ], + [ + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000a0252600000000000003140012007265616479207768656e20796f75206172657a9f8532ebd8b6ad19af49dfc88adc7ca9ed3c6d0e050b0d77c6a32faad64a76964bc0edb98d378f8151aede47e4a993352457daf113b1c52b028dfc468f4305" + ], + [ + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e00000000000000000000000000000000000000000000000000000000000000000000000000000000808d5b0000000000000c2800e020187d15e3819eda5e20e955f3d07ab1b1fdbfe643d2ec8a8ea717806a198c0000000000000000ebc61c13a751a2a14c7e999ed0b05286ce2206a939aac2c736e09be5496e12626005ae9a52726b47368af4d39ae91300df97b5e0812f761275ac5b355fbcf00f", + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e0100000000000000febad8e9f4ef7eeea09338f4d746597c490e80ba884ea65eef5e22ee8a7dd17c00127a0000000000000c28009093065ca95615f6dc6a914f67e9aca40d244894ce2ea1111cd0744cc9b35462010101010101010184df42539d2b01d947f47ea777f2e936b19e708b0b93af48a069d9d30c1a8f92a4ac4ef57973099938afd9ea913fa185043494e318384c3df42e2277f280f201" + ], + [ + "57455631010b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384bf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000a037a00000000000000404000401000065af889198beaf2bc9a0bc1ebebb0c233dc60622e2be73b0c7c41dd6ee05944a4d9fc7e2193808242558708e32c30c4ef23a84f3e858b4b9f3deec8cb3d7d503" + ] + ], + "outcome": "accept", + "room": "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "grant_digests": [ + "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3", + "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3", + "1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6", + "035d9546c8fdcffa822fe69a3cb31d8646213891bf1fc88c0acb3b4846fe4a1a", + "c43e1d0afa038c2a10ca7c5be4b1bf56ab408c91e5fda8d518b06220ecda89e2" + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 0, + 2, + null + ], + [ + 0, + 3, + null + ], + [ + 0, + 4, + null + ], + [ + 0, + 5, + null + ], + [ + 0, + 6, + null + ], + [ + 1, + 0, + "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3" + ], + [ + 2, + 0, + "1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6" + ], + [ + 3, + 0, + "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3" + ], + [ + 3, + 1, + "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3" + ], + [ + 1, + 1, + "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3" + ], + [ + 1, + 2, + "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3" + ], + [ + 4, + 0, + "035d9546c8fdcffa822fe69a3cb31d8646213891bf1fc88c0acb3b4846fe4a1a" + ], + [ + 1, + 3, + "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3" + ], + [ + 0, + 7, + null + ] + ], + "state": { + "present": [ + { + "principal": "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "grant": "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3" + }, + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "grant": "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3" + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6" + } + ], + "published": [ + { + "principal": "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "media": "audio", + "profile": "speech", + "layers": 1 + }, + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "media": "audio", + "profile": "music", + "layers": 1 + }, + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "media": "video", + "profile": "camera-1080", + "layers": 3 + } + ], + "slots": [], + "tracks": [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b-1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af-audio--0", + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b-ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e-audio--0", + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b-ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e-video--0", + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b-ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e-video--1", + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b-ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e-video--2" + ], + "timeline": [ + { + "principal": "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "grant": "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3", + "t": 0 + }, + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "grant": "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3", + "t": 0 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6", + "t": 500000 + }, + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "grant": "035d9546c8fdcffa822fe69a3cb31d8646213891bf1fc88c0acb3b4846fe4a1a", + "t": 600000 + } + ] + }, + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "moqt": [ + { + "grant": "b42f9cd478eafb3122efd0bca16746e00924722cd85a42ec10ab414cc10f59a3", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "1ab7d0ea380a97e54a8815a66380ef19c66010c2c78285186d6342b0a954f7af", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "1" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "2" + ] + ] + }, + { + "grant": "c9572d2b23648824de14dd5a375fb5cf305db9474b338f754c4b76cbb9de68e3", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "video", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "1" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "2" + ] + ] + }, + { + "grant": "1e86384f6141b38d5a34f34e0dc80d0bfeed4a1adc8c7eeb38bb357196587eb6", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "1" + ] + ] + }, + { + "grant": "035d9546c8fdcffa822fe69a3cb31d8646213891bf1fc88c0acb3b4846fe4a1a", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "0" + ] + ] + }, + { + "grant": "c43e1d0afa038c2a10ca7c5be4b1bf56ab408c91e5fda8d518b06220ecda89e2", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b", + "5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "0b924dbd5a430d6f8c613eba87e18f0eb88a481f3d858a9cd6ebc75242c7384b" + ], + "1" + ] + ] + } + ] + }, + { + "name": "broadcast", + "about": "a broadcast room with no key log, its authority its own clock: one publisher, three viewers voting in a poll, a moderator's deny decision, a viewer removed; one publisher at most", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928500406cd8e95d060040420f00000000000000400000000100000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010058000000000000000000000000000000000000000000000000000000000000000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fc12b0170258ce87d6cb935ee8a52798affdabc2bd42448afc1968074e487077eff3418a97c7cfcdca12b2d77529910d94b8ddc4c4e6a06d0e4eae8cfa97102", + "grants": [ + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000a8177e3c0539f41e6c9b83d40829e2f307edfffb32550ecd60e3bd4b821dda5ac91ec5c8b19188a730ea0f0eb411f512dd8c03128dd53236be6a5aa21db0d304", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000100010001000000000000000000000000000000000000000000000000000000000000000000574550310108080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000a4938ff4b55bea84315bb0e0ac10830619d2ff4181e1d6c95205d06f268ad4d1fef18371ea65d03fc0d08f5713baf79e86d7b9dddeda6dacf7892c842fef890e", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000cc0a03dbb739fbb3b2930097a0f3dedf61cba97ac6dd361a74b7a2fcdea4729653c62254df2b637199019827f0d985af00e3b4ab41dc22684878694a9ab80a0c", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000152f73f95b4fb60a5af17e64975f4de00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000c3751b7e6f106c5217ab43900a588947c6ac45b587573e1592b853636310d3cd171cb873976a127c6f50087b73c80c5792012f49f0fef49efeae4d29e556d807", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000002000101000072597590e28f1de5efc0048fc10eb95f00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500008f113eb273113603940999be642873342c9d74ee026e49c969bec9489d9d8c7aa1f1faf71e0f9a4c50e906edb798f24e418f5bd98195ef5ae66201f337811900" + ], + "key_log_head": null, + "chains": [ + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa15d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f891af1afcff9b556903f0c6b499602117af5b5928d85e08ce769141ba2797bba90802b3f2f1692843f65a7c713d5ce9a877963f451d49d5930de8e0830f7795600", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c285892850100000000000000f158f677824cfdca96097265650b71d22f545f06f17e3ecc1bd01aa21024d31d000000000000000000104000883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaadac8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad113093fd51f4f400fae119c0e96bc46ffee12be5621360a0ba35bdcad51169bfdf77f14a686e7185358767342c40ac67a5e5c0fb7ee0981567d2b62fbaae16584103", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928502000000000000001d940a3fdc07acde1c678221e7804212137b215bee7c8cc45b405084668cbfff0000000000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100020102d2c3573ecd1a131d24e5e96aae6716f01d54ea6333d78fd336803724d614e1bdb5441f0005a570ad35519bf26ffd1f0ad14ad2815d1eebc3e83f765fd8dc6800", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928503000000000000003edea9bbb0af157e6a776ee6b12e6fee85295e59695dd6268e1602b34d7641c00000000000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100010001f0592a14651a7062642eaf28e333047c88f94a04bf163a0b58fb26b7ba6585f7c8d4493ebdb50c2f3184dc0af223e4efe4516ff22100e3fb7b5d151c7e8dfc05", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928504000000000000001e7bc9c01087c27c8c8737f6d25b3d7a02c8aa405fc83923dd2e0162d9c9fb1840420f000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454b56f039e77cbb6df56beedf741cb136430512c904d980460da259b257fee59a879f5c6b4eea6a252ff2503e324718e2feb728cd439533a351c371f49e1101105", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928505000000000000008c97279bda2646acdbf7c5de17a1f22dd6d83824a00a73ff918e44011da47367e0c810000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fdf84081bf4a470f9c6974012bc665103946c471159790d27a79388f5e7a4e13b8c03dd950a9af79b4b67bb27e850e1df13e81382bb8504a409a39116b9a64be0a", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928506000000000000006da7009e67c115f4e28f5cbaedd9b3e6a08dab41bf35d32cf06af080d6e63d0b804f120000000000001040005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65f6bad9885b3fbc86637f4c8fa3ddfc89b0fdd1acfc7a3fe236e3e6bcbf3eab3746c495bb15c2f2ce9413bf1f2bcf7bed791ab08b2c1a60657e132711ec135706", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928507000000000000004f69921d5414af2b4a51e770a438cc57755ff2f15cb479519ff01a85f77ea7d300127a0000000000001121005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79021d4d984f0d3e652c3649a1bf325c294cb6b4b2c76124d58bdd17491ad7ec19f0f9c924666da93807ba393a0f5ae4f79b136d1bc740b2c0e117ae72d79731fb09" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2000b80b00000102656e160057656c636f6d6520746f207468652073747265616d2eb4cd653cde10a2e448aae06f3a43da32735e8c459100ed497298b7c19dc765f45252d29db4e12a7c0b3cb50f33a93f0ff7d9349ef37ca63244b6d34bfb920805", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa101000000000000003995329f6b1a78e490d75080148e2cf01f27350c7c51e7488cd479955b854ab2c0c62d0000000000000520000b004e65787420746f7069633f020700546f6f6c696e670700526f61646d6170914b002faec41374b4e47dc03996a05ed2bc8db3dc59fd2792b860faad894de4cae4f8f5b7252554739c5e8c441b5f4d64d17f7c713e35e3d156b5445c490204", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10200000000000000c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace614c0cf6a000000000000072900c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61402010000000200000076f8e77544c4b5992508592aec062c4f8d8269fd436c91e73c947e750fbde52122865e76a7ccd5090e816b764806447aeca8f1177a0c8e7b54259c6f48a3dd04" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000000093d000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61401e3b6f361a978bc5704db480d4e18adeff11123102fd8a6c785ce6d5ebbab5dc88331280a540c29d024963b93c035149ffd5ed59e9a1a64fc1225edbc62ada408", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0100000000000000582c0158a99a98f6a7d4ff0061f897d7a6584747f7f74208e22b9290cdacd68b808d5b00000000000004040004010000d48e1a78461dd62b4fbdd875a118213ea84e248810e6a6e52580e6af3f0687f7408577d4c20e0b62dcca593bdf5418cb73256c3f4a6956c64edbd0b588b8fe09" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000a08f3e000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace6140111929c98d6472261488c63ce55eb9823bab1c74fe0c0fe31be9e804742e973887194775afc315655a76f9c85d53258140a30db55ae66f2fb54c1523d44a81103" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000401640000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61400a5e21f57a0a23b5d6679af935614c7eeaff52e8188b9a6f434bb20abd314ab75623cdb4fa9ed76e47353717dabbfb475dd16c389cf81250cc96c48ca1ac4c200", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79010000000000000034db1268f014b0b6314982afc0ef6852c16a63298bc73a97ece67d37cbf57cc9404b4c0000000000000325002300666972737421212120666f6c6c6f7720746865206c696e6b20696e206d79206e616d65e52e03724395f2683ed61f939c193235a53dc9f255bd2466456e51b6e943ab957023fd64ad22f9c41510aa733a786daeea32a076c4dfbba691abbbd427b6620d" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada0000000000000000000000000000000000000000000000000000000000000000000000000000000060ec530000000000000b23000244f68aa32c596f08b991e26fd58c501e1d391bdee00d7cc7d79502558888a19a030045537bdf38737b91e221cc208fa0ca82bdf8decc6bf99aed27feea0812a23ac348a82bd7a96dbc54c2e73d64f89d2e2521326925f652ab0310d7129b58cdfb09" + ] + ], + "outcome": "accept", + "room": "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "grant_digests": [ + "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89", + "c8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad1130", + "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454", + "4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fd", + "ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65" + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 0, + 2, + null + ], + [ + 0, + 3, + null + ], + [ + 0, + 4, + null + ], + [ + 0, + 5, + null + ], + [ + 0, + 6, + null + ], + [ + 1, + 0, + "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89" + ], + [ + 1, + 1, + "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89" + ], + [ + 2, + 0, + "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454" + ], + [ + 3, + 0, + "4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fd" + ], + [ + 4, + 0, + "ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65" + ], + [ + 4, + 1, + "ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65" + ], + [ + 5, + 0, + "c8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad1130" + ], + [ + 2, + 1, + "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454" + ], + [ + 1, + 2, + "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89" + ], + [ + 0, + 7, + null + ] + ], + "state": { + "present": [ + { + "principal": "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "grant": "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89" + }, + { + "principal": "883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada", + "grant": "c8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad1130" + }, + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "grant": "4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fd" + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454" + } + ], + "published": [ + { + "principal": "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "media": "audio", + "profile": "speech", + "layers": 1 + }, + { + "principal": "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "media": "video", + "profile": "camera-720", + "layers": 2 + } + ], + "slots": [], + "tracks": [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb-2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1-audio--0", + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb-2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1-video--0", + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb-2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1-video--1" + ], + "timeline": [ + { + "principal": "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "grant": "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89", + "t": 0 + }, + { + "principal": "883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada", + "grant": "c8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad1130", + "t": 0 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454", + "t": 1000000 + }, + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "grant": "4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fd", + "t": 1100000 + }, + { + "principal": "5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79", + "grant": "ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65", + "t": 1200000 + } + ] + }, + "tally": { + "state_hash": "2f4962452064a71ee46b9775f0b59470a1a0a704a330b0ee25ecac822db99aab", + "polls": [ + { + "poll": "c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace614", + "open": false, + "counts": [ + 1, + 2 + ] + } + ] + }, + "moqt": [ + { + "grant": "5d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f89", + "reval": 0, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "video", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "screen", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "1" + ] + ] + }, + { + "grant": "c8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad1130", + "reval": 0, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "0" + ] + ] + }, + { + "grant": "595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454", + "reval": 0, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "1" + ] + ] + }, + { + "grant": "4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fd", + "reval": 0, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "1" + ] + ] + }, + { + "grant": "ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65", + "reval": 0, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb", + "5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "3a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb" + ], + "1" + ] + ] + } + ] + }, + { + "name": "takeover", + "about": "a feed of precedence 200 takes the stage slot over from a performer of precedence 10: the slot's subscribers keep their subscription and the publisher behind it changes (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000002002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000309706572666f726d657203010200181100000000000000000000000000000000000000000000000000000000000004686f737407010102ae060000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000001057374616765020100000000010a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7d309370da847d258a12a1b25bdfd262652051fb7ebaa27e8a324f52f75179d4712321e5c3836a4b298773fc09599ee08e33b3224f6a9e0cd01d7d803910202", + "grants": [ + "57524731017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000030102000a0000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000b1c8f431665e34d2c3879eb18c27294cbc4f0b8cfa7a3b134cdf31d76234a6113bd6a6ef8ead59d2b39abdc85c758f1d0ede024a8b2f4552256dcd51df67b208", + "57524731017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf13c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000107010102c800000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c65000083dc29d6f6df371a3ba19fe120b066c50924b8458884b5f9d8bc0c4e1ad5779890404ec159ae2482109cf666ef30ea5a1cac66d671a2a8196a04c93a97977109", + "57524731017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000ca0aeddbade722ec2e4d076636a1c09e90e9f0d8a2c0fc60b356142f6f295955cde68c0486965385dfb3534694933d4421d952dc0844ea5973a939c80ca9840e" + ], + "key_log_head": null, + "chains": [ + [ + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e3a83f68f0efedeb9ed22ef252574bc7fb60682dd5b77f0b28d85cbe0bdc4c9b6851e99d24f6f3630cf7db3538fe6b33f893affa876fda8fa78939daddc5ad5ed616e01179498b1503aaab36302ae9cd4206af975075f92870f7af61164a67c07", + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b010000000000000005c5560effbf42fe9283222534f7962f6b950848fdb7dd0bcbfc358b184ef0ce0000000000000000001040003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d2492513beb235cd96f34e45781bdd8a8c25b6e41a88a87cb3d554aeadc963b25b8dacc24f3164c993e690d6dfc96944d12e2db33dab00b25dc7bd0acb0bd1f890d", + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0200000000000000bf9a397cbeda9cac12745cd39860759a8af897ff50c979a3a2004843581e2794000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392b474c45821d709115e5e799fe6874fec72e115df9c7dcc7ed47d463d4d094bda61cf2ea3dcfd72e550af1eb580e4700cf275c2dd24fd63c282a0b674c5ee600d", + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000abc656b63dd81029f6d2dcbe7918a3bb729e415b7dea66221c5391cfd426006a40420f000000000000122900ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e05737461676502000273403b199cf87d3df0828ecec9d4beed07e9be90603877a4b514a5f832e45e5d0998a53e5d9e8503f23c255986a8f128f35d1a2ec3b7370ea733b6df35d3c806", + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b040000000000000060d319ba7db548d5e8fd86bff6edec24e9da34498f8e913611c0b35a5465897a80c3c90100000000001549003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af057374616765020001ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e28234b6e19984dabfb65aa05e9aa79fe8443944cffd60c75d3f623554f57cdad7b77f6ee86ff8c9862531c6375f4514364a0583ff86d74762a852beefb6ff80f" + ], + [ + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000030e000c00736f756e6473206772656174b7c8c15335330d07de448d27ff8082dcc4324a1f65e85b42474690da800fcbd3ac8ad170dc41441ec965de489fa5ec89f7201882932e47dc313b1cbb614e9005", + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0100000000000000f44df1375aa47dc5e52230df143d5cf20f7ea016130489b4d136498db6aebfd8005a620200000000000310000e00776861742068617070656e65643f95f688f0ccb91cef52b5d8ba52c9625dc2ff4da2ca93c7041107046101ddb536f4f5ff89acf5c7fe6a613909d672ea561b5a50c9dadae1f080d8547ab176280b" + ], + [ + "57455631017cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf13c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00000000000000000000000000000000000000000000000000000000000000000000000000000000c005d9010000000000020a00040700000060ea000000435cb0fa47b171b6b99dcbbea0d3ea2de0367528e9adeb83d0dea329d9de84f7df508fb96d76efbaad09cff2e264cfae12872e2885e5eb01da289829b6538405" + ] + ], + "outcome": "accept", + "room": "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "grant_digests": [ + "3a83f68f0efedeb9ed22ef252574bc7fb60682dd5b77f0b28d85cbe0bdc4c9b6", + "2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d24", + "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392" + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 0, + 2, + null + ], + [ + 0, + 3, + null + ], + [ + 1, + 0, + "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392" + ], + [ + 0, + 4, + null + ], + [ + 2, + 0, + "2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d24" + ], + [ + 1, + 1, + "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392" + ] + ], + "state": { + "present": [ + { + "principal": "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "grant": "2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d24" + }, + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "grant": "3a83f68f0efedeb9ed22ef252574bc7fb60682dd5b77f0b28d85cbe0bdc4c9b6" + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392" + } + ], + "published": [], + "slots": [ + { + "slot": "stage", + "media": "video", + "live": "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "standby": null, + "precedence": 200 + } + ], + "tracks": [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1-_stage-video--0" + ], + "timeline": [ + { + "principal": "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "grant": "3a83f68f0efedeb9ed22ef252574bc7fb60682dd5b77f0b28d85cbe0bdc4c9b6", + "t": 0 + }, + { + "principal": "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "grant": "2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d24", + "t": 0 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392", + "t": 0 + } + ] + }, + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "moqt": [ + { + "grant": "3a83f68f0efedeb9ed22ef252574bc7fb60682dd5b77f0b28d85cbe0bdc4c9b6", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "video", + null + ] + ], + [ + [ + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "_stage", + "video", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "ef6d6823350d74efcc4375e1e30023e0f4cb51920fff4b7f55a2ef7932047c9e", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "1" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "2" + ] + ] + }, + { + "grant": "2642724ba54b0d20afc5b8fb1d20723691b6dd5db5002ff0ec97ae84526d3d24", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "video", + null + ] + ], + [ + [ + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "_stage", + "video", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "screen", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "3c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "1" + ] + ] + }, + { + "grant": "93d0a6e6b8cc6057d9cc605cd9cd251cc91521160595b03bc81289f5057be392", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "7cc143d5b2301c9fa0b025fb66e8a41aa7e0e3b4e1db5a2143e5fbdf3a0b1bf1" + ], + "1" + ] + ] + } + ] + }, + { + "name": "redundant_failover", + "about": "two encoders bound to the main slot, the second on standby; the first stops, and 2.5 s later, past the slot's 2 s failover rule, the standby goes live (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000002002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000207656e636f6465720300000000000000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000001046d61696e0202d0070000010a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041620710411a0b9d178a58d6bab143c23fbac78b73f2062186681d0033fc2b098dafaef536f6c5e20cbb99c3703b302495ad10f7983b29d8faadbb7843dc7e0d", + "grants": [ + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd379500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c6500001fdeebaf20a2b4ab8d8037c43b1cd7fb13ee82c6ed70e896a1684d65421991f66110c01d87eec63262d1f5e16c882da656aa3e68bdabcc753073539c60c8470e", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a618fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6f97764c450682f5481c88cb661dcd9c7e863284f0117b17c912b6d402d8819ba93c08ce59d3242e1681e3a3988a637473c0bbb25bcefe6765738d1b9b73c04", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000100010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000636effc39ee2cbc9e819667284ad5e19aebe1e2eed7404524c0dab993d40c3f6184b26e069073b69fd267a65bba5da87a3d19231d0cafebb459386f12de89b0e" + ], + "key_log_head": null, + "chains": [ + [ + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db1225f40e324a812151fd4327b5c8b90d4ae52004b0900373fd6c2cf81c91326baf72ce5e8ed73748cbbb4b7e5e1024ee97ae425126800222829e27a1c53da13fb09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b01000000000000004f6fda73892a28e3b9be7f9a9a1911f0401c6f1bca4e51afb11281cd137ffd2700000000000000000010400018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129609c30052eca319ca85969175cc1f4d5dbfbb0807bfe5dc5d0f41c74920f994d0ca0a2f71f9b89e7ac6700adb72cf9bf27d9d3fa3cbefe293d7beec49334590c", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b020000000000000011027901a4fcaf11a3d622711d7fa0c172bb305c04125a5f0d436ae8e3cf1512000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09cb6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf97d69d358f89f6fe8814009953037952151088139e62f112162f737bb7956f0f287523a15e7733559cce283ed3cd6791785dc52e55bb4fc6059f3ff730689708", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000cd88570dc4d10384920b2b73d467500a22ea0ef34049623729a3001ccdb3aa7840420f000000000000122800044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795046d61696e020002af63a3eedecd1076f4491a56fc3b8dfddeca2d840e4065a4344f77076a58f0c2188f52f21bc63172fee32ff7d49f2073e96b3af8df43a352312ec2260b690c09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000004eeb163a7d1888e4af7d2a3b338e34473e740f7b45c0eba0045f9dc11bcf359d804f1200000000000012280018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3046d61696e020002402a836f4c34fa58b98f2f7844ffe6efdfd308a2355267a209f8e7f20dc5232a76920b8dfa70b43df306e13850b81791db6c7e6b52a9e47ab24f5f678fe81106", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b05000000000000001512f0cd1729e8fe875fafa15f81f9c8e5da7fa02af3aa91fe19ab2e24f9a810002d31010000000000164e0018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3046d61696e02044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd379560070b010000000090260fd79e2127eb2d803fccf4c7dd435cdfdbc9403be6675d39b5ee7a1d762ba9d4f57ae40cd9ce682424a75b78fa06b24ffd2041d2e9de754af852b5802100" + ], + [ + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000406f400100000000000311000f0070696374757265206973206261636b0dddc8f36961f12312fa1d4b933d592e056bc8e21bdf340c0e19092302e60a0efcff182e1e14a689e6503ab3bcfe4ccc6d7960145baca31ac0194bc242dbff04" + ] + ], + "outcome": "accept", + "room": "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "grant_digests": [ + "b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db122", + "beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129", + "b6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf" + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 0, + 2, + null + ], + [ + 0, + 3, + null + ], + [ + 0, + 4, + null + ], + [ + 0, + 5, + null + ], + [ + 1, + 0, + "b6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf" + ] + ], + "state": { + "present": [ + { + "principal": "044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795", + "grant": "b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db122" + }, + { + "principal": "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "grant": "beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129" + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "b6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf" + } + ], + "published": [], + "slots": [ + { + "slot": "main", + "media": "video", + "live": "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "standby": null, + "precedence": 0 + } + ], + "tracks": [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6-_main-video--0", + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6-_main-video--1" + ], + "timeline": [ + { + "principal": "044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795", + "grant": "b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db122", + "t": 0 + }, + { + "principal": "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "grant": "beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129", + "t": 0 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "b6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf", + "t": 0 + } + ] + }, + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "moqt": [ + { + "grant": "b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db122", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795", + "video", + null + ] + ], + [ + [ + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "_main", + "video", + null + ] + ] + ] + }, + { + "grant": "beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "18fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3", + "video", + null + ] + ], + [ + [ + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "_main", + "video", + null + ] + ] + ] + }, + { + "grant": "b6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "75dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6" + ], + "1" + ] + ] + } + ] + }, + { + "name": "promote_viewer", + "about": "a viewer's audience grant exchanged at the 10 s tick for a guest grant chained to it: before, it may chat only; after, it publishes audio and video and sends a marker (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000004002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000020861756469656e63650001010058000000000000000000000000000000000000000000000000000000000000000567756573740301010058010000000000000000000000000000000000000000000000000000000000000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085fb1648fb4eadd58c012187878f0899377d781ad07e5a0bdeb3d8fa86b496b65b76827cd48db71108d5570e71c5fa74c70ecb924ec456dc168821e2d0fbbc07", + "grants": [ + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000000010100002cd16a698a000309187ab311e3e43dbc00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000ce085371b034d09a584e9cb79a303e485b95de64310c000c2e8bff420bbb7d74ddc40b22b59338b2d3f4884ace0299dedce4c2d2bb8b7b038899240ffd11e30a", + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ff13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000000010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000b0f65165b661d2ab1a091eae01d3f7b246eff39d5aee83c159bfad742a7d60464379db288f5c62bf7f2bbcfbe86fdc7d005354b15a595eee47fa31788f445905", + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b49718096980000000000f05ad16a0000000080bad26a000000000103010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650900056f72646572010033382f12ddf501732ec766e2b6b1ba2d09fb91475d60d30953dca6709165a1d23550588a348eab2382103e3af643aedefeae49a391236fba30f38a8426a897a706" + ], + "key_log_head": null, + "chains": [ + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971fb49f7d7cc837cb03ee191a021a5ee2337761f674a8ae3f27c2249d008c78e4f534d1c74e4814cf4361a854c1b7e282b510ac6e2169ca1a1061200647de2c40b", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b01000000000000001bb56ec23163b62835b49adf3dd1fe477c2cbf67b532f6b1965198212601d605000000000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfba9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7e001fb31827342ab85d532613c2de7b597b8ea4fa1dc150b91d33eab0e0523074c6397229087e7d722eedecd320fe9e0f6bf797995cdfb1b22f4873ef6457f01", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0200000000000000c69fe25e3866367da71f3ca32bc5a4b63d45f3eba848d05b4575b9d76c9a573f809698000000000000146000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed749c31da1cfbe4ea630b46f363d34540e2cbfb50ac66717bf85adb3bdff28afdfcb9ad1858cd046fd1c81ee99d9611e595260bc8d3503101c5091af2f07c200e", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000dce5f901d8cca15e87487e6d124c21aa9bb68b4204eb32d401efddbb5a2e42f9c0d8a7000000000000122400fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00010001d19389a3e404ad77aff1a855d0bfe346958615afc08efd9aa112929a4b40bb19b27218b0d1a0d9f95df011d02a5feddd28268841e722c9d65d5b6f6d6313f40b", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000000a908ed68b4f7beb444ac69ba5aaaf4bbba9b9b63cea415a083f912cc946b2edc0d8a7000000000000122400fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c000201027c09ef31e47df5dbd804b0ace65cd12a66b0163f0186a4dcf936f86242e23a678cc40c8813de8a3158a90500f922e13c9cc6520aab58a478f32e45c965de8d0f" + ], + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000031700150063616e20492061736b2061207175657374696f6e3f36a82863e7a3c1860708454d8cf4db6180b0635b9bda3c7b821ab2005131fcde2781e3787046644e9c396c2a558b42761c335d9981a683a501d16a66a310eb0d", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c010000000000000038a761fb4c8f8fe395353ea95aaea155b41a6f8484ccf2f0e80d1fee6b89a45f001bb7000000000000081000010000000108007175657374696f6e00c186e2a7d871b4b00e6442bb4acf944f7e27909bd43cb46c188ceb151fdee0c9bb5f775a72641101b3f4b9f2b676587f878d8a701c1e6d052e1850ca34fbd50b" + ], + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ff13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000001bb7000000000000040400040100004d20e1e4bc77f9e260a28433467e8091af091bbc46e6e8ed5f172e11ae532d8adca0ae959f5076b801c987d7d97a3dbfc743a7ceeb4099da914fa1b3cfe22208" + ] + ], + "outcome": "accept", + "room": "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "grant_digests": [ + "063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971", + "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7", + "a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed" + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 1, + 0, + "063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971" + ], + [ + 0, + 2, + null + ], + [ + 0, + 3, + null + ], + [ + 0, + 4, + null + ], + [ + 1, + 1, + "a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed" + ], + [ + 2, + 0, + "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7" + ] + ], + "state": { + "present": [ + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "grant": "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7" + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed" + } + ], + "published": [ + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "media": "audio", + "profile": "speech", + "layers": 1 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "media": "video", + "profile": "camera-720", + "layers": 2 + } + ], + "slots": [], + "tracks": [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f-fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c-audio--0", + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f-fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c-video--0", + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f-fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c-video--1" + ], + "timeline": [ + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971", + "t": 0 + }, + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "grant": "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7", + "t": 0 + }, + { + "principal": "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "grant": "a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed", + "t": 10000000 + } + ] + }, + "tally": { + "state_hash": "771b30268d4b5a93046d9e87dbbc10bae6fc76c4c2d5dde9071f801bfdb9a68d", + "polls": [] + }, + "moqt": [ + { + "grant": "063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "1" + ] + ] + }, + { + "grant": "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "1" + ] + ] + }, + { + "grant": "a71e15d272c944bc492f928feffd4cc621ef71fb2a11d2b6351e9393819729ed", + "reval": 300, + "scopes": [ + [ + [ + 0 + ] + ], + [ + [ + 2, + 6 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "audio", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "video", + null + ] + ], + [ + [ + 2, + 6 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c", + "events", + null + ], + "0" + ], + [ + [ + 3 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ] + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "0" + ], + [ + [ + 4, + 7, + 8 + ], + [ + "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f" + ], + "1" + ] + ] + } + ] + }, + { + "name": "room_gap", + "about": "a viewer's chain whose record seq 1 was not delivered: a delivery gap the room reports, not a refusal (§9.4)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000004002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000020861756469656e63650001010058000000000000000000000000000000000000000000000000000000000000000567756573740301010058010000000000000000000000000000000000000000000000000000000000000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085fb1648fb4eadd58c012187878f0899377d781ad07e5a0bdeb3d8fa86b496b65b76827cd48db71108d5570e71c5fa74c70ecb924ec456dc168821e2d0fbbc07", + "grants": [ + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000000010100002cd16a698a000309187ab311e3e43dbc00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000ce085371b034d09a584e9cb79a303e485b95de64310c000c2e8bff420bbb7d74ddc40b22b59338b2d3f4884ace0299dedce4c2d2bb8b7b038899240ffd11e30a", + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ff13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000000010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000b0f65165b661d2ab1a091eae01d3f7b246eff39d5aee83c159bfad742a7d60464379db288f5c62bf7f2bbcfbe86fdc7d005354b15a595eee47fa31788f445905", + "5752473101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b49718096980000000000f05ad16a0000000080bad26a000000000103010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650900056f72646572010033382f12ddf501732ec766e2b6b1ba2d09fb91475d60d30953dca6709165a1d23550588a348eab2382103e3af643aedefeae49a391236fba30f38a8426a897a706" + ], + "key_log_head": null, + "chains": [ + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971fb49f7d7cc837cb03ee191a021a5ee2337761f674a8ae3f27c2249d008c78e4f534d1c74e4814cf4361a854c1b7e282b510ac6e2169ca1a1061200647de2c40b", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7fc73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b01000000000000001bb56ec23163b62835b49adf3dd1fe477c2cbf67b532f6b1965198212601d605000000000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfba9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7e001fb31827342ab85d532613c2de7b597b8ea4fa1dc150b91d33eab0e0523074c6397229087e7d722eedecd320fe9e0f6bf797995cdfb1b22f4873ef6457f01" + ], + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000031700150063616e20492061736b2061207175657374696f6e3f36a82863e7a3c1860708454d8cf4db6180b0635b9bda3c7b821ab2005131fcde2781e3787046644e9c396c2a558b42761c335d9981a683a501d16a66a310eb0d" + ], + [ + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ff13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000c0c62d00000000000003050003006f6e659f59540c5bdf7b49adca7e94e2932cab7615e5205369a4221248911bd952e107ef2dc7b5cb18aff0ba368cd3c93901273588d929eba1f7b6e00067ec8bbe700d", + "5745563101c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7ff13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb02000000000000005cf4bc6412eb8ad1c29d366a148e43eb4c20ad04d948e7e59f64c08a2639b83f404b4c000000000000030700050074687265658ac9df9c9e3fc5d7d35e288e2efb61ce66df881bf09dbadc7b258188a1ca7c61ed2d5f5e3a0c4608a442286d19e2012fd9791bf6802fa9f42828b5f7782a2c08" + ] + ], + "outcome": "gap", + "reason": "delivery_gap", + "room": "c3d472daea41aff215909683792757bb88e95c0885382f987fbe27682f6e4f7f", + "gaps": [ + { + "principal": "f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb", + "first": 1, + "last": 1 + } + ], + "order": [ + [ + 0, + 0, + null + ], + [ + 0, + 1, + null + ], + [ + 1, + 0, + "063953f01aa48c3a682aa5edd52cc28a46e3c299b71c892d72b7cf4f575b4971" + ], + [ + 2, + 0, + "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7" + ], + [ + 2, + 1, + "a9bf151f689aab582c481fd84fb67e00598438c55f0bd556949ef3690736e0d7" + ] + ] + }, + { + "name": "descriptor_truncated", + "about": "the descriptor without its last byte (§3.4)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c3", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "truncated", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_trailing", + "about": "the descriptor followed by one more byte (§3.4)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b00", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "malformed", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_unknown_version", + "about": "a descriptor of version 2 (§3.4)", + "descriptor": "5752443102988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "unknown_version", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_bad_signature", + "about": "one bit of the descriptor's signature flipped (§3.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37b387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_tick_zero", + "about": "a descriptor whose tick is 0 (§3.4)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d06000000000000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa7090913df3b62173acf8d8aae44b0191b5abd9190127f9bd281f6a2817dc7134c27cfa25dc44441d73698f71cf354b1494191a220d279f635987403ebbe0c", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "descriptor_invalid", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_profile_mismatch", + "about": "a profile named music that turns DTX on: a profile under a registered name must be the registered one (§8.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc050000000000000000056d757369630101046f70757300000100000000000080000000fe01000080bb00000208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f55e90c20f070bc68adf7488eaa1d309b6c7442d0c7d283f18910bbd0753f0edb76f2c65af36d6ddb1a1e08a2c61e7a21263f17eb7bb0e4a3e6a5abce753605", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "descriptor_invalid", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_role_lifecycle", + "about": "a role that may send join, which the ceiling never permits (§3.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100080001000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074b4f10c57b9773bf92279ef1864a5ee2d4a486c783ff2b790d6fbcee21baf87eb8a14ae162ff548fccc3e114443592569b1825f699015e0e852e25346573f0c", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "descriptor_invalid", + "at": [ + "descriptor" + ] + }, + { + "name": "descriptor_recording_jitter", + "about": "a recording policy whose jitter exceeds its commit interval (§3.7)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000d0070000d107000000079c724a88251db4be04eac311b975de5eb2564ef9329a703a00c076dcd1f08c6629793587fb1250759e29fcc6ce33de21e17c6fd8b4b34060a52a35170ed60e", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "descriptor_invalid", + "at": [ + "descriptor" + ] + }, + { + "name": "key_log_missing", + "about": "a descriptor that names an origin, and no head of its key log (§5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": null, + "chains": [], + "outcome": "refuse", + "reason": "key_log_missing", + "at": [ + "key_log" + ] + }, + { + "name": "key_log_other_origin", + "about": "the head of another origin's key log (§5; jwp-receipts §7.2 rule 2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://elsewhere.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"012a0022ad43c6d14bb7ce8c39cf27511f87292cd13e83d6fa08437a13eac7e4eca2099fa7f36ce21ff3a6387aa45099284befd8a52b332a6963f6f6ba07d20d\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "key_log_not_held", + "at": [ + "key_log" + ] + }, + { + "name": "key_log_bad_signature", + "about": "a head whose revoked list was changed after its root signed it (§5; jwp-receipts §7.2 rule 3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[\"5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a\"],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "key_log_not_held", + "at": [ + "key_log" + ] + }, + { + "name": "authority_not_listed", + "about": "a head that lists the authority's key with delivery and not live/room (§5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"delivery\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"5fcf7ee5580fcddf371c3e288683ed6b2c43c35d28326d7da58017efbaf93dbe76c6e3cdcd311dca60794ccdb949c6bedd1760d0606a1972108f2f36e10a310f\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "authority_not_listed", + "at": [ + "key_log" + ] + }, + { + "name": "authority_revoked", + "about": "a head that lists the authority's key as revoked (§5; jwp-receipts §7.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":\"2026-10-14T00:00:00Z\",\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"revoked\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"842af0ed858bbf82d46fedb5b48becbf76c5bb0931c88d6a0aa556ef482151ac5e2aa432f78d268a539396493644b93c5d3175da758f7527e7a36bd650396600\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "authority_revoked", + "at": [ + "key_log" + ] + }, + { + "name": "grant_truncated", + "about": "a grant without its last ten bytes (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000da52cb8a9a33184a5da85c37affe7d9dfc6f4e7a3019ecc07c090358ded448066ac88859718562bb805f34d7da43880addb6098e654e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "truncated", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_bad_signature", + "about": "a grant signed by a key that is not the room's authority (§4.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500004a464919239752c456ac1c8c534be561df706fda93ec55cedcba87f9b21e7ee9a0e572e8941f7c35cd52c4bf92b95a76cf4ea681ec7ea2f99dd47cf0f04bc700" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_wrong_room", + "about": "a grant of another room, signed by this room's authority (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "5752473101b719f5d1886cfce5effb0947e8bfd87197836a5f3c07b707321db8b67a671d1ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000b4c9a2be409f87cd41b10663853a4a7a16fbc190ad734d625bcc950f09fc32f7afa30d2d084647783910425bda5d7aafbfaf23a17ebed421ec5c8da4fc89eb02" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "wrong_room", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_lifecycle_kind", + "about": "a grant whose policy permits join: no grant permits a lifecycle kind (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310108000100000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000ad92fa71080c87cf8766aab10a1cb354a0cbb8daead09c785d5896856c48fb6c08787832ec172b07e7e988753336580debe05a28c0d58a9770c68495b835a202" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "grant_invalid", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_attrs_too_long", + "about": "a grant whose attributes take more than 1024 bytes (§4.4)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650304046e6f7465fc037878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878782283f509a539ced74002ce49e88dca76e0ea2bbd666b9d749d21152f797382a0a013b79355c3f4796c5439de30ea0935d16efeda9ea446bc1ebbad5166873204" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "grant_invalid", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_too_long", + "about": "a grant good for fourteen days and one second (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a00000000f1cfe36a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000e7533ad356457152cd2e5ad7a3da176419a6625b877258af012ba55e7c400a610d0c2a26453e5f790f27efa324da9199c3027ab0164f34672e5acf45b7fc1c0e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "grant_too_long", + "at": [ + "grant", + 1 + ] + }, + { + "name": "caps_exceed_role", + "about": "an audience grant that may subscribe up to layer 2, above its role's layer 1 (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010200000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000407ce0083737734792bd582f9969031b207a664716400f20ef21f2d8a7c0107c069ad39441e5ec98e3af10932a7f4e3c462c1ebe6d373c386b80f69f8b1c6b04" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "caps_exceed_role", + "at": [ + "grant", + 1 + ] + }, + { + "name": "grant_exceeds_room", + "about": "a grant whose payload bound of 4096 bytes is above the room's ceiling of 1024 (§4.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000010f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000b61c9b29e1eb7daece294cf7acd6eb76498af84b80adf827b8b946058a17431160173dc75542524cdd9d4b4867677133fcffe84eeda30a440bb4a8fcf98b0703" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "grant_exceeds_room", + "at": [ + "grant", + 1 + ] + }, + { + "name": "exchange_unlinked_grant", + "about": "a grant whose prev names no grant given before it (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000008067f81349126761a6b7fe0cf3bd66d94800e6a65dc2f9d1d07de1a362f6d95bd8122dad96eed33117981aa9923f907d8a1a236fcf8c14579e586cbe500470b", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c1111111111111111111111111111111111111111111111111111111111111111404b4c0000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000988ac3315480ce75058a65eeb4d0c8bfe27ec04ebc078d19f39f168050528583be147b7673d239cd021db0eff6fdf0dd390051fd6118ed28e3a02f0b94788208" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "exchange_unlinked", + "at": [ + "grant", + 1 + ] + }, + { + "name": "exchange_mismatch", + "about": "a grant chained to viewer_a's that names viewer_b: an exchange that changes the principal (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000da52cb8a9a33184a5da85c37affe7d9dfc6f4e7a3019ecc07c090358ded448066ac88859718562bb805f34d7da43880addb6098e654e8e51481afb9ee22ee40e", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb37d406a857ee63ae9fecd4f293211c3e92c6847beb4871066ecfbca21f4a3860404b4c0000000000f05ad16a0000000080bad26a000000000303010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bd67e742a94d871741bd741697144215cd3c703f3f39f78be8c20d00966a7944f52c1adc744b81cf81c8fd1ac07d5bf87ab2bd68b0392582999e3577515b3d0f" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [], + "outcome": "refuse", + "reason": "exchange_mismatch", + "at": [ + "grant", + 1 + ] + }, + { + "name": "event_bad_signature", + "about": "one bit of a viewer's event signature flipped (live-events §3.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000030a00080074616d7065726564816a3da4f959e58f91be66477fd0ecc8642c94dab50510b16f459d0b187c42882e028f3a0758fb095ae647af342ec54ca9ecf9a05284b59b8cdb99b333524007" + ] + ], + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "event_wrong_room", + "about": "a viewer's event signed for another room (live-events §6.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e" + ], + [ + "5745563101b719f5d1886cfce5effb0947e8bfd87197836a5f3c07b707321db8b67a671d1ffcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000030d000b0077726f6e6720706c61636542975fec54382dda09fd82094e8ca3c28949ccf86c9a1c9e0e9d1c08d1b041823c77a8c57a6f441c1e8624cd65709b50780f0599b9b2c54368650e8dfbe67005" + ] + ], + "outcome": "refuse", + "reason": "wrong_room", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "kind_not_in_grant", + "about": "a viewer sends a cue, a kind its grant does not permit (§9.2; live-events §6.1 step 5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000020a000301000000000000000023870cc9a8043f15164426cbb17756a321d9e6cd098a8201063ea5f6bd4968131579bda52d2dd5a67cbe6f5ed98522abb5632b5880135477f0e92dd7df9f2605" + ] + ], + "outcome": "refuse", + "reason": "kind_not_permitted", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "lifecycle_by_participant", + "about": "a viewer authors a join: only the room's keys author lifecycle (§9.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb0000000000000000000000000000000000000000000000000000000000000000211107d3c0aab3c25024c80492217a65e77a07f44b8bfec6ed4e988c3d4d2edbc02c358e1bb111eafcae468538cf459fceb32a8bb3b711983e0dfcbcbd953703" + ] + ], + "outcome": "refuse", + "reason": "kind_not_permitted", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "outside_grant_window", + "about": "a viewer's event at t0 + 60 s under a grant whose exp is t0 + 60 s (§4.3, §9.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a000000003c69d16a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000016ebc63b1eb889ded5404827b35f7bd46732f45006ba5cac8811f5b196f4a0026ceb968ca1abe5a0d632d80789dec5abf75e2864a147e360904dca6992dbbb02" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c2f1c95dfe786c27aff2fbdf4363b4ea47d669672638d1845ae0bb555642a28b4f51ea65371dc3e3c5266e8e869e59915f1478ddadeaaeea66fafcaef5a32df30c85600bb9c2de0f2e7e6e2500749d55f9cb88684ef810a9381da83e8f1a1390b" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000080c3c9010000000000030c000a007374696c6c206865726548f3e1fa44e4ccaa20abecaca99f1c3920a79c2f6eb2f1120da419cac7a813b1ac3d207a675ec720c9b3bdd9a85d19904441259453d2f76502398e204ec77202", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c010000000000000009bdcc916b0fe21dd1e242a95d2ab38d5a5fad9f1160d69724ff06cd9646b55800879303000000000003150013006f6e65207365636f6e6420746f6f206c617465a3a013e62dc8fd982c95f6eb77c7aad2086824e7f06006387f99510429ff1dd9c590c9fd773d4973e132f674efd9fbbcbd2638fea2ad0ea01b9105f722f64705" + ] + ], + "outcome": "refuse", + "reason": "outside_grant_window", + "at": [ + "record", + 1, + 1 + ] + }, + { + "name": "join_before_nbf", + "about": "a join at t0 + 5 s naming a grant whose nbf is t0 + 10 s (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c000000000000000000000000000000000000000000000000000000000000000000000000000000000a69d16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000000b9b6cdb77416ae27294f591664e521518554a6c744b5d7644bd37a49d24436c218f125dd9434fd1a2f6869b456a0f20b65fcfc930c098102d85de3b0149307" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000404b4c000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c3759f2ddaeb144a00d93bb2eb6ad8602967092825b540957af2c1f7faf2ebd80b7a4503cd590f21f2240c7df7467a72d2a07c179e65e1fdbabc16d439d41a024871060d68fec8e81845ddd2edd368a380f324ebc7f6d2cf6493cff4258ca6a00" + ] + ], + "outcome": "refuse", + "reason": "outside_grant_window", + "at": [ + "record", + 0, + 0 + ] + }, + { + "name": "not_present_before_join", + "about": "a viewer's chat at t 0, before its join at 1 s (§9.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000da52cb8a9a33184a5da85c37affe7d9dfc6f4e7a3019ecc07c090358ded448066ac88859718562bb805f34d7da43880addb6098e654e8e51481afb9ee22ee40e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003070005006561726c79fb90b7cc5dd604d96e3372b9afd7cf58ca51c0226ccec03a02cbae57ef37202285854be8126929018bd5b441680787543cbd40f324e40ce400beb50045f2af06" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c37d406a857ee63ae9fecd4f293211c3e92c6847beb4871066ecfbca21f4a3860cd747ce11fad7421e5aeb6cf381ca631dac6043ca90729fe411bb8e89e22b872ade6be7bc655effee3edbe4d918cfc7fbe6037b4383eb1a250485c18437a590f" + ] + ], + "outcome": "refuse", + "reason": "not_present", + "at": [ + "record", + 0, + 0 + ] + }, + { + "name": "not_present_after_leave", + "about": "a viewer's chat after its leave (§9.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000112100fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c01f02cb125a6d4317b6f259d373e6bc7c581fe9ededadaad11c38ba961f3ee6cbe95f6e53379210ea7b90714bcf1e9367b8b2ee154fdf4fa2972a9495b64c1fc05" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000c0c62d000000000000030f000d006166746572206c656176696e677cff4824d0369bef1ffc42bd82553719c51106620c16cd82b690fa0591ce1e117bb0cbe3c326c8cbe67645c51029676e32c6d8997d76c1a03f6d08ec67e42607" + ] + ], + "outcome": "refuse", + "reason": "not_present", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "grant_revoked", + "about": "a join naming a grant whose digest the head's revoked_modules lists (§5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000c05b406054db0e3c8885af7a8a15f43600000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000c6c760ebb0c5f8f2b3477e868e5e4dc8f74459f838ba33475bcd32d908a034d472c78ece6945f1436f212721618e505746acc798efc1540c3ba4bdca3e29b50f" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[\"71d86863d1bc9b3d587748711f1d7e9308a319fe8f6c3405930bbdd6b3aa92ed\"],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"425c37605c9b53636fa7787646a0541e2e61cecc226523a6321945e5c2de67cd43d65c7998939ec713005c277a6032f8b456fbebf8e72baa89600b8ec431bb0c\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb71d86863d1bc9b3d587748711f1d7e9308a319fe8f6c3405930bbdd6b3aa92ed7e27d128aa89feb0e0e494e9264582c1b03a04a792e192fd26bebaa63d17a10632d7433791302e6c3523190371c9108e1a2342deac38bdf93c127b453b9d850a" + ] + ], + "outcome": "refuse", + "reason": "grant_revoked", + "at": [ + "record", + 0, + 0 + ] + }, + { + "name": "viewer_revoked", + "about": "a join naming a grant whose viewer's tag the head's revoked_modules lists (§5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036875528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000002000101000000000000000000000000000000000000b1163b86dc0362e286c8985c28f09315574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000060937041954b30477eff44461f51403e11f8438d7896913a2852b50bde4484491c0fccc1a9d9ff6da4bf0b969b5492d45459e7daf539647b617f63776965308" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[\"c067f63c46d100b874a2b8fdc3af8a5cd9e236eb5e8a428125f0f7b1b70e275f\"],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"d4d9a2007cf54f6ce4c182859bc25cabb1a7d5affc05ae0dcd08e4d90f840ebff3157fefab15a46d07a479c6c41df3cb3ad21205d2e1f8b30dac6deea8b78b0f\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79b61ff9ed8edb513cb8a9c54d8dc2a2dc9fba52a88280c9c457a10d2ebce94f0294e4509332b9c088f3e0e239dc7f2148ba572d3810d5066aa47dd48f677a1d136e89b44d1210b05b8002fe2f7827d83b9f842b5b6f38c044355466fae8c1ed09" + ] + ], + "outcome": "refuse", + "reason": "grant_revoked", + "at": [ + "record", + 0, + 0 + ] + }, + { + "name": "grant_reused", + "about": "a single-use grant named by a second join after the first ended (§4.1, §7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000112100fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c04fae512ea9ff906e5e522f409c281f84d705163894a2be6192195b3f4f342c2e258f07bcc9cad8d6adf114d4ac06e7e4a16b62784b444c4fb165cc2a9f1e52909", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0400000000000000c64c0d328accab2a7f56512302a9e30c7cac10b32b36e4701e289662a02308fac0c62d000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80999804867c85af079185d084b55faa986c2ff15dd2e55ce0dd5b6e2a4ea7e3b43b6796bbef94d9a3c020f3f60d20fd8ebe058fd3be89d226156261945e7914b907" + ] + ], + "outcome": "refuse", + "reason": "grant_reused", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "grant_unknown", + "about": "a join naming a digest no grant has (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb777777777777777777777777777777777777777777777777777777777777777793bd06356c5fc26c8ba654288841df499d6a72417be10f74aaabc755a76ca029e2936182839202f07db66d459c55280f29608d3321151d642c5212410c76a10a" + ] + ], + "outcome": "refuse", + "reason": "grant_unknown", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "grant_wrong_principal", + "about": "viewer_b joined under viewer_a's grant (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099967fcf3ce68bbeab7f084594c341f0c45d4671a94de57411cac7d96707e6d72abf442d7b70f4a895ddbe29204155ffeb3bb5c137469cf90b6b3ef75ab4ec0c01" + ] + ], + "outcome": "refuse", + "reason": "grant_wrong_principal", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "already_present", + "about": "a second join of a principal already present (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd47bb2d8bc147effcac0aba90d421605857d4516ff96a9b8ac4b4e2f60b83e706665003405b08a405d600184ae0d559c9d975344e95494c11918feddccc71af07" + ] + ], + "outcome": "refuse", + "reason": "already_present", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "participant_limit", + "about": "a third join in a room of at most two present (§3.5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650200000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142a2d8c45d59c385935acee57b3d2bccb359c7d648eb9fe6a922c9794f6fcf22f6546587364645bff165478cca1cc23a5af605a6db1c4cf583cc4d7f35c1809", + "grants": [ + "57524731010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa58fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500000b62557b18bdf030f39a8ca03d82bb745a0916abeba00ab9b17adda523ad098f74b93397a915f3575b50ad8b351b5f08ba2777ce001947fc6afe07c9e324a801", + "57524731010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa58f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500009c9bd1dd1dfa401e34136928b801aec5b82b345948e24f3ca42cc72b50ae85cdb7bd0d0f214f574d9532029297413168fc332407c2100690e7ee5b71a33cda06", + "57524731010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa585528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bfbf02d51d8b4544eb98ce32e07dfdde6202a3ea98a372fdd5adb51aaa22e61afd612f3f97fbc8e16568cf0bcb86ebcb3adad78d2805e3125daaa0ddd839c004" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa58c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09ccc865a45949c59b5d0cd093424a3fc60eead7c8bc7dec7f50e08ef66306dd75b1507c46fc718e7466bd6018e7cb7dbe2c84de508ce7cfdb1ae3e4312c91414879c2fc92fc49043c74b1bc67103e44494ca70acb5ba18bf9b987b5c335e5dc90d", + "57455631010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa58c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000fc2671c4880a60ec621e162ed9723a38f769b91f4b5c53425977cfef9d51dbf5000000000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfbfbf30a227c8b2b349cd8553d992999d0949154ecfd34f70b7a7ba9f8ceb802a611bdf993cde2e180a0c64756935caffd73691edaba99e05aed495f6d67f2d5fe3b07043442d6190dcba4787734662f5574b1bfb5882cfd9d18184a22affd3b02", + "57455631010684127e483704828565d434cb80c7f84f733fdf53353a295ccf3e0f3384aa58c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b020000000000000017f31bc5f1fb0ca32fde01bdc5647dec4cb12d287b13039dbb0c58cfbfcfcde540420f0000000000001040005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79215b28fbdd38728cb59a977c81d275095db271f1fd8f8503479bd09414d166dab77ec064309f3b10c12d8c6e21a23134523ffc31ecc5d76a79bdec7d2f741fabcae577d5d0c8602fa2a618c1126ff1909014e3f8ac17b3d6630469915ea3f50d" + ] + ], + "outcome": "refuse", + "reason": "participant_limit", + "at": [ + "record", + 0, + 2 + ] + }, + { + "name": "lifecycle_malformed", + "about": "a leave whose reason is 9 (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000112100fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c09ab3051b3702bc6b9d2b1c83257ca05d77e601f7550b400c53d9fb95692d5dd455d146a9b2c97b111605c417c2cae68d8c3adef15a0d579e9195c46004cd9d508" + ] + ], + "outcome": "refuse", + "reason": "lifecycle_malformed", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "publish_not_permitted", + "about": "a viewer, whose grant publishes nothing, published (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000122400fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00020101832d76d601fe247eb35de85029e457795caacaee4480446eb502f12a8e265333c271f746ec2073010cf09c781e050c46aceeb2d41a8b8297ab3954738aa6480d" + ] + ], + "outcome": "refuse", + "reason": "publish_not_permitted", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "profile_not_granted", + "about": "video published under the speech profile, an audio profile (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10002000105e1638cbf23e1c9f8d18fd72c88e61f06cd2315fda519556c351d2a7dddd51efcd86390cdaf5f0110236e192a412e3e9971df8c03a503876a6ec7f1defacc0d" + ] + ], + "outcome": "refuse", + "reason": "profile_not_granted", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "profile_layers_exceeded", + "about": "audio published with two layers under the one-layer speech profile (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000100026f8097d3c23b50aee0c91d9ffb682d5c76e651ccbab95ab473e8e5890f99db9768aa8a81fd1ebc71c00fe209f20f92566af141b70cf9493178608ef436d8a50c" + ] + ], + "outcome": "refuse", + "reason": "profile_not_granted", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "already_published", + "about": "the host's video published a second time (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201015fa80de5698d729e44d0f5f2c661ee96a184a83c733c57914fe4fb05fc5792f854d7c829cd3540546089352db83ac4e780e23e55e76407f1e5a1edc63bd8e30b" + ] + ], + "outcome": "refuse", + "reason": "already_published", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "not_published", + "about": "the host's audio unpublished, never published (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001322002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10001905188c4624927fc2101d3b612bf5fa2162918af92a113ccaa649c5dec6e4a77f9e4796b1b043d827213fa632e50845e5199f4fcfc03d9ed815e0c475401820b" + ] + ], + "outcome": "refuse", + "reason": "not_published", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "slot_unknown", + "about": "a publish into a slot the descriptor does not declare (§7.2)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000122d002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1096261636b7374616765020101b0f6cb44f0fa692033961f8c3e395873315bb7569d3d5f23ebad91c7a741a28ad5e5c878bf7eb9ca7255e2fc3cb8b0fe4bdbb7c294cddbc4d47275ae87d0f90e" + ] + ], + "outcome": "refuse", + "reason": "slot_unknown", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "slot_full", + "about": "a second publish into the stage slot, whose redundancy is 1 (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036873c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000101011568747470733a2f2f72656c61792e6578616d706c650000ec4de0fdb63d0025adbf5204c6c3b25df5910224109dbd22cc58f20980eb00574218ed0c68f7fc5b1b2a556961a61f1f750e8f745dc8c4eab431cf93edfd6e03" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001040003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49afe2172696bff2910601a91e9e60759f5a6ae1ea077fabe475dffe7f1041e4852b5f15743080eabcf397870e3a19647ac9a0e37017e555f037b43e64d708e38c507dad4827b14015bb1dfa93e7db614ec3a8b11a811abc8dff237e9dea9728420d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000002720b67b27f75e4f7bc640da7d5fc23d3cee66fe059e31cc68b5bec4b6ec545ec0c62d0000000000001229002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10573746167650201019e42c8ec17d13f7dc774726c15603ffbc46e24f631eed1077d01fc96ce8525359eda0e4a151a3225da630657835ff3f826ce7e7fbb1f900fe68d4433dcfec20b", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0500000000000000d52a03e51e0522e8cb9ceec28c565033c00af0f0da2027cb74fb69d78be6f49600093d0000000000001229003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af05737461676502010162670e4740ba8b7651ecbb3a896d541e758bbe5bc485eeeb9886be60f2c92bb5652875b591efdc696188f4372423fd5a37d4d7162e59fc2bc93863b2e4879700" + ] + ], + "outcome": "refuse", + "reason": "slot_full", + "at": [ + "record", + 0, + 5 + ] + }, + { + "name": "publisher_limit", + "about": "a second principal publishing in a room of at most one publisher (§3.5)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000001003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077b6a36f6c3ab79c15c3773ef43483e514cedf09335b417e08285d92d21c86c9d185ec882aa1cec314a7420466fed4dbd2e9afe25c784e8a5e9746b5636f6606", + "grants": [ + "57524731018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000b8e735f34a4436bbab701d6ab1472ef3d24e9c6a8d0afbd2c6a92c4ea8d01185d91ca0e94ac1945caa732092764d4de001e8a8fb8a960a4bf8a286577672600d", + "57524731018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c6500004dec6dbf8a0a6dfb975e77949305220cbdd465b9eac619406d318ab119b811ec80d844f4a8f7b67219c906e5bc6396f13264c5ee018b3c1e090a1ad22dd46e0e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f00c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1773a64b01eb8398a9a6f9e4cd53a312d0752c01680e4cbc781e566d44f7b4d7b0a027f5881ed0d6aa606dd732eec0df47211c179e99d42b95745a8a35da9107bc64754afc974431f946b2234b47fb71a0bab5a055b44fd9ad4e19a13a718b104", + "57455631018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f00c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f0c5c283639bf16682a74d53daefd3332224bc57f1e34782432e2965bf0b00fd0000000000000000001040003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af614609a585a1ace355267aa98bb593d41151dd07bc8323d277647e40c3b5b7f2f389609e097d85ee7251e6220eb3cb12901841880aea879cf19f3afbae066cede0ec0f08205ea899f5e6f5a5fcef48d3912bc2d1cfd0e1dc9e79dd3718f3fd07", + "57455631018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f00c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0200000000000000ac7c9fe274928fb7622730228f5b10dd88e10be1391981736708aecd1a94ccb440420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10002010271470bfb7b82d9dfa710943875f04f298ecb46192999c7d4b242872eaf66f772759ccd49c76f28701b3c7a3403f0cb4f5ea5eba6c5bc8a4dfd4cc2c1e1c2f807", + "57455631018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f00c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000759653150810b0688bfd3d41923f8b0de4ca5e7c5fbd8962d2e62adda77cb0c240420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100010001913d577d395261abde976579394d115376a6d995b047c59e038f1398f7cb1d8e1401293d717d34e2866e07f37f34dad728efce7fcf449ceb6abe5b3ab93f7209", + "57455631018ffab1e81457377bfe47932a2532487c1bf5719732e88097542400383b806f00c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0400000000000000108a8e5cb5ae53b51b87c7fe4e9e08197f6b99dced6bc210c913699f6820bd5280841e0000000000001224003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00010001b45f81d5127db7fe5815ea63a8de62092f17d9b5640fb3c737b9cf3c3aa0edbcec2b9ae00a027628a3ce3f5595f92378455dbcbcdc10adb7ed7bf4a3bfb98906" + ] + ], + "outcome": "refuse", + "reason": "publisher_limit", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "exchange_not_current", + "about": "an exchange whose old grant is not the subject's current one (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000d938e05b7a1e6eb8f6220c3bf394f5c0be952214bc1ca7630d35f0687e6717a6c44930db99017e12b78a6bb16833959ddb96861f96caaaaa4a57598e65593602", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb7084feab2bfebc5704ad4a8f062d39f24bfca59bda0c60b7454d0e495cac3b49404b4c0000000000f05ad16a0000000080bad26a000000000303010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000a707bc5e5730b48c2a221ce84f7bfd1c7ac0b7c23983984faaf7c7754cad6e67c1bee123e0a47d5dd43ededc8309913447f5ba2412d72d73faba75f55f10860e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb7084feab2bfebc5704ad4a8f062d39f24bfca59bda0c60b7454d0e495cac3b4956dd51cb40320304e847dcb14132f669923b100258128c990ee5378f67dd711e0dba8932924eab8a81ad6830119fee360c2c3b8950aef90a07f0a1115f7cac00", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000000eb8538a2b81d4159c16cc87ce525973de4843e95d46efa6ad80e89606e5ed1a404b4c000000000000146000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099f247e7905aec52821e80550b296bc41a6c098572a824f09da4e64d6f7759b2dc481c76b04614bb955d6ab7739259fd60c93593b77fea869ed095d7838ec0c07207266bb59064bde3814d00027373e51c2d12b4a3757dc5aa3a76024dfb360808" + ] + ], + "outcome": "refuse", + "reason": "exchange_not_current", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "exchange_off_tick", + "about": "an exchange recorded at 5.5 s for a grant effective at the 5 s tick (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099404b4c0000000000f05ad16a0000000080bad26a000000000303010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000093f1f1deb2ea56235932800125a7410bb2ae7287a0861b492d8f4ab10ebb482b5558d336b0898c298489cb6409ed898b7c6c4b6fedff989c7b953953825e750e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e560ec53000000000000146000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099e1eb511b8821343d490ec1f3d98a2375ad865fd41178be7c2ad9972380a8298ab2629313d046bda05570556a89b831e98c3bdc526b128ed695b9486a2575e7f5952bf32eceed99d0468d64635ba07514a2036883b85f442e4f9596e01f63610d" + ] + ], + "outcome": "refuse", + "reason": "exchange_off_tick", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "exchange_unlinked_event", + "about": "an exchange to a grant chained to an earlier grant, not to the current one (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099404b4c0000000000f05ad16a0000000080bad26a000000000303010100000000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000093f1f1deb2ea56235932800125a7410bb2ae7287a0861b492d8f4ab10ebb482b5558d336b0898c298489cb6409ed898b7c6c4b6fedff989c7b953953825e750e", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994054890000000000f05ad16a0000000080bad26a000000000303010100010000000000000000000000000000000000000000000000000000000000000000574550310158010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000534d8900ca884725c53c87e1c3c10052a0b86c021ac24e626a094e825ccc904862655315e5ca6eeafce1510386674c2dfa38c43ca5f284ee72876cd73c89660e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e5404b4c000000000000146000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c8099e1eb511b8821343d490ec1f3d98a2375ad865fd41178be7c2ad9972380a8298ab98079b1659392208513ba1e667ece6444e4273e2ff4e1ac843e302cb14d9660ad86a8e7044d1e06aef029ba482476f94b03a6c7213d85db465b04af1f4faa02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0400000000000000203d746bdebe3d83564f47b91d37f2f69a561269ac630e23757c2caaa2334585405489000000000000146000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09ce1eb511b8821343d490ec1f3d98a2375ad865fd41178be7c2ad9972380a8298af7a8facdaa2b9c2de6fe45dcb224fbf9c919876489363a746477e6259e06fa8214443032282b5a70d7113118396ea9c346a5cd78a90ad671321d3487301410336cab5811f19867cedef56050c285c42a05a0fc4b9fcaaf3d730a244169c3d00c" + ] + ], + "outcome": "refuse", + "reason": "exchange_unlinked", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "exchange_while_publishing", + "about": "the host's grant exchanged for an audience grant while it still publishes video (§4.6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd404b4c0000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000046aae085288a2deac9f4ef5ad4a6d540b35e1dcf1f2eb41a7adef9a1e23c52761c136dbf7ae283f6b2f6b67801a7d0eef705fddea25daad06390796d7899570b" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e5404b4c0000000000001460002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd7e60ac870566076eec6d78b6f6a6f1bff7af4606610a7351dc925b083d4e49aa6f8885b3eb4d5cd7ee01b52c3195e27155dccdc779e0985e3e32eb2b27d85656da8ab4c8d0207bca794a1d64f25508b91ca1dd48a17ac211556b0f531e6d9f06" + ] + ], + "outcome": "refuse", + "reason": "publish_not_permitted", + "at": [ + "record", + 0, + 3 + ] + }, + { + "name": "takeover_not_higher", + "about": "a takeover of the stage slot by a grant of precedence 20 from a publisher of precedence 20 (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000022505e424a8c874cecdf9242d7000e7f3e221e9b1bc25d44773936a819dbe2157787518e34f2d9aa92363bced84687522b3b47e69e7e108eb4fb91f1c9ae500", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b73ec6efcfdf2e3fc5d0549997b598113574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000bf42588185d4d3b960ba6d34593cab2887eb20c5cee2784145cc9cdcddb58c33b19105915136de06062eab431fa69eca8cd64299d3a5f99760465ff94192de08", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036873c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101021400000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000101011568747470733a2f2f72656c61792e6578616d706c650000b3bf7deb711c5e34fd304383b7384c1d5882cf685071140055914db69d3b4a6c7e385f3fe2f63b787196ad49981df861b9f2297b58f0326af4462adbf2da4e0e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10148fc122e86f6e371b945b18505474acdfa27a7db90820d2942fd90f592b3fd90b68fb3d4e5bfa7d5c889869165e5730f0205bd15d6c2335511e2b9df3ce0c045533fb0dc3a2162dfd99b9c82138bf0b5c6473b44c87d40bae078e0a6532c02", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f125530efc91d692b133a73b44b6912a0d40c0b6beecdd13fafae06739bfb305000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c8e5676d25f93e1e0d9d8effb185c0e876e36b0b94f6f29c6030450c38e5c80994b3768b3c649825b4b4f1af746866fd9ce1e4ee8a13cf2e5c4301e33893ac7565073c07cb336e3976c085a12e988b72cf5eb22855a426e6cf64bca50ff12090d", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b02000000000000003dc4e559fe2b5aa4b6d26a4578388ef9622026d5d73c7e306a1c3fba2a91205540420f0000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa1000201028c978aab8fbceedc85be94f1a83822820473e80b223db9cdfdfaca77f7f0961cb8365efdc5f92691cdaf4f956df4bdee7a548b28a5684fa6d5588ffa6957030e", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b03000000000000004790a661c49ab3dc66aa2970d8bdcb41849dbcb8190780a5793b0f0606f4d6e580841e0000000000001040003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af50dc4dbf0cbdd490b4822e20a01b1088bce4b90df2325a58f4bf7022d3964ef89bad7ad4f13ac17dbd8dd3e4e99cc47d3bf6d82fd332dd4705a987547a56c0ae95d974a0e02bb3f51e72ed170dcbb9b0f9584ea1b26f94bfedd5c67994bf030b", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000006fa8dbfab4661e11e227df526065990ed3cd05c18b5f13a54f0665166b5c3754c0c62d0000000000001229002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10573746167650201017c4e253d627b52cdb81a3740c7cfd80aa097c2cfb8dd50a3c321834d032b8ee68673dbe5d1368041be3fd8b9aabfb217208c12ffcedbd676fafa8eb2faee180a", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b05000000000000002b9c71f5676146b3eeb951aae76ecff9cfa8468562165403a52ac0a182d1e94300093d0000000000001549003c82ef79974909487ff3cee76fd819cc0da2f6f55f09358da093a1a4090a49af0573746167650201012df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa15225ed8ab8882f42b0bf55f0dfd686b578c066b5e978e41fd6ab787a72249f337a0f2abbd0a596b394949913327cb809fb39853da3045972a8e53375d943180d" + ] + ], + "outcome": "refuse", + "reason": "takeover_not_higher", + "at": [ + "record", + 0, + 5 + ] + }, + { + "name": "failover_not_standby", + "about": "a failover to an encoder that is not the main slot's standby (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000002002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000207656e636f6465720300000000000000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000001046d61696e0202d0070000010a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041620710411a0b9d178a58d6bab143c23fbac78b73f2062186681d0033fc2b098dafaef536f6c5e20cbb99c3703b302495ad10f7983b29d8faadbb7843dc7e0d", + "grants": [ + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd379500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c6500001fdeebaf20a2b4ab8d8037c43b1cd7fb13ee82c6ed70e896a1684d65421991f66110c01d87eec63262d1f5e16c882da656aa3e68bdabcc753073539c60c8470e", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a618fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6f97764c450682f5481c88cb661dcd9c7e863284f0117b17c912b6d402d8819ba93c08ce59d3242e1681e3a3988a637473c0bbb25bcefe6765738d1b9b73c04", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000100010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000636effc39ee2cbc9e819667284ad5e19aebe1e2eed7404524c0dab993d40c3f6184b26e069073b69fd267a65bba5da87a3d19231d0cafebb459386f12de89b0e", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a65528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c6500007021aaf64f03b4708e12e9832557a4d6518d6a9f494b67f5048f3a25f45bd2b433d94b165d6166780a758c7abbda8728879f5dba07f9dc967e82959d3fb8a002" + ], + "key_log_head": null, + "chains": [ + [ + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db1225f40e324a812151fd4327b5c8b90d4ae52004b0900373fd6c2cf81c91326baf72ce5e8ed73748cbbb4b7e5e1024ee97ae425126800222829e27a1c53da13fb09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b01000000000000004f6fda73892a28e3b9be7f9a9a1911f0401c6f1bca4e51afb11281cd137ffd2700000000000000000010400018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129609c30052eca319ca85969175cc1f4d5dbfbb0807bfe5dc5d0f41c74920f994d0ca0a2f71f9b89e7ac6700adb72cf9bf27d9d3fa3cbefe293d7beec49334590c", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b020000000000000011027901a4fcaf11a3d622711d7fa0c172bb305c04125a5f0d436ae8e3cf1512000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09cb6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf97d69d358f89f6fe8814009953037952151088139e62f112162f737bb7956f0f287523a15e7733559cce283ed3cd6791785dc52e55bb4fc6059f3ff730689708", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000cd88570dc4d10384920b2b73d467500a22ea0ef34049623729a3001ccdb3aa7840420f000000000000122800044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795046d61696e020002af63a3eedecd1076f4491a56fc3b8dfddeca2d840e4065a4344f77076a58f0c2188f52f21bc63172fee32ff7d49f2073e96b3af8df43a352312ec2260b690c09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000004eeb163a7d1888e4af7d2a3b338e34473e740f7b45c0eba0045f9dc11bcf359d804f1200000000000012280018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3046d61696e020002402a836f4c34fa58b98f2f7844ffe6efdfd308a2355267a209f8e7f20dc5232a76920b8dfa70b43df306e13850b81791db6c7e6b52a9e47ab24f5f678fe81106", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b05000000000000001512f0cd1729e8fe875fafa15f81f9c8e5da7fa02af3aa91fe19ab2e24f9a810404b4c0000000000001040005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79fbd28e02d5ce49dce064aabc3ee9ceac9829df2d0c8d9ddeb33f6af30ab986124a647fb53bb5519c1ee539b1b8987b7646746615da71aea72b21f719c6b3998e54de1717a7023977c457d986325c687ed4a67908a298fa67282de872a0221108", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0600000000000000808cad40ada77bb740b6e6bf4932e1e747bb1c0d5a5f58940f300a96cf1d5ae9002d31010000000000164e005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79046d61696e02044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795c0e1e400000000004ee00eae11c6fa51e071ca4d42c8d36060b743f70b253b12eb63e55ac806c71256a7069f44081119681054c4f6c8e917b59c85f466d3c672b2c51dafd00d9c0a" + ] + ], + "outcome": "refuse", + "reason": "failover_not_standby", + "at": [ + "record", + 0, + 6 + ] + }, + { + "name": "failover_early", + "about": "a failover 1.5 s after the live encoder was last seen, under the slot's 2 s rule (§7.1)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f000000000000001000000002002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000207656e636f6465720300000000000000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000001046d61696e0202d0070000010a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041620710411a0b9d178a58d6bab143c23fbac78b73f2062186681d0033fc2b098dafaef536f6c5e20cbb99c3703b302495ad10f7983b29d8faadbb7843dc7e0d", + "grants": [ + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd379500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c6500001fdeebaf20a2b4ab8d8037c43b1cd7fb13ee82c6ed70e896a1684d65421991f66110c01d87eec63262d1f5e16c882da656aa3e68bdabcc753073539c60c8470e", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a618fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000003000000000000000000000000000000000000000000000000000000000000000000000000574550310100000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6f97764c450682f5481c88cb661dcd9c7e863284f0117b17c912b6d402d8819ba93c08ce59d3242e1681e3a3988a637473c0bbb25bcefe6765738d1b9b73c04", + "575247310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000100010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000636effc39ee2cbc9e819667284ad5e19aebe1e2eed7404524c0dab993d40c3f6184b26e069073b69fd267a65bba5da87a3d19231d0cafebb459386f12de89b0e" + ], + "key_log_head": null, + "chains": [ + [ + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795b59957908d67c72552ec52e8a4b80ebedc51b4016b6fcdff3fa779b02c0db1225f40e324a812151fd4327b5c8b90d4ae52004b0900373fd6c2cf81c91326baf72ce5e8ed73748cbbb4b7e5e1024ee97ae425126800222829e27a1c53da13fb09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b01000000000000004f6fda73892a28e3b9be7f9a9a1911f0401c6f1bca4e51afb11281cd137ffd2700000000000000000010400018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3beed3ce25265deff9dc89403006fb235bddf27025ef02c7ef7aa8ecae8038129609c30052eca319ca85969175cc1f4d5dbfbb0807bfe5dc5d0f41c74920f994d0ca0a2f71f9b89e7ac6700adb72cf9bf27d9d3fa3cbefe293d7beec49334590c", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b020000000000000011027901a4fcaf11a3d622711d7fa0c172bb305c04125a5f0d436ae8e3cf1512000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09cb6c5d77d76d83c1fb8f250c399a13f4ab659a4f2dc31cda4623dc2a6d6b62caf97d69d358f89f6fe8814009953037952151088139e62f112162f737bb7956f0f287523a15e7733559cce283ed3cd6791785dc52e55bb4fc6059f3ff730689708", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0300000000000000cd88570dc4d10384920b2b73d467500a22ea0ef34049623729a3001ccdb3aa7840420f000000000000122800044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795046d61696e020002af63a3eedecd1076f4491a56fc3b8dfddeca2d840e4065a4344f77076a58f0c2188f52f21bc63172fee32ff7d49f2073e96b3af8df43a352312ec2260b690c09", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b04000000000000004eeb163a7d1888e4af7d2a3b338e34473e740f7b45c0eba0045f9dc11bcf359d804f1200000000000012280018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3046d61696e020002402a836f4c34fa58b98f2f7844ffe6efdfd308a2355267a209f8e7f20dc5232a76920b8dfa70b43df306e13850b81791db6c7e6b52a9e47ab24f5f678fe81106", + "574556310175dcf74bf2dd6815ac553d882a055c9d79bee21be1a364d533c0a68bdb4a30a6c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b05000000000000001512f0cd1729e8fe875fafa15f81f9c8e5da7fa02af3aa91fe19ab2e24f9a810002d31010000000000164e0018fa6a59bfa637376f6bff25179f29dd92fb74015503392eff56d631020535a3046d61696e02044833e55ab13673818af0bd379312a92b0b22e9ff71b80d3a91a9f19ffd3795a0491a0100000000f9fc4d399ce1631a0bd8667b8a0ec4172f26da6040d4b6e7fe1002de5b47d59a7a961e004fa65ce65bd66252ecedf7f00596934954d4c6f5b59b65659d07250f" + ] + ], + "outcome": "refuse", + "reason": "failover_early", + "at": [ + "record", + 0, + 5 + ] + }, + { + "name": "power_not_granted", + "about": "a host with the direct power but not record mutes a viewer, then sends record_start (§3.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000f3291ec877bab8689dc8cf1a86d577a46799555b9457fa43b63275b5cb7104c1796257323e4fdc7bb3a8cc230e2c6feb4b3e59af6572377951f810a706c3ef00", + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000da52cb8a9a33184a5da85c37affe7d9dfc6f4e7a3019ecc07c090358ded448066ac88859718562bb805f34d7da43880addb6098e654e8e51481afb9ee22ee40e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa11c0e9534c1ed8e97a2173ead915931f69b9041c19ca02e45d5003edec88521189fb06d1e5a8bf78d6a017974ceb3fe159c52b8bb571e2c28d433ff38ed0ecbe1af29d13ddd68e19b9d6e31ec13ffce434741968b508e847a4468f3a85242f704", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b0100000000000000f92464190b07f5912ccb6b38800e272310efb2aa308e2dd1b04d90fde252c649000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c37d406a857ee63ae9fecd4f293211c3e92c6847beb4871066ecfbca21f4a386078620d76ab77cd2615329ef51f4a637242f33eebc30d38d76bd17d4cc7ce50c9fb00fd3c59a90d4231fe778e68b2fbe2a9494a87343acf713b290054d54dea00" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092200fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c040179d414745f586e37d26466bd240eb26f9b905201d538ef4d11382560ce5eb0b31f5a62b037c9065f159789dbd2ba8888807e7d183d805e4b0aae45cdf572d006", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a2036872df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa101000000000000008327e190719b444d997d34e01ea88cd199fe56687b461e03242a3ad97ad2415b80841e000000000000092500fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c01b80b0000a41b41f6ca9bfdf347f2e68b6199598cefdc811815f0ddd6677437cc907bde1068a8f5933d4a6b52174b2be6e5c6237f93c019b9642605aaff64e61e06834608" + ] + ], + "outcome": "refuse", + "reason": "power_not_granted", + "at": [ + "record", + 1, + 1 + ] + }, + { + "name": "rate_exceeded", + "about": "a third event in one second under a grant of two per second (§4.1; live-events §6.3)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4010200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000b01bf4a15e959679c4c8d52c591523ad20943444362410379e951838ac357513227f1d06414a184d01e994d15cae33d10ef30fd7091ba7a010a7ae5c686fa50b" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c86c1ff67524159b62a7fad7703dd71cb2cf38d0d5d6919f4262fa46a6a25e01f3f03dcf8d205799ce95e432aef2c8b87a5666dcf58f95583583843af0239607ed05bc240da749ac193f767281e9446244e6b37a968688f6964bdd7d4b6f2a50a" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000303000100618f8dda3fe7605dc8f7b0668e64953348b7c73d4d0a73f7e70874a7088cd0810b517a18e49c6d8138f40747d9740263eb21540d5b37eece7d3eea254b3e3ebd07", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0100000000000000ef99fc4330809765c546c98a1779850b4bc928397f8cad2a7af38e09b05e4d5120d613000000000000030300010062d9d6453ea400b89fa24c641432327e96cba6a205c567062094dd790c2f121440683ba84d3be136811641c57d8faecc10a58b48e8d6b7976f2c65b5665a8ac007", + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0200000000000000143c02b5a4ae903d2cecc5f7fa44a36d76ef385403b1a7e9982f5199322aacda006a18000000000000030300010063cf23fd60a7203d7749421abafaf2ee08106d3584a8d912939f1184387137d478d5025dcf8708bf514e4e72c251902ceb127bbf0df393f4b55a272b07a22d450f" + ] + ], + "outcome": "refuse", + "reason": "rate_exceeded", + "at": [ + "record", + 1, + 2 + ] + }, + { + "name": "payload_too_large", + "about": "a chat of 43 payload bytes under a grant whose payload bound is 32 (§4.1; live-events §6.1 step 6)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00406cd8e95d060040420f0000000000150068747470733a2f2f726f6f6d732e6578616d706c650800000003003c0000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000504686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e636500010100580000000000000000000000000000000000000000000000000000000000000005677565737403010100580100000000000000000000000000000000000000000000000000000000000007656e636f64657203000000000000000000000000000000000000000000000000000000000000000000000002057374616765020100000000046d61696e0202d007000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086c97e1a4b2609cb3438fd6c165e0bdc6f016bae7d16c4d37a387f4be3891b46f97c63fbf4814de11aadb3ee409d246a182017b43cacb6a6c64905bceb31c30b", + "grants": [ + "575247310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000002000f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000006d0a922a6fd0a39e78853e53f61ba7ce5ccf8e020a4f9b417dc60ac2df237977f675af5ad2e445cf30c651f5ae0e7448e862d2842a9c481f3a683268ae65b05" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"3328656f3df5d9617e108d46080e23610712c9979d4437e706240f53d6cadf7b\",\"origin\":\"https://rooms.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"687972706312d9675734bf13b4bcf695ecb1b374de7809242aa91f130c6a1c0c\",\"seq\":0,\"sig\":\"ba55b157ebe88fc97f2b5a5e3556415563552ed88b9931060b9e99ae0a7decefdc63e2cb916b9a5d03c80a0c1823de14e7d8d3fe0b726c2464d823611780290a\",\"status_max_age_s\":3600}", + "chains": [ + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687c73c9d1dc51b9a83c180ec0bd17f1c8520c0ab70c4874225109cadb2d493ec1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09ce28ed5d070cef54955230cae9c3b2cd32af8fde6fd5b9475c62256a09b9f83a96c52e1a5fbe5dc9dd426e6ee87ab935fc28a900d8314858f9b4d2f6fa49bf8cb90c3e3dcdb26260d743b716038eba70fb11fd4ece77dda26ed9286f7dd71da00" + ], + [ + "574556310191ac4a45ebdee375b286d920fb2d07f064a31e7b7243829126eee2e27a203687fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000032b002900746869732063686174206973206c6f6e676572207468616e207468697274792d74776f206279746573322abdf44dc6dfb70ba9e11a38ea1f5e9279d4294597d1a6fbf453f877e53b8fa99293787ab692823782aae891cd680efb6cb8a18ffca844991372720915cf0c" + ] + ], + "outcome": "refuse", + "reason": "payload_too_large", + "at": [ + "record", + 1, + 0 + ] + }, + { + "name": "tally_mismatch", + "about": "the broadcast poll closed with a tally the replay does not reach (live-events §7)", + "descriptor": "5752443101988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928500406cd8e95d060040420f00000000000000400000000100000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f737407010102ae06000000000000000000000000000000000000000000000000000000000000096d6f64657261746f720001000108080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010058000000000000000000000000000000000000000000000000000000000000000002067370656563680101046f707573000001000000000000100000004000000080bb0000010f0a63616d6572612d37323002020d617630312e302e30354d2e30380b617663312e363430303146010002800268011e0096000000f40100000005d0021e00f4010000dc050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fc12b0170258ce87d6cb935ee8a52798affdabc2bd42448afc1968074e487077eff3418a97c7cfcdca12b2d77529910d94b8ddc4c4e6a06d0e4eae8cfa97102", + "grants": [ + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000000070101020000000000000000000000000000000000000000000000000000000000000000005745503101ae060000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020001011568747470733a2f2f72656c61792e6578616d706c650000a8177e3c0539f41e6c9b83d40829e2f307edfffb32550ecd60e3bd4b821dda5ac91ec5c8b19188a730ea0f0eb411f512dd8c03128dd53236be6a5aa21db0d304", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000100010001000000000000000000000000000000000000000000000000000000000000000000574550310108080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000a4938ff4b55bea84315bb0e0ac10830619d2ff4181e1d6c95205d06f268ad4d1fef18371ea65d03fc0d08f5713baf79e86d7b9dddeda6dacf7892c842fef890e", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000020001010000a874d3c0a3e2ed3410ff8fcad373c97b00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000cc0a03dbb739fbb3b2930097a0f3dedf61cba97ac6dd361a74b7a2fcdea4729653c62254df2b637199019827f0d985af00e3b4ab41dc22684878694a9ab80a0c", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000152f73f95b4fb60a5af17e64975f4de00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c650000c3751b7e6f106c5217ab43900a588947c6ac45b587573e1592b853636310d3cd171cb873976a127c6f50087b73c80c5792012f49f0fef49efeae4d29e556d807", + "57524731013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a0000000002000101000072597590e28f1de5efc0048fc10eb95f00000000000000000000000000000000574550310158000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500008f113eb273113603940999be642873342c9d74ee026e49c969bec9489d9d8c7aa1f1faf71e0f9a4c50e906edb798f24e418f5bd98195ef5ae66201f337811900" + ], + "key_log_head": null, + "chains": [ + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c28589285000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001040002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa15d341a5f8f3665350011af6e1cb707f08a960df9e38cbbbb06f3eb61c0c92f891af1afcff9b556903f0c6b499602117af5b5928d85e08ce769141ba2797bba90802b3f2f1692843f65a7c713d5ce9a877963f451d49d5930de8e0830f7795600", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c285892850100000000000000f158f677824cfdca96097265650b71d22f545f06f17e3ecc1bd01aa21024d31d000000000000000000104000883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaadac8d72255cb0be291be12917055b21dc642ba9d469a24265a1ab95836d6ad113093fd51f4f400fae119c0e96bc46ffee12be5621360a0ba35bdcad51169bfdf77f14a686e7185358767342c40ac67a5e5c0fb7ee0981567d2b62fbaae16584103", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928502000000000000001d940a3fdc07acde1c678221e7804212137b215bee7c8cc45b405084668cbfff0000000000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100020102d2c3573ecd1a131d24e5e96aae6716f01d54ea6333d78fd336803724d614e1bdb5441f0005a570ad35519bf26ffd1f0ad14ad2815d1eebc3e83f765fd8dc6800", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928503000000000000003edea9bbb0af157e6a776ee6b12e6fee85295e59695dd6268e1602b34d7641c00000000000000000001224002df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa100010001f0592a14651a7062642eaf28e333047c88f94a04bf163a0b58fb26b7ba6585f7c8d4493ebdb50c2f3184dc0af223e4efe4516ff22100e3fb7b5d151c7e8dfc05", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928504000000000000001e7bc9c01087c27c8c8737f6d25b3d7a02c8aa405fc83923dd2e0162d9c9fb1840420f000000000000104000fcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c595d14118a463c65e5de942c0276370d89c356e0e3f27a6db71b2cf967f83454b56f039e77cbb6df56beedf741cb136430512c904d980460da259b257fee59a879f5c6b4eea6a252ff2503e324718e2feb728cd439533a351c371f49e1101105", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928505000000000000008c97279bda2646acdbf7c5de17a1f22dd6d83824a00a73ff918e44011da47367e0c810000000000000104000f13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb4aa33bf3baf499bf721c9cbd59bb63ac31dd3788f17935d557aa5df05b08e9fdf84081bf4a470f9c6974012bc665103946c471159790d27a79388f5e7a4e13b8c03dd950a9af79b4b67bb27e850e1df13e81382bb8504a409a39116b9a64be0a", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928506000000000000006da7009e67c115f4e28f5cbaedd9b3e6a08dab41bf35d32cf06af080d6e63d0b804f120000000000001040005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79ba553a1a0d8e74ad9359d6cf08451c5d2830817e29d43a90432349ed87618c65f6bad9885b3fbc86637f4c8fa3ddfc89b0fdd1acfc7a3fe236e3e6bcbf3eab3746c495bb15c2f2ce9413bf1f2bcf7bed791ab08b2c1a60657e132711ec135706", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb988ec20b60d2d23c4c475c1f4e623f115ffbe7659bd0c81c0af9233c2858928507000000000000004f69921d5414af2b4a51e770a438cc57755ff2f15cb479519ff01a85f77ea7d300127a0000000000001121005528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79021d4d984f0d3e652c3649a1bf325c294cb6b4b2c76124d58bdd17491ad7ec19f0f9c924666da93807ba393a0f5ae4f79b136d1bc740b2c0e117ae72d79731fb09" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2000b80b00000102656e160057656c636f6d6520746f207468652073747265616d2eb4cd653cde10a2e448aae06f3a43da32735e8c459100ed497298b7c19dc765f45252d29db4e12a7c0b3cb50f33a93f0ff7d9349ef37ca63244b6d34bfb920805", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa101000000000000003995329f6b1a78e490d75080148e2cf01f27350c7c51e7488cd479955b854ab2c0c62d0000000000000520000b004e65787420746f7069633f020700546f6f6c696e670700526f61646d6170914b002faec41374b4e47dc03996a05ed2bc8db3dc59fd2792b860faad894de4cae4f8f5b7252554739c5e8c441b5f4d64d17f7c713e35e3d156b5445c490204", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb2df53b5dcc0c0ad294a87b904069ccadbde41494fa7e39cbf6720e1b2d5c5aa10200000000000000c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace614c0cf6a000000000000072900c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61402020000000100000056a916341246013f93aca9ed795010b35bf3e0fd37b3ae5571ca8bd0a860598fcfcd53c52bb5ed611d175adfd487da2344b390db7c5c40979e13b0530f3d220c" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0000000000000000000000000000000000000000000000000000000000000000000000000000000000093d000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61401e3b6f361a978bc5704db480d4e18adeff11123102fd8a6c785ce6d5ebbab5dc88331280a540c29d024963b93c035149ffd5ed59e9a1a64fc1225edbc62ada408", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbfcb90cb92576cc567d08bedfa255bb94366c5b882a03ce247745dfd0e32ab09c0100000000000000582c0158a99a98f6a7d4ff0061f897d7a6584747f7f74208e22b9290cdacd68b808d5b00000000000004040004010000d48e1a78461dd62b4fbdd875a118213ea84e248810e6a6e52580e6af3f0687f7408577d4c20e0b62dcca593bdf5418cb73256c3f4a6956c64edbd0b588b8fe09" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bbf13c5bf5891361c68de9a2df70c5613d760e1dd3ca67ce44989f5168db2addfb00000000000000000000000000000000000000000000000000000000000000000000000000000000a08f3e000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace6140111929c98d6472261488c63ce55eb9823bab1c74fe0c0fe31be9e804742e973887194775afc315655a76f9c85d53258140a30db55ae66f2fb54c1523d44a81103" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d7900000000000000000000000000000000000000000000000000000000000000000000000000000000401640000000000000062100c3e24ecdd8c54ab60748c044b1101011975ec79aa080b85adb0eb841e4ace61400a5e21f57a0a23b5d6679af935614c7eeaff52e8188b9a6f434bb20abd314ab75623cdb4fa9ed76e47353717dabbfb475dd16c389cf81250cc96c48ca1ac4c200", + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb5528b645856e07e862f963e5e8663ceb5df25f473f68258e9a9b82cc62041d79010000000000000034db1268f014b0b6314982afc0ef6852c16a63298bc73a97ece67d37cbf57cc9404b4c0000000000000325002300666972737421212120666f6c6c6f7720746865206c696e6b20696e206d79206e616d65e52e03724395f2683ed61f939c193235a53dc9f255bd2466456e51b6e943ab957023fd64ad22f9c41510aa733a786daeea32a076c4dfbba691abbbd427b6620d" + ], + [ + "57455631013a100dd6b60b6753959ec8beaede328fe116a7b600550f5d5f969b1601d7a7bb883c6235a9df7e62f78a406e115dd1369a2db838b3c58f33a14dab416addaada0000000000000000000000000000000000000000000000000000000000000000000000000000000060ec530000000000000b23000244f68aa32c596f08b991e26fd58c501e1d391bdee00d7cc7d79502558888a19a030045537bdf38737b91e221cc208fa0ca82bdf8decc6bf99aed27feea0812a23ac348a82bd7a96dbc54c2e73d64f89d2e2521326925f652ab0310d7129b58cdfb09" + ] + ], + "outcome": "refuse", + "reason": "tally_mismatch", + "at": [ + "record", + 1, + 2 + ] + } + ] +} diff --git a/wai/live-conformance/takes/README.md b/wai/live-conformance/takes/README.md new file mode 100644 index 000000000..9c4d689fe --- /dev/null +++ b/wai/live-conformance/takes/README.md @@ -0,0 +1,91 @@ +# live-conformance/takes — capture binding + +The corpus of [`extensions/capture-binding.md`](../../extensions/capture-binding.md) §13: +takes, each a room (a signed `WRD1` descriptor, its `WRG1` grants, the head of its +authority's key log, and its principals' `WEV1` chains, the device's `take_commit` events +among them), a device-signed `WTM1` take manifest, the uploaded parts, the store's `WUR1` +upload receipts, `WCN1` consent records, and an evaluation instant, with the outcome a take +verifier gives them. + +**Take equivalence.** For each vector, a conforming take verifier given its room, its +`manifest`, its `parts` (each an `index` and its `bytes`, in the order received), its +`receipts` and `consents` in order, and its `evaluated_at` (seconds since 1970) reaches the +outcome the vector states (§9.5): + +- `refuse`: the `reason` and where, `at`: `["room", …]` with the room verifier's own place + (live-rooms §9.1), `["manifest"]`, `["record", c, i]` for record `i` of chain `c`, + `["store"]`, `["receipt", i]` or `["consent", i]`; +- `verdicts`: the `take` id and its `stream_id` (§11.1); the digests of the held + commitments, `commits`, in order; the last held commitment's `size` and `root`; the + `verdicts` of `single_take`, `aligned`, `complete` and `publishable` for each of `live`, + `record`, `distribute` and `train`, each `holds` or the reason it fails; whether the + manifest `stands`; and the `markers` of the room within the master (§10), each with its + `event` digest, its `t`, its `chunk`, and its position `into_chunk` and `into_master` in + microseconds, stated where `aligned` holds. + +A verifier that reaches another outcome, reason, place, verdict, digest or position does not +conform. + +**Provenance.** Generated here: `wai_capture_take_vectors gen` writes every descriptor, +grant, key-log head, record, chunk, manifest, receipt and consent from takes authored in +code, from fixed seeds. Each key is SHA-256 of a fixed label and the principal's index, 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 rooms' `t0` is +2026-10-16T00:00:00Z), and Ed25519 signing is deterministic (RFC 8032), so the file is the +same bytes on every machine. 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 (jwp-receipts §7.2) 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). +- `vectors`: each with `name`, `about`, `descriptor` and `grants` (hexadecimal), + `key_log_head` (a key-log revision's JSON text, or `null`), `chains` (lists of records in + hexadecimal), `manifest`, `parts`, `receipts` and `consents` (hexadecimal), + `evaluated_at`, `outcome`, and as above `reason`, `at`, `take`, `stream_id`, `commits`, + `size`, `root`, `verdicts`, `stands` and `markers`. + +Every take is in one lesson room: a director with the record power, the performer's device +under a grant whose `subject` attribute names the performer, an audience; a recording policy +of mode 1, 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. Vectors: + +- good takes: `lesson` (the director's `record_start` with a four-second count-in, ten + one-second chunks committed every two seconds, two markers, `record_stop`, the closing + commitment, an upload sealed in DE, the performer's consent to live, record and + distribute), `resumed_upload` (the upload interrupted after four chunks and resumed, chunk + 3 sent twice) and `minor_guardian` (a performer the grant marks a minor, under the + guardian's consent); each stands, and `publishable` for `train` fails; +- the negatives of §13, each a single defect: `commit_gap`, `spliced_chunk`, + `reordered_chunk`, `extra_chunk`, `missing_chunk` (`complete` fails and `single-take` + holds), `late_commit`, `root_not_extending`, `misaligned`, `consent_missing`, + `consent_expired`, `consent_revoked`, `minor_without_guardian` and `device_not_bound`; +- one vector for each other reason of §12, a manifest of another room, a manifest and a + consent with a bad signature, and a room that refuses the device's first commitment. + +## Running + +``` +cd ../../wai-rs +cargo run --no-default-features --features capture_take --bin wai_capture_take_vectors -- verify ../live-conformance/takes +cargo run --no-default-features --features capture_take --bin wai_capture_take_vectors -- gen ../live-conformance/takes # regenerate +cargo test --no-default-features --features capture_take --test capture_take +cd ../live-conformance +python3 capture_take_verify.py takes +``` + +`wai_capture_take_vectors verify` and `tests/capture_take.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 §12 and `delivery_gap` to appear, the three good takes to stand, and §12 to list +exactly the reasons the reference reports. `capture_take_verify.py` is the second +implementation, written from the extension's text and sharing no code with `wai-rs`: it +verifies the room with `live_rooms_verify.py` (which verifies every event with +`live_events_verify.py`), gives every vector the same outcome, requires the same coverage, +and then mutates copies of the corpus, one defect each (a part's byte, two parts swapped, a +part dropped, a signature's byte, a descriptor's byte, the seal removed, a consent's byte, a +commitment not delivered, a later evaluation instant, and stated roots, ids, positions, +verdicts, places and reasons changed), each of which must fail. Pass = an exit status of 0 +from each. diff --git a/wai/live-conformance/takes/vectors.json b/wai/live-conformance/takes/vectors.json new file mode 100644 index 000000000..283b60ae8 --- /dev/null +++ b/wai/live-conformance/takes/vectors.json @@ -0,0 +1,4442 @@ +{ + "corpus": "wai.capture.take", + "extension": "extensions/capture-binding.md", + "principals": { + "authority": "d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd", + "relay": "0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b72", + "director": "d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52", + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "performer": "59425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699", + "viewer": "78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c6", + "store": "0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13", + "guardian": "0f5abc454ea1768f79427030f81907cb6f01b9c5e15cecbc85dd79435e22f1d4", + "minor": "e8bd88c2c452b210da597e83fecd410304ed8909ffb2d16f3e0195cb5597c79c", + "impostor": "aa26ee0d0025f9b60f30a73d2c67159f09f6d1c678b11f3cb528d5e4f2d6f198", + "log_root": "93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c", + "log_next": "8369fef0a61a9a51088aa48364b64028f16d03391ac681b915db3c95309e0750" + }, + "vectors": [ + { + "name": "lesson", + "about": "a lesson take: the director's remote record_start with a four-second count-in, the performer's device committing every two seconds while it captures ten one-second chunks, the director's markers, record_stop and the closing commitment, an upload sealed by the store in DE within the room's region pin, and the performer's consent to live, record and distribute (not train)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000037090d56c333ad6c4392ffbb8f80b7854c7ae3d562e182d6b76685f99db2ec1f0100000000000000c0c1702a010000000004802a0100000055000000000000003b9b3da8c3121692dbe9b75ff7b37a77773cf7d71d8b7c885253d5b3855c53b902000000000000000004802a0100000040468f2a010000003a0000000000000097f5ee9829746c16c29946a44489846e4a385eb6d62804ba22a18a99a92642ab030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a480600000000000000000dbd2a01000000404fcc2a010000004e000000000000002b869dfefc2fe0873e06d23c09f1629470a788c6b8f2aa8e6aafb1298cd73fe60700000000000000404fcc2a010000008091db2a0100000033000000000000009f10cb7a3feccf63f5c0c398375eaf998628d314dc8159d15845fe5a0f8a006b08000000000000008091db2a01000000c0d3ea2a0100000058000000000000008b03281ec96d96d0e76e48ef184b7a60d4856eddf77629af961fe54746404ef60900000000000000c0d3ea2a010000000016fa2a010000003d000000000000001fb42eb87b4ea4dc72d02c9e6ea82aab91be4bbef122892b8921e2f552a462678883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f2506000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262139c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe48967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699c874fbe7fe39aba8993c0ebb1a0647056ea2fe4fff0d2fcc29694944a8a8c58fee5e2f555f41e799748151133d481ac6eec8d5578c88da05ca67d552b6f4d691bc26594f33cac8c4d43f411570c4ce5daa62bf815c3e27ee72181c28abdff101", + "parts": [ + { + "index": 0, + "bytes": "7eb57dd6ea48bd6e750625aa7e27550ca3420032751c71a7d297b6461d26b5954525542bc117fa7ee7cfe6f32ba1826a" + }, + { + "index": 1, + "bytes": "5a3084a18d88da020a4b71b5bf60a1c535d7c9902b990e26ec748fce394af54cbbe92f37ab82295cd3fb69a6adac53833c669739146cbd3c9e7115bf2f1a10a3f7588995e23fe777121cdc4cf95f1bb9cdff24af20" + }, + { + "index": 2, + "bytes": "48ebf0b168a3c7fc0c55b3c91416022da660a350dd70aef26ddc6a124ed3f89554cbaa4b0a623251e046c5d051bb2184160fb0d45061c051e7cc" + }, + { + "index": 3, + "bytes": "b89715796bae21b2526339343c05418d5d89c863b331588fe0005f588148aca6c1d6f8fabc0c1453628552025d98e640e92c6e1bc36306e50db0fe471ca92773b96f17ab3617a16f0685f0135d6f061965e8a49060fd5fc6fb32e22e2dd9fa" + }, + { + "index": 4, + "bytes": "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43" + }, + { + "index": 5, + "bytes": "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + }, + { + "index": 6, + "bytes": "99adaa567aa5f9bf37864924714aadc3d468ca77dbdd919f43af6abc0862cca7490e2a3a2f47975d05df11e309b62230f795056f3ad5b429ac5357f83b614900cc654b83885b2aa9512497ba8ea4" + }, + { + "index": 7, + "bytes": "0cd5712f2691897913959444771fc75fc0c6c517527433a9c0e54d6760ace4a225feb80ec74ed745b6a70548e3bdff6b4bf85e" + }, + { + "index": 8, + "bytes": "bc2cfa9caa3a36a92f97d0b19cb6c815157590e91ad7b7dd50ffe220aafb5cc005b4f056a39062a4f38637accc3fba12e930f7fccc2d4fae10549574fef00bd503172f07003b0f44e103650fac84e96c762b8e0a5203e7f3" + }, + { + "index": 9, + "bytes": "4ae0c5cbc03353d721157376812f9a91edad1f0cde378bdfc4acb168d45c33d36051d8233de27c78ee8d85c0e4e145904680d83d59be4e766cd1988ca9" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f254445bae353aeb0a1752cf392f5f3c50d80d0afad5039fad420dd4a03a309bb3373d1a7c62b068c0730ce2d762d35b7f8a84bbe9c9a941d93b8704b2a31a40c266b0d", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000cdaad304e1328ac3b9267fabcbbd5504b6c6fe56ef14146ec6c546c6a1cb90c280faf8d9e95d0600040a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25444503c547cb38bfffbda98c6cdb820b320445d1692eb34da06c7621bb9f4a3812460832a53c2495a648e4662481dcc100150c339c6734bfa54036fd54831cc5230d" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000e300c25e7ac42dc73953adf59c8cd2a19355ea54b3ace510b4515dbb37cfbd7e7a841e15c8f8f649503d8190f46ba6223e86e6a3c3d3e33384ffc907b274bfb2f630a81ecd47ab9061238e930050e902" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0", + "108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621", + "39c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe4", + "8967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad", + "5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e8" + ], + "size": 10, + "root": "8883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": true, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "resumed_upload", + "about": "the lesson take with an upload interrupted after four chunks and resumed: the store's receipts run open, progress, resume, progress, sealed, and chunk 3 is sent again after the interruption", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000008df84767b49af62c5ce11be1ead5ccea796e542b87cce9e37886470b76035564000efad5feffffff001f88ca47fb3c594071a9cc8b30e2469a179a93813f08dd584eceb2d9080ad8d94f24155688bd5ab3fbdafd7826019f8805358456a8a497e6e0b7a9dea0d5160e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000d6fbf4398bb57e9dcab3e04bd5e9b28c36432d598d580183dc9162461f010608602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002d6fbf4398bb57e9dcab3e04bd5e9b28c36432d598d580183dc9162461f01060802000000000000000400000000000000944eb141bb0b9aed3026ac76d46f73fc2bd892cdb18e641461b03f65714a58f8000efad5feffffff018839fd3b75418d940fa5f2430315e6e8b6c8b03715fe1d81993248ac02feacdecfac6fe11596887f8c18e5154800bbcac9cb32e548721979994111770f5082b925ce3ed3fe856aaa7f3820a343f5798c7bcdfdda1a5fe57336126985fa0ae707", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5030000000000000024db4408455639991cb89017db14510d87ac0ac6989a93b3ff95002e9a1bce90e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e030000000224db4408455639991cb89017db14510d87ac0ac6989a93b3ff95002e9a1bce900400000000000000060000000000000083493e63c7c91f4ef9228a3e4ed3b5e5db1343ae1781e5d77ddc734bc0801606000efad5feffffff01eb8739f412681271badc7184c219d4dea846a403efcbf6e87fbc68a6b07c8593e782232778c4cfacd213747336bc4064cbc6aa8781bc1793f1db562d279ff1022c3fbb19bc8436f2719783a5ba2583b3024b0345c1303f428a0095b02fdb3c03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000400da1d3b872d503c17e84ff3a93268eee645d316203e525da7647eea251ee266033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002400da1d3b872d503c17e84ff3a93268eee645d316203e525da7647eea251ee2606000000000000000800000000000000bb4ad80ca0ef12afd1c5a29b942d5df7e59274671125bd999e0daf83db478a26000efad5feffffff03eb8739f412681271badc7184c219d4dea846a403efcbf6e87fbc68a6b07c85938f481901989d92a5de27a6a6d6db3d020ce0a183cea8f08ef31433b8b0b0f6a5944eb141bb0b9aed3026ac76d46f73fc2bd892cdb18e641461b03f65714a58f8be51852aa57be5ec74cf68fec25637f953e46cf097aa7808bb1743d55284d655a90d90aa427695cfe8168f2cc95187a4291389ac9d2d7cedb93bb9c930af4105", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000565dc67ca6cda3097fe687ba2a4358ac02ccc0b89530ebd306888c7f6e88bbcc803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003565dc67ca6cda3097fe687ba2a4358ac02ccc0b89530ebd306888c7f6e88bbcc08000000000000000a0000000000000007fc386f1d6a0e3ef14a1804bd8b3ccca41ac3c2b0bc44ba6ff6fdb1a045fb8d000efad5feffffff01eb0936fa42a29520d1ab4976d95d69658c8898e8d39c9c52773c2f82f91f2170b2bac4c16c83ab5b83b070eb9953ce7786c032dfa2e1a4e3878b1dd31aa51c88b165508c4600d339c4932e87557446b3ac6683415b9c0282c5487be13479cc0f" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000000fc635878b5017892ef56f4d25447d4f6f663e347e2447987f3e230ca128fc080100000000000000c0c1702a010000000004802a0100000055000000000000005b480d41d7fac9c9b7fe2869e605954d5017b550eeab9edc0b3370c98102d2e702000000000000000004802a0100000040468f2a010000003a00000000000000b92d3732485d0e325abd2ab1f44d5b56a01ac80400b8ae30d3628118beb285dc030000000000000040468f2a0100000080889e2a010000005f00000000000000c3b6a20aaa85aa617d36a4be049c78e3355fd77acb0dd6d917131f2dc1ad47f8040000000000000080889e2a01000000c0caad2a010000004400000000000000e2b413d989d72a6de91f9f663da2622d7b7e77ee48be1a9f699973850014af720500000000000000c0caad2a01000000000dbd2a0100000069000000000000000c2f051485454b3ff7187d4dc4d49a6073e78b247b0e619b5d8041c3af71d5a80600000000000000000dbd2a01000000404fcc2a010000004e0000000000000005c6e42a34256a53bb222c937e591584f376f414737228938fcc98198be87de90700000000000000404fcc2a010000008091db2a010000003300000000000000b514d59773f2e59dea394cc401772de8eb581de99a7f02a0e0d0b3e3b393248208000000000000008091db2a01000000c0d3ea2a0100000058000000000000003a5897bd90cc868243f61f36c4e07d99a54d8ab4590e3fde2cd78ed6fb1d7c960900000000000000c0d3ea2a010000000016fa2a010000003d000000000000003314e45c704095d35e8ed93a5b2aa2f211739573fdf448f728a35f92348b77a807fc386f1d6a0e3ef14a1804bd8b3ccca41ac3c2b0bc44ba6ff6fdb1a045fb8d06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6d6fbf4398bb57e9dcab3e04bd5e9b28c36432d598d580183dc9162461f01060824db4408455639991cb89017db14510d87ac0ac6989a93b3ff95002e9a1bce90400da1d3b872d503c17e84ff3a93268eee645d316203e525da7647eea251ee26565dc67ca6cda3097fe687ba2a4358ac02ccc0b89530ebd306888c7f6e88bbcc3d019d5ac2637f3739cd87d16daf1d0857c8c3ba89268b9abe674a9b315b58340159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699c1be8b109ff84cb3b5b1e5ebb7c8575705847ed1a79a798e2c43c50835a22f31f04069b8c1fdccd74a0f7b7d7102753977126b42f0a2f7828bb61c58bd2b5b825200ad23eee02eae9919ff56de417b67d7261b41ae6260e26d220e15d0990607", + "parts": [ + { + "index": 0, + "bytes": "0948a2d12f15dafd7d8062808b8c1a8d6fb0e5d429998de5b0097117ccf2948a154ac1c00a848015ed414d5e7337d783" + }, + { + "index": 1, + "bytes": "4c1d9cba1d8a6a1ba39bc552487e7dbdcd278f81c744cff652f66cb13aa3a2ebe549eb51547c9dd506e3080402c611bdaf2151b45a11dc8e22624e152992d290f45db31679915d3259f135435d98f76d01478b72c6" + }, + { + "index": 2, + "bytes": "ed3046d8ffb742d36cec75ae56cc66daac7e065eea3bb753153fd53dafc893dc669bbc22391a4a00cfabb16806f19e7eb2e5d40b10803090933f" + }, + { + "index": 3, + "bytes": "5419b24fc97380a7fe5013c00e3f58347d7fbb4f99581ff6d7ce4f228b0ef652b39e79c2e8c5453c735dc077c2487ccbe5623d07ff4ca34cd8ed53544668a5e5b0cc2e1f6c2a1aa1f48ff068357ab7a9f31db543786f735c2e9a56208ca02f" + }, + { + "index": 3, + "bytes": "5419b24fc97380a7fe5013c00e3f58347d7fbb4f99581ff6d7ce4f228b0ef652b39e79c2e8c5453c735dc077c2487ccbe5623d07ff4ca34cd8ed53544668a5e5b0cc2e1f6c2a1aa1f48ff068357ab7a9f31db543786f735c2e9a56208ca02f" + }, + { + "index": 4, + "bytes": "e47769f378ccd5c7efc50e5706d2907ac8012c23f9afbe15e6086aae309146c6f371288a7c39d26f7f719e4b4fd333859c62060198f4be943ac0d7d5467823b9ab011597" + }, + { + "index": 5, + "bytes": "58c031be876a56d85749ce435b61754156dff9cce592dac560c999f6ed6e00675191fab88edff9c11502294b37529e2ddb8e3a4b984aecb037fa0b97c6ad41d56c9664b4a90088fc8d0696efca2d1a8b60380ed801d9207f9909bb218edb362b8d6edb2f581e6ee0b5" + }, + { + "index": 6, + "bytes": "95716b403a55434b7b2948ea8b763ac6e05b41b480165c2d73bc83dad9f2f0b40929df38fbd60fbc21df720aa77060d389e31218681367fb2658ab12f924a5cac7d149c1c48a7988d14bb650d48d" + }, + { + "index": 7, + "bytes": "d9461dc91e9a44222db0dd8bec4485d83acc4a819c9f60b6a45c32a4a329379289580cb80730793ac6debfc79137e3e2c09888" + }, + { + "index": 8, + "bytes": "01db2b59479eae46b3e7340f604c3634c246dd16abebcdba8f7adb9740a7abfb8f1790a3bf88064c688bc16c088204fb345188ef8abd0a87527867c72f264233f4346392be97d6d493383d50dd6bb6443b2af260052d8052" + }, + { + "index": 9, + "bytes": "c316bfeff269aa37773fc7c1ecdab6d79d35fea0efe6eed392471088cd270a69ac262f5fa54aa631829e338926dfcffd7bcb9dc32d362ebe062b457f98" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020400000000000000944eb141bb0b9aed3026ac76d46f73fc2bd892cdb18e641461b03f65714a58f84445840d8501dedff99e274ce2f091e0f56d63e3cc8539b8f121460d19eee1c60d787bafc70f1ec18acbb9f73090d481890fe554623da48100940699b3e40f99660b", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000d1fe3016fe3e5d3fd3adbd23d2ae108b30d3847e450df1cf7cc210e8485ae03380faf8d9e95d0600030400000000000000944eb141bb0b9aed3026ac76d46f73fc2bd892cdb18e641461b03f65714a58f844450d3a788f182354e1ed9cdc2d50b6f33d6df7512d7a195bee0cbab7dc519d87d4f5a65a132b63941b839aae8dbf31f39103c504815dfd0533c424c74673360408", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000000000000f28ca3a96dc5c489d814aed433ba3c9e36a60d96a90cc48dea96d666350f503a40c126dae95d0600020a0000000000000007fc386f1d6a0e3ef14a1804bd8b3ccca41ac3c2b0bc44ba6ff6fdb1a045fb8d4445ff773cc49913a72e815996f365e9f6bd8e0ae4cb5cec71a943d754b5a83139009fcec00c20b5960b9809e95c2da65d3e54d7298598432d60ae8b497d9aeff201", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000000000006946bf2bcffe00f5208011fdcf5af2b3e413de89fc154a2a6f028a60c2fb3587008854dae95d0600040a0000000000000007fc386f1d6a0e3ef14a1804bd8b3ccca41ac3c2b0bc44ba6ff6fdb1a045fb8d4445b2bf44f9c3acc85c941b0f2e4f11c4c0036793b481638aa70248f04b4b9c05356778a76d5e19bd4a6a09bae883fb0ccd93b6ecb22b5f4e52ba3522aec4fe1203" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000004d629bdd9db49fa3a2ffb7746719bfad2311a38d56989d6ee8d86ff43c152fb951cdcde9625fed4f555c71df31b0497b7c27b1a55dd467c00c9d3e387b50304936d504be200be557d03d8dacd90ea104" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "d6fbf4398bb57e9dcab3e04bd5e9b28c36432d598d580183dc9162461f010608", + "24db4408455639991cb89017db14510d87ac0ac6989a93b3ff95002e9a1bce90", + "400da1d3b872d503c17e84ff3a93268eee645d316203e525da7647eea251ee26", + "565dc67ca6cda3097fe687ba2a4358ac02ccc0b89530ebd306888c7f6e88bbcc", + "3d019d5ac2637f3739cd87d16daf1d0857c8c3ba89268b9abe674a9b315b5834" + ], + "size": 10, + "root": "07fc386f1d6a0e3ef14a1804bd8b3ccca41ac3c2b0bc44ba6ff6fdb1a045fb8d", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": true, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "minor_guardian", + "about": "an audition take by a performer the room authority marks a minor in the device's grant, under a consent the guardian signs", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655600056d696e6f72040074727565077375626a656374400065386264383863326334353262323130646135393765383366656364343130333034656438393039666662326431366633653031393563623535393763373963bd08a7b905e11af569e31b06dc79c56caa1a24f5e40b9516649daf9cfb9212f0ca99de021aa0a81dc962f09f9d756f735e3ddc6f44819fcf1024104ac9b26609", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5a92483e929f70df5d360ce7415def67a65500429d15ee59848e8eb87ad79a91ea2fd13942c30fb1390a85950d140059cd9c074a230ac790cb9a018fcdd2cbb16904f5445dcf3df0c3f27896553f87f1922b824a7bd7a88a7fbc142133b1cd00b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720200000000000000a3c2a2a40d1f9f0e70dd3df13497bf855f0eac0b95ad62c49207c3eb4b19d1db20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecb8a9e52b127a6c675fb6e9a2e8a2d3f7e67be99c8db4af6b15f9890a54b4ad40388a445038d30f5635c554004679828775942c773a4cbdac8fb09f536c27cb09", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000003c179b699ea2fed8f53092b562272d08e8bda1f756b3a35f761f289841640b3d40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000101016db7e37c92aee72320c299bc672f5e9e4deaba492adbf268ffe4749386dadfe9939981cd3cb5d340a5df964918af2b1dfe222543b8d94a1af187b91294312404", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000fa92e6177710c309a0298a6062adc18639499abbfec6677b67f59bce983602ac40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202039a6e978471944a41ad6752a87192359f410ce70768a281e4efc16d18f483aec5c99f4ca47b19d7246583af1d33048bbd0ee9cf408bdafcbeb2fe1e624058d306", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7205000000000000004903d7a303492b16514bff4ced16b6fa3a96d069953225c477acc01481ff5d5a40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520001000112dd287bad93c0d36361443dcd923398856dd72c726d97b4a15e8b26c24382d9462d003892f35697e64148fd8f66fbd3bf0becd003170896c980b0d2dc618302" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000ea4a18ebaa0e228bc6c4c70e15a90e54953ebdf90590dafdb4086668a83f7b49000efad5feffffff005946819e0a074b91c15691500aa0ccb57fe412907bcf64c53b23d633b3fae1ab14400f560e6d319723b592635ac0e9a1bc79c11166c07b87e378b2c6cf91f008", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000083619bdda0b893d251173b5becf1c20fa109fd43376c87f59902597b60b504cb602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000283619bdda0b893d251173b5becf1c20fa109fd43376c87f59902597b60b504cb020000000000000004000000000000008aeb7834f2934bdda4567abbfa1bbdf459d4701240961b66b83920da9bb782d4000efad5feffffff01497a5dd2e7f52b2765665b3864f1030ce4d0f18fc76515c7f9b970909e140f8a98e7c3147ca307cb868965eaeba92b1514c6e14a5b05c2981232cbd378529dbdbc13ec7b478ced57f56951759b79639aa2303a09dd26669efdfa886e492ceb07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000c147fa2734189cd712394b5d5e5054d4e3016b436cbc36caa21689a0969e4d24e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002c147fa2734189cd712394b5d5e5054d4e3016b436cbc36caa21689a0969e4d2404000000000000000600000000000000e7fa84c181f9272b3e12dae76ad43d7502d8e0d922def8c8d2b27dd85cf6158c000efad5feffffff019d0222eed099145b7cf90f6321e4c5669eded191423f5d1585f400b96facc8177b2210647580354004e5253783e59dcaa626fc8a9484499c11feab4a3df95008b8579f20937f86734b15e4a6a9ddad5dfb2e3088d416b13a002f4504cb9cbd05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000dc7c9481e31fc40715087717fde63540874fb9983ee4ebb6be484de2866de2776033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002dc7c9481e31fc40715087717fde63540874fb9983ee4ebb6be484de2866de27706000000000000000800000000000000d7c33e936fb0b99c3ca6558848f8e576c8bd0d27979c96b9ad8b2015c212b75d000efad5feffffff039d0222eed099145b7cf90f6321e4c5669eded191423f5d1585f400b96facc817573f1f6410f3dfbc3a0fbf2e5e7b70fd28bbac7734dc79841d8fede0810cff088aeb7834f2934bdda4567abbfa1bbdf459d4701240961b66b83920da9bb782d42f1148e9cb3f1b5219822a40fb517412c18f89f94d161472ffca3c6182882310fd64bf7dce0f90900dea3b2bfac8cd3ea9430daa3dc4de85ed687fd2cd1cde04", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000ab391a1b53f3dde74033487a36b2b8429f635ccc3cc48552841c9a95469920ac803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003ab391a1b53f3dde74033487a36b2b8429f635ccc3cc48552841c9a95469920ac08000000000000000a00000000000000030757708d1353c31ea3d83f6d90c7b11c082366b2f63ac0ac4b39ee1568fa0b000efad5feffffff01278f5a8e7c5c4651821dfc1e5ff305401a3b4457186c2988048ecd0a37ee65b31f5a5a54b9ae5bb915019c0e897c32a5a5b9be40fdf014008a92a3b9c63ac76951b2f03b0ad6cc07ea37f1c8aa78fb3d79b484f3ae3258cd5882ddd552d1d10f" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5e8bd88c2c452b210da597e83fecd410304ed8909ffb2d16f3e0195cb5597c79ca23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000d1a301e3a7bf031fd4968f217c9f8ca749d527ebfddc0c4de2c452d81d8413de0100000000000000c0c1702a010000000004802a01000000550000000000000053dadc88436915040c5fb6ddb540e68a5925301c400bd710d44690befe707cad02000000000000000004802a0100000040468f2a010000003a00000000000000a91d4e8157f02f4409a7c2a6a97d96c06f0ef4b4b0a891fa002b22a274248203030000000000000040468f2a0100000080889e2a010000005f0000000000000030bedd31d7dff8ad02d9722b1aab6d3de3f501b783b439e68d5b2be286ad2f19040000000000000080889e2a01000000c0caad2a010000004400000000000000c80fe8eeb61038cdda8276a21ecc0305fbd36eb31048dcdf2241dcd0cc24f7b10500000000000000c0caad2a01000000000dbd2a010000006900000000000000e1113029c34b4b38ccae877b05981e22b6d14b7db2717ae259066741666168770600000000000000000dbd2a01000000404fcc2a010000004e00000000000000750373266335d2e67ea90824a41b63657069f1adde2317aceec20185ee957a920700000000000000404fcc2a010000008091db2a0100000033000000000000009b9256cd40eda2544c12870d99ded811ce38884309330664db1ffe53ef3501f708000000000000008091db2a01000000c0d3ea2a01000000580000000000000043f27dc9b375c5cf536e7b47b966a2ddeef84457d0745e2b0d8692291e3c37d70900000000000000c0d3ea2a010000000016fa2a010000003d000000000000006c7d73199478eb1a83f7c87339cd6e4a12dc3f99e36fb3215e86cc24e67aba0e030757708d1353c31ea3d83f6d90c7b11c082366b2f63ac0ac4b39ee1568fa0b06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e683619bdda0b893d251173b5becf1c20fa109fd43376c87f59902597b60b504cbc147fa2734189cd712394b5d5e5054d4e3016b436cbc36caa21689a0969e4d24dc7c9481e31fc40715087717fde63540874fb9983ee4ebb6be484de2866de277ab391a1b53f3dde74033487a36b2b8429f635ccc3cc48552841c9a95469920acac5d0b9551871676f3b9586269e746581c260ccb2a0d5490f88ab78f15654a4301e8bd88c2c452b210da597e83fecd410304ed8909ffb2d16f3e0195cb5597c79c5bc4d6c1e24d7386056d14a5c160372652242e6644764f1ec376e1e3a72ccc930bc097c0a288585091f11060e321532faffcef9da3f614f705a0d32880ae502e2dd989299cd43a2988458533bf10a2eb59fb2ebc97a69b10dabc7366d4aba506", + "parts": [ + { + "index": 0, + "bytes": "838ec6eb480bc71e3d409228f9659fa3f80f4c94625e0252c1897ed2b69d5d8deb66356eadb391d8f30fa762ae469435" + }, + { + "index": 1, + "bytes": "0bd18fa0d97951b49e17cb8980bf4d7992672d0834477751a7624da16b04daba201ba5d0c61d68f85f7f5c3c2f93b2f3634f79ad0a0a15e8b84b71fb653edaba27ee45cf4ce2be2f68fd2e7b38b6e9dc2c7e600e69" + }, + { + "index": 2, + "bytes": "dd70cf4f1aa8991e9a09a5481f4f48118e81704b9423420d7411788f6ecd535c144cc064eeebe90254253e04bc7c6bf909cfef28d824730a7613" + }, + { + "index": 3, + "bytes": "306a2fb03bf462abcb6f104563dee961fc756035ba1be527d6a787a3d1f1e6c6163e8b2220c6da72b440050bf5301d6e2164a5ffa24d70cc0ed076981599ebe1ec119f11480ee88212150deaee7fc819dc8e2bc9a3eb325c016c2c22fa6612" + }, + { + "index": 4, + "bytes": "f47f9df5db0620f7ad20ecbad5dd40f9483e6bb8c6eed37bcfef9281c35d37a9abe41f3ff3b8c43b239fa7cae815684ff8d8e9d5c7f691db5281a1c8138c9c27f0b1e1d4" + }, + { + "index": 5, + "bytes": "4b855aa11f6749d595a8b9ab4a9648dd565bd989273d62b454ecd888a6f36a660e8e108b4082c12aa1eb410f05f546d82aa720636fe8e0c4367e74e03df45c86659226fc8e9f533ae8fc528d55e082b71eb248b15f887e758945c4fddfa8f016471bc56ab7ac3f3399" + }, + { + "index": 6, + "bytes": "547af8eae9b72978be453fd5ac0bd045e92b5a704211245c48a718f63db3501bbc55c4fcc582f3d88771eade42fa8977174b09369dcb8d3a8f25edd480f4b05b2680a1cf62ff6d553f617da88dd6" + }, + { + "index": 7, + "bytes": "1fd860707eaafef61b8b3f94c76be6aa013da535ccb44e00fac4f16a8f84f134318e0da5f868244493ba1c0702925ea4d75d16" + }, + { + "index": 8, + "bytes": "a973c0056462878612631c800d48411a525be0aa0fad2ec420edc3dba5d1bf94cd690cbf7dc64fd5d2ff79440330e87fe8e6539a3a29ddfefe716ec265f7c0b4895ccdfbad66e1ec4b90e2c4fac929bbe12674c27181f2b6" + }, + { + "index": 9, + "bytes": "9b0b1aefcd867c713712c108f7c3257db9f534cf89a2a9b48e3a4f73041e0470a851193020a7bb34a571fe0694b3a96d15429270cab4fb39dd4b69dcc1" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000030757708d1353c31ea3d83f6d90c7b11c082366b2f63ac0ac4b39ee1568fa0b4445a5df327a844f41e50febcbad18b5fd3823b644744f2d2a38490f06aa2140a11eba1cd2fcffd1a0705cdbcdd52a899cd67d536ff6602dcaf819e7540112b1e604", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000a4ff801952f9451065b6080303af7b84c32d125ec1e6e45dc44b9f04201fec5580faf8d9e95d0600040a00000000000000030757708d1353c31ea3d83f6d90c7b11c082366b2f63ac0ac4b39ee1568fa0b44456872c3e20a10586d7e0bf44248ab4edb5183f709fcadaeef4152d551a3326a8628476ddeecf0a0c02e5eed597d10effa7ad296515386139b5f59ca8df220e403" + ], + "consents": [ + "57434e3101e8bd88c2c452b210da597e83fecd410304ed8909ffb2d16f3e0195cb5597c79c010f5abc454ea1768f79427030f81907cb6f01b9c5e15cecbc85dd79435e22f1d4075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000f3406e7fa2c6d19754adb443f11ec26f1b7f427c03d42ef0042fe165bedf0e4190f8d6ef63df22cf7768fc687b761330d744bd6526fb7875700ab8153039037f40c79b5c9a221d96f8fb52fcfb182801" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "83619bdda0b893d251173b5becf1c20fa109fd43376c87f59902597b60b504cb", + "c147fa2734189cd712394b5d5e5054d4e3016b436cbc36caa21689a0969e4d24", + "dc7c9481e31fc40715087717fde63540874fb9983ee4ebb6be484de2866de277", + "ab391a1b53f3dde74033487a36b2b8429f635ccc3cc48552841c9a95469920ac", + "ac5d0b9551871676f3b9586269e746581c260ccb2a0d5490f88ab78f15654a43" + ], + "size": 10, + "root": "030757708d1353c31ea3d83f6d90c7b11c082366b2f63ac0ac4b39ee1568fa0b", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": true, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "commit_gap", + "about": "commitment 2 not delivered by the relay: the device's chain has a gap where the manifest lists it (§9.4 single-take 1); aligned and complete hold", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000065839b7c9a2e5272c5054002155793f609688673dfbe546abe0f686928de582000efad5feffffff00e87baa0aa89bfd446691765061b4cc76c802f7d3d373dc2a207c743b680ebc4b0e874da52eefd496998781f42057f6ddc643e54b33769b5ee7bf662d9827890b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000006bdf44c5965f241d1fada0d2bc5c587e3628b7bea79cb18a13b2a6b265df4658e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000026bdf44c5965f241d1fada0d2bc5c587e3628b7bea79cb18a13b2a6b265df46580400000000000000060000000000000018b9feece69e2d08608e679ce85d457425709831f6726efed431d7f160eb9819000efad5feffffff01d63c40dcb3c068079a566096bde31b70c78022b351a5a5dcd1b56b521c24bf1d5539b17c7c1172dff51efbc5648a6cf0a3a9d0b94563422c7c5ce170a6b5ab39bd1edead7f9bee2a0e9c3be10404f2efb5ff81201f9dc37ff237d059b23b6d0a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000003a707bcbf00a4001d4f2623e963b2a09fa315cf526a1cfb5496766f7015054066033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000023a707bcbf00a4001d4f2623e963b2a09fa315cf526a1cfb5496766f7015054060600000000000000080000000000000006ba71175636e051273d51b7db8470a340737bd491ca735122c0e09eedf0097a000efad5feffffff03d63c40dcb3c068079a566096bde31b70c78022b351a5a5dcd1b56b521c24bf1d6dc9c25a2b330024eacf278d0872f505e474f72ff06f4b9dde900beb52a664c153e34248038244792fc01e74cdf0a22862f0e0f6fa98f1092d509a2d72c36d8f241846b0d0eb7596ece208fa5716b72974ab7726a12a3f69aaa7aa125171af41d09dd1fe6cd3fe6d5ec34439a64aeb4004473f56ddf3b31121fb3ff23806540e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000fb9985baaff9aff0c9b96c7bc168d42d5f1530c85686232c1417ba1efc6b7bf8803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003fb9985baaff9aff0c9b96c7bc168d42d5f1530c85686232c1417ba1efc6b7bf808000000000000000a000000000000009d5439a6a829b9753b95857a76a82cde614a40939c927104e510248e9b496c7a000efad5feffffff016d85b525f4ce23a60bfb61d86482b1336a30ff4443cc16b6f6c13fc76720f4408939430b913a777b530233943558b7968251a9b358879e591cb311e1a57bc450a75149fb7cff98838e809b36717cd8e5dd106c3d6979dc89d98aa9fc4fcc9203" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000008df5ba309e769d0a72c737b3e4a6b424ed700fde115dc05b6f0e9edbc8d531e10100000000000000c0c1702a010000000004802a01000000550000000000000055e7c1eb978ff64fb10113779ec24e186c52e972c1b2394b1ad5cbc776b9f1d602000000000000000004802a0100000040468f2a010000003a000000000000002aeee66f44bcabcd007cd3418f8eb3451238ac22676cb70c3d6d59286970f79b030000000000000040468f2a0100000080889e2a010000005f00000000000000cc7e144fe4fe528bc75e29a15c38f6745ea6faf05b9cf01234896373ad273791040000000000000080889e2a01000000c0caad2a01000000440000000000000019bdd00bfd9132b8c68433c22ad792561103b79a2b889f27b28aeda4e416243a0500000000000000c0caad2a01000000000dbd2a010000006900000000000000413cc82b273af11d06665c2e76f92908b1a60fedb3d4fb572d1ced87a0e87b680600000000000000000dbd2a01000000404fcc2a010000004e000000000000009e8c8368aabb05d7601eb2b61c044c2051566147f29df9bc8f57b8c12e744ccd0700000000000000404fcc2a010000008091db2a0100000033000000000000003b3c4dbdc393baf97f0dc4942163e05b4f9c9fd79db9cc7f6d974d439c04eae908000000000000008091db2a01000000c0d3ea2a01000000580000000000000063a5ff794a0d034842b6e99f5ddbc4327b5840c91191b7cf3ff754a80bd3d1040900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000080e0e7835199fb91ddcb819796c7aa3f34fdfa22037dccfe0f3cebea15fff2659d5439a6a829b9753b95857a76a82cde614a40939c927104e510248e9b496c7a06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e64168024554c44e1b37107ee3fcf38b48b90ed9b732b82685fb0c9c8fcbb565e56bdf44c5965f241d1fada0d2bc5c587e3628b7bea79cb18a13b2a6b265df46583a707bcbf00a4001d4f2623e963b2a09fa315cf526a1cfb5496766f701505406fb9985baaff9aff0c9b96c7bc168d42d5f1530c85686232c1417ba1efc6b7bf8014f52a86bcb1e59721ed890ba32612e890d849e40301fd4ed896612c1c33d1d0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699c838427ef1081660742dbed807130c7ef8c80c0b0e0d47c1cb319ea02d04211e1b32f887f8dad149a173f9f4a7cd4bd48c1b1069159af29133ad3bdeb76cd01240ddbb375df98fb0ca6691748edb6384a25e32b9e0e4197e866f879bd3007707", + "parts": [ + { + "index": 0, + "bytes": "8e9a2d98917345efe6e4e116951fa181bee147f1c8f627eb92d8f680f9264a6a854825bc4478bc8b0a8a594863469571" + }, + { + "index": 1, + "bytes": "8e01d7b435115caddcef10c83ed7fc136bee68210fed8109d0a8a3bee11222c75178a8bc802f81193609af30b059d1903e527c6a9168084ec979ffa6dddc89ca4a4f16deaf660bb45c24741d6d7d0cb2201bfbe7e8" + }, + { + "index": 2, + "bytes": "432f81298a2d80a2e792fa54888275fea307454a765acc896ed1f39b191df45d7c81e31221cd8c572cc091d51e8a52cf95576e0c661b5006a254" + }, + { + "index": 3, + "bytes": "abd9260db5cd32974980b5123b0b1d77c89e215dcf5f93366106c414b34e8f258fc7e30396651d3f892f643fdf760028c50708ca1fdc6b0259dc20e928026aca78a6c413c62bc0fb5234848335d439399fb93d2616f8329c38b3d0e9834579" + }, + { + "index": 4, + "bytes": "c22b90d98f068afd53a830060c539471e7203fef31086ad455350ab17238cb0553bcd2823b111c9253a0fb048239e97d1776cd21d741a6b770c5bd80d95b68e06dd91ecd" + }, + { + "index": 5, + "bytes": "0854564863c7aa7a5e10210dae6d765196c41fdbb97ea64af5cb15ea500d52cd0ec162ca29458fa688c30f9b96499eea19120dfd4c53ca37f200c1305c2454043d6c618df17794afa5303a3b7e9bfead05fb8947464bdf02fc6ecb4f1a3981cfc0adaf56d133288455" + }, + { + "index": 6, + "bytes": "dd940d099442afc9334599823ebf019790cc965d8ce3dfc23eb1f3b3a0c5a530b77e1c00fa4862fd9201262b49420afe417ce161ae49afa95bde09e2c300d010a26502e024e2440354c0602867fd" + }, + { + "index": 7, + "bytes": "59df86b6fe6e758bd30f9a3803ad342417c19b6c315e1323c82e6803131731c2f1ebe1dd955e2ab878406fe70a84762543fd72" + }, + { + "index": 8, + "bytes": "eb7ca87b819f8c64cd9a8e62ecccdcab4ef087e479ae329284c669c76e816abba5acb1e8083a2c5859b8bd4ae5de7be3cef839ace33e09083e2c8f214b5cd873c8c434de088978ebc8b0b99e01fe27462686bb8940512078" + }, + { + "index": 9, + "bytes": "d010aaecb45125796c68d98276d358e1ecd6da5fb1cd8a05636dffe2a3d925982b8fb6f681aa7e1f710621f9dc1c4f9a717af4c6eba0933b40ce052813" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000009d5439a6a829b9753b95857a76a82cde614a40939c927104e510248e9b496c7a44459ae2ca2382e4840c2e95bb3c0815a34045c85d49b4b54001b24cd4caaa0d4bf91de0efd0b5e23056f72606c5febb50c0b16e5fd1b46f347694df202e0e9d9101", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000003627ec6d4c01635361ae1c7c0ccd81af5d406cec72dddce9904c9b0b92927a2980faf8d9e95d0600040a000000000000009d5439a6a829b9753b95857a76a82cde614a40939c927104e510248e9b496c7a4445d15d755bdca3cec6acae366cd894510671dcad6a9c7d3c55ab20dd5cefa3c1c58f4432a49af3b720b3d466a8c660ea3e028247be33667d375d8b454a01262b00" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000007f7e03e07d21d06a060ea10558e27b7ce8f8e87eac2d259f3d322d0634065f0676c54622f1c3fce993de30bbdda14dcf48c4bf3cd2947e5dd2d36a2326f3026161e6ce72e0d5eda21fe2d8c34ec2606" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "4168024554c44e1b37107ee3fcf38b48b90ed9b732b82685fb0c9c8fcbb565e5", + "3a707bcbf00a4001d4f2623e963b2a09fa315cf526a1cfb5496766f701505406", + "fb9985baaff9aff0c9b96c7bc168d42d5f1530c85686232c1417ba1efc6b7bf8", + "014f52a86bcb1e59721ed890ba32612e890d849e40301fd4ed896612c1c33d1d" + ], + "size": 10, + "root": "9d5439a6a829b9753b95857a76a82cde614a40939c927104e510248e9b496c7a", + "verdicts": { + "single_take": "delivery_gap", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "spliced_chunk", + "about": "the uploaded part 4 altered after its chunk was committed (§9.4 single-take 11); complete fails too, as chunk 4 was not uploaded", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000146af4506534d292144495d8398d7dd8c47827083683d3ef7fb0152b8c124168000efad5feffffff005dd974e604dee1975caeec6a6ee1c8661274667b825148487cb5f78cdf8d43020b903b46cf5570cb138ac7ae93b2b20b0f26a5776c519ada3f34e474ca841a07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000008a3729b5125127944b8921d51330eb0c475ff22aef0e5926593b124b65cb0685602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000028a3729b5125127944b8921d51330eb0c475ff22aef0e5926593b124b65cb068502000000000000000400000000000000f348ec0db306a39e7d57fe704a4eef54a890e3f0bde11669e127093ada91fbe4000efad5feffffff0122768134c14b2e3a6d5e339842b3672d4552dbb52714d705a498c011d21a7d9890e1534d2528c2193c9c0613fc737b4763ea68713bd5206b7cce17c4b63569e67b72dd99cf3e79b2324e857ff0d1978248bd705ce459628a93e49d781559d209", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000d536871760c5d78464cdcfedffada460b941bcca10f718f9136a38028d1074a5e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002d536871760c5d78464cdcfedffada460b941bcca10f718f9136a38028d1074a504000000000000000600000000000000b14a0c17862e0fc259f683537c945beeca11a89a9fb9692d71072616e32ebdb0000efad5feffffff019b647680cfa1fa4bb1ddb1edc9767793929002ac4a69f77ee8fb6097984fc38f62e30b67baa3a9ceccd92ec98495b5e84399a8dd8fa194e6f0e8af90e909630f28bdb27409a7640fdb7d1cfa03eec88dda0ef4958a70117368983623fa94ec0b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000beba2e6fcbc89ae438f6b484b4cfe9d1c781f9f802a142eba6c40b626d0652af6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002beba2e6fcbc89ae438f6b484b4cfe9d1c781f9f802a142eba6c40b626d0652af06000000000000000800000000000000dc1826505c7278cd6886ba2dcd396b1c784d1dc74db9a441cc9eedcf1082629c000efad5feffffff039b647680cfa1fa4bb1ddb1edc9767793929002ac4a69f77ee8fb6097984fc38fe4e70ac052160fd9ab40422d754d4997ff8175bd3f8ee7dca7abb523d62b5bcbf348ec0db306a39e7d57fe704a4eef54a890e3f0bde11669e127093ada91fbe45aebb0ecd71fddd8a74011374dd3893605274db237fc52019db4ed56e586b0c85b286212943eb2caae80c17da0aad8496be8c2c88ae78181e3c25ae66078a800", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000a2fb616447003a53534cce2e25a45da4d4a7485679b7451bab1747b2c3159539803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003a2fb616447003a53534cce2e25a45da4d4a7485679b7451bab1747b2c315953908000000000000000a0000000000000006e14a0d1641fd81afafbcd403f7a537ddaf490084fa0aaefaec5985c799b460000efad5feffffff017d1a53a8ee7732bf19902896c9f3f5fc56466b6a3f264bdd23c8e6e65255172ef902bb24a980e543eeb3927e9395a9938ae777997e0c22d0b33c121a20f80b92e5747e8b78f8a6bb4da4d18a4927748e632d0c75a5aec2976d41a19242d6360e" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000004c1d17f46ece8aa8e381756b53ada986ce858d72a966d5d374f91855ab1ac5430100000000000000c0c1702a010000000004802a010000005500000000000000c287ed28c4368168d5e30f877266e5748bf3211d1c5f679f6326cbaae40824f202000000000000000004802a0100000040468f2a010000003a0000000000000031bd0ffb69aa37fba17262c77ea7c2bc233adbe0dcd086372de8f10d92792b42030000000000000040468f2a0100000080889e2a010000005f00000000000000a9fd559aaa39a4cf3b1877569824c1da864a49b27e1da3d4b2284f2b6fef2dea040000000000000080889e2a01000000c0caad2a01000000440000000000000048a2595ec3a301c2057c558b205609de698ff3d39376b52d3acf1b85791382e80500000000000000c0caad2a01000000000dbd2a010000006900000000000000267583f8c3f7984c33237796b53f3c7d6d45fa8af3e322be99b05054d4a4e2340600000000000000000dbd2a01000000404fcc2a010000004e00000000000000c06b3a916f9955317656b0e58aa80910e615a6fc4727cb67f0a13afc8b220a350700000000000000404fcc2a010000008091db2a010000003300000000000000ba4535de1e3d107c32868af93ba73949e9688647ae6c0954899b38253eece45708000000000000008091db2a01000000c0d3ea2a01000000580000000000000067b242d52928db368d97ba3aac3ed2d306356cd6aaa7201211c1a3d4d0fcff7d0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000773fe2461b7e89f9f346003ebf983dccecdf9d21617a4343ea051e8b0457805806e14a0d1641fd81afafbcd403f7a537ddaf490084fa0aaefaec5985c799b46006000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e68a3729b5125127944b8921d51330eb0c475ff22aef0e5926593b124b65cb0685d536871760c5d78464cdcfedffada460b941bcca10f718f9136a38028d1074a5beba2e6fcbc89ae438f6b484b4cfe9d1c781f9f802a142eba6c40b626d0652afa2fb616447003a53534cce2e25a45da4d4a7485679b7451bab1747b2c3159539c5d071b97a2828631f6bf7bd4db1cde0d040f74b3499cc16ba75b7bc64c795280159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936993efa1ccc563f574a13484b67bfabb7167094813a423fc96b9ba831527279dd06211388b87b05e6fcf5fb3dffb2a0ef9e921eb99cde280185c88d8c2fcbe73ccb4e07b324f4bb5f4bdca2bf7bc1f48a38a0ee89b49790b2b8f090b6e1a0016407", + "parts": [ + { + "index": 0, + "bytes": "d336f823d9967a2c8bce09f010460ce2c0777ab99f96e545fa1e34344f92c1d90938459d03143fb088dd485fb9297f0b" + }, + { + "index": 1, + "bytes": "f31b936491c8d2a3b92739b85761c5a987212b6094f3df5af1cc0c6b2e0f080c3ac1c90b053f23f971fed4514014d381b04498becfe59c6c511476511f8c722ce13f4cc6c1a1f56c11a1514fa654b721e83f779286" + }, + { + "index": 2, + "bytes": "c01a0b6f9aa5503b54b1a4fd245bacab6355e59507aac70494c6771d1aa5e459117c246397e97cd63c19e9f7849ae38817a28c54b60d39ccf136" + }, + { + "index": 3, + "bytes": "f06aebaddc20d2c1626a4183e3caf053a6a6cd7adae61c00fd22aca56eac7dc88bed7e1069d6ec8f132cdbe452f69e78bd7b0e5b6a609ddf9950f4819486ed15f0f77f78707dfb35860696587a2c4ab989e753972d5c94225a5d10fb0f4aae" + }, + { + "index": 4, + "bytes": "e8b706480d5a4c094a571e1f48e826de511704436d08ed62aaa6e6bbb676ce99b8dda134753aedb0fead1980f3142daae843a3b3371638a5dba0693b9c0e8489aca733f6" + }, + { + "index": 5, + "bytes": "7dba42640a19aab1f84c806ed9f1cc1a3a42cb041a67ffe368e5c23e33cce92c70cd27a8632f7961fe5759ffc8f6888f2aa93950def056c709200242c3b2fd99417ac404320bb9d1eee062d159c04f8db6ec5a9edf9cb4e550137d1047a7133a9d80fdc076d6ad2f9b" + }, + { + "index": 6, + "bytes": "0fac9720e6a49160ce3b41b658234e1c909e3be46c5acf13bbb71ea4957384a4c4339706c35d87965779b0b5a6061feead700e1dc6bb91a16867f6a9553dd5a9ca7a05e9bb6edbe2b5a682bfcf4b" + }, + { + "index": 7, + "bytes": "07e6fc49435bcaf2c5aa8f99af4da562d7182137bdc5a81dd0597ded655d3d17ce8ce62e76a8ed7b55faae85ec6fe39ee84f3f" + }, + { + "index": 8, + "bytes": "50d1b8119fce7ddd54e70eaf2e1e452b7f084832ce4379c3b5edc895007df96a04d3d9f5fdf8e1a620214fde91a0fc09ce035259d126137d99d2b1c775599781c41139206bd308ebb9c6ba468d23591ad86d12e4d49b53aa" + }, + { + "index": 9, + "bytes": "c2eb0f3c418e2b23daa991ace0aa45305ef2cf74a1e4ba178516759c81260700c5ed809833ff98c1ec9726724a9e2e985d2f8d8e335a5a792fc1c11c84" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000006e14a0d1641fd81afafbcd403f7a537ddaf490084fa0aaefaec5985c799b4604445cbb67208dd7b9aaa7678bf635b32045a96bef56ab4966b1690d4ca6c14a726ba6bb8e8f80ed29753d53f7e030f5714577532bd6cd06a9e96a57175b404ba7306", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000d1aaf6a82ce7fa410f40d8009bb3bc98bd08f2a6024d77cdcce3e11e4ed9905180faf8d9e95d0600040a0000000000000006e14a0d1641fd81afafbcd403f7a537ddaf490084fa0aaefaec5985c799b4604445fcde7d6195f5a5f1771cc818a561ea627beb4dcca071db8e81c1b1b92832057f12caaf0a6cf8d7bb13841844ece81688c76b4042ee174dd3e3ac5dc77c323800" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000068b4e819977f42b7b347fde4a135cf3a8f084a257264932c73a0b4319d3f7393785d97da365a441aee162f1f1ab57767599fc59cf24af3fdd02eebb028d53fcaab7f8075fc36280ccc80b56346d39604" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "8a3729b5125127944b8921d51330eb0c475ff22aef0e5926593b124b65cb0685", + "d536871760c5d78464cdcfedffada460b941bcca10f718f9136a38028d1074a5", + "beba2e6fcbc89ae438f6b484b4cfe9d1c781f9f802a142eba6c40b626d0652af", + "a2fb616447003a53534cce2e25a45da4d4a7485679b7451bab1747b2c3159539", + "c5d071b97a2828631f6bf7bd4db1cde0d040f74b3499cc16ba75b7bc64c79528" + ], + "size": 10, + "root": "06e14a0d1641fd81afafbcd403f7a537ddaf490084fa0aaefaec5985c799b460", + "verdicts": { + "single_take": "chunk_altered", + "aligned": "holds", + "complete": "chunk_missing", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "reordered_chunk", + "about": "parts 3 and 5 uploaded each at the other's index (§9.4 single-take 11)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000ec65d3e7bf6390dbfd8e28966eb0aef1af2dd171ec43756d7795a060433bcb29000efad5feffffff00d35669dbd7742a4a832d6c60abc6a8be43d7a6ba79dde7383d87d4ffad57c6a7b34253c72b4096b1a47a216139b19cdf82da7bc8b41c90715a7e2188fc4e100c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000007daeaf91e9de22f17ddae7fe3ba16b3f329531f060265c63e1860f750c9815ed602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000027daeaf91e9de22f17ddae7fe3ba16b3f329531f060265c63e1860f750c9815ed0200000000000000040000000000000046917c91136c7cf3ee8426929c7a669dbbcc89a62ec5d8db07960a4d6d88646a000efad5feffffff01807b5739212d7a1f67331c1681ef5e0a4cdac76007796139280f4f2879e1d2c50b8d287f7966d0bf89c1b0f594c443e2313d317ec77df3e08af35d9ccd32545c9fadf575322b4b155742b5f1ea7af8511f0cd73528680b4ff5722cda66c75b01", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000084ca34bacb038b2ec0173b3939f64c46a56b1c5c1411aa3e90cabb6f7894652e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002084ca34bacb038b2ec0173b3939f64c46a56b1c5c1411aa3e90cabb6f78946520400000000000000060000000000000021b7db7b3c6c0621a1642b38001342b76f8212ec258678e6c73f40559c799d9a000efad5feffffff01fdf58207388a3f8b9c4e73ba5aea7b5dbc84138ea8c8cd15af8ba2484c4e33dbb0998ae033b68c1f40b987ab2e8df7db9ae0265874a40f46bc5aaab4b5368ac0c1abed2b5302e114ff9ac8c2a3333522bb8bd8697b0fb5099ed04d913ac7b00a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000003446519075c74ce59a86a6a88db8d6d7e22f3c81559892dd6143f3dcecdbcc486033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000023446519075c74ce59a86a6a88db8d6d7e22f3c81559892dd6143f3dcecdbcc48060000000000000008000000000000000020f706533ac770c16ee8c73339ac05c2f7aa4e82443f8abb7b413ebc37fe30000efad5feffffff03fdf58207388a3f8b9c4e73ba5aea7b5dbc84138ea8c8cd15af8ba2484c4e33dbeaecd28ca2a12f722edfe55e60ed5e6279699e6518fe8e4d4fe563b0f5ad552846917c91136c7cf3ee8426929c7a669dbbcc89a62ec5d8db07960a4d6d88646aa4fed811da144027472c70beb6f9ce9d130e139bb0c84707493c074b3c191a0fbc5a29035762dc31fe956bde7c8687f356de6b5a87a495c6128e0ad40ed19004", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000d270d863a2c7c063e018fb048e7d18ab3f024647146ec607e31f73deb2a0e3a6803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003d270d863a2c7c063e018fb048e7d18ab3f024647146ec607e31f73deb2a0e3a608000000000000000a00000000000000bd9eac700bd4d8fc0bf55c32499b0b02099ebde4621401beb53571dab896564e000efad5feffffff01c3655c1637caaab8b9bcd75142c6694ee385bbb7e72d1f3280e0cf5df1456f9f90b0003416d2898fbe408f867f43a299cb32ebcc8afbdbc83bb569bb8c86866cbee16500adbf54cc1b4822e9b791fedc69a933ccedc10acc8d6664c92e4d440a" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000447c04386237cd6183c3946a1f7ae17c6f4cf817f6daf7b4c770af6597bea0630100000000000000c0c1702a010000000004802a0100000055000000000000006e0550449eaf8dc7564fd0ed208fc9087fe3d788c5c446ebad3ce811b6a94b5102000000000000000004802a0100000040468f2a010000003a000000000000002da6207a1610910f1f80c151b3a905d5872c4dd06204a4a379def1cc4b9e65be030000000000000040468f2a0100000080889e2a010000005f00000000000000f1c8c8a51d9446a239c5f90702cbedb489bbd1834c1539cf1f2e352302dc30b5040000000000000080889e2a01000000c0caad2a010000004400000000000000b4dc7a87a78aaa70725690596a278fa3c2cdeb3033a399d644d8ce92df68005c0500000000000000c0caad2a01000000000dbd2a0100000069000000000000006784c96c57429e21e7a95e593afdef1b891a3b1b00ac64425d993826cae07e000600000000000000000dbd2a01000000404fcc2a010000004e00000000000000ac1a996162d40695783e7d000d4a0dc3ba2d1c399ea6eaa5add199c28bd5d3080700000000000000404fcc2a010000008091db2a010000003300000000000000ab460961d96ccd2da16de62ee953458a2e1c91028e62549099e43d751229b3b308000000000000008091db2a01000000c0d3ea2a010000005800000000000000dcd0d2cfb1a0d305d250dd125b6fc0c0e6a02d0200a96f5ba42ae194dc1a1fe10900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000072480b2e32e02bfcd109396fce733f661bcf3a99d9ce07aafae29826cb095385bd9eac700bd4d8fc0bf55c32499b0b02099ebde4621401beb53571dab896564e06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e67daeaf91e9de22f17ddae7fe3ba16b3f329531f060265c63e1860f750c9815ed084ca34bacb038b2ec0173b3939f64c46a56b1c5c1411aa3e90cabb6f78946523446519075c74ce59a86a6a88db8d6d7e22f3c81559892dd6143f3dcecdbcc48d270d863a2c7c063e018fb048e7d18ab3f024647146ec607e31f73deb2a0e3a64963eec1dd062e4a2ef9c79a2c0c589ca9d7d0e44ec8b6d38abcd2040be4054e0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a8b052892edf09d79ff805819e194e60c31998b0b4b9d8846c2ab07a512a467d63b1adb74cc006bf78c86a4e28d34c0bbe5293c31aa53d8de46761fdd5a514a923fe02128aab9032baf96cb5b2c2608f2276f74c33ce33ed017e50bcf0ba5100", + "parts": [ + { + "index": 0, + "bytes": "86a3df3419220479e408484cae6d588e2d48bef08a80aa1232f71559864f6060c3923290c3c6b956469283fbf49ff2c9" + }, + { + "index": 1, + "bytes": "928351f4b25cff0709875d9a2aaa38e67075c7b2a5b4f94e99c1793c1a7c9e57bfa2fc2f2bc7150eb442999c90948906efa8e26901755427923cc8e27c40ed732daa8f79e723ce01703c49121ffd46a12e27b2ea13" + }, + { + "index": 2, + "bytes": "8b9d699e33a50128d69ab8da6909b7f3721701c0bf80df7bc131603addc1e380b763fd90357a5080842985e676b650531aa3148947e0c4db167f" + }, + { + "index": 3, + "bytes": "6f7bc4f0e7a4fac364f64e78cc2f6201400317d3a420b8e329b8d1aaa079ec5f3776352cebf14b7eea627fe71a6a4c622f9f8c45927fc6400c269c61033e28c345a03f5f91226ac63c60fec4c0135ff23bc26a6dc937fa00c04c340474914a47570b7825caa4dc2a7d" + }, + { + "index": 4, + "bytes": "805cd4494599910d4c6c5715477fd5119344477fd9dc0d66e2089d2e90c8653dc8c062d2147a3cf4cf1be0d389c3f0b3e939195805b5e505e9e1f3ccb078b46e95e700ae" + }, + { + "index": 5, + "bytes": "353159203f6c4c2caee0ddfcd0ac1c7bfefd7c658f8ab72035d19d4c15e0c77a7964a688814b811a374552e1cd4b99273d1d443c33e7beb66b92e274a2ea2a6c2fde6aaf705665aa511936a91211e5df774fc37738ea9455233e135b704f3f" + }, + { + "index": 6, + "bytes": "c1fdba468beff944025c5725e7106bca2cd2597f59e19ee88aa9fcf47b642d71ff8c9a3d05cd999beaeb3238bdeeeef65d4c95aa1218c949858080ca84a366a4dbc3d5a7b3d84148c37703533e7f" + }, + { + "index": 7, + "bytes": "6f7c3038d62d6599c1c11a5effe0438e92317be65a4e8e453f16fc197f8c36e7134be5232c356a31445af5e954eb27d1b351d4" + }, + { + "index": 8, + "bytes": "98e5bf975c1af7ac2f24b647a2d78bb91530a4eb4df442ed636fe917266ffd36062c9d2f62bfdd132e0037640b9176499c13afbbff1ef2f51f13347af9dda163b9db348df246c4316bb68156674042ca575e0959c2a74f15" + }, + { + "index": 9, + "bytes": "bee7a98a8ff43d6e2e27f83c6e783606852535b99989cdd6c3fb455af6b0d8e737e3297e6b7d010b2ba71644a02e2b5d26894ca29fa668ffc45862ebd8" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000bd9eac700bd4d8fc0bf55c32499b0b02099ebde4621401beb53571dab896564e44459835e5861db2369dc25496198d5c93b323d4a528658bac3b58dcf3a92614381685a123d0f713b646c2e6ca4016cabcf2ce0ece188137f6346e8bb5515eadd408", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000dc80ab14599cf9bdff96b548501b7df96c70cfb1b0da4a4399857bd3fa3d4fdd80faf8d9e95d0600040a00000000000000bd9eac700bd4d8fc0bf55c32499b0b02099ebde4621401beb53571dab896564e4445449e2404c87e24bb67e90a8580887edf95f07ee9856572302b56303333879c01a52ac2fe2b8301dc0f345a23705285ac74fd887d9a10ff43774b6f803ecb600f" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000002f2a99b06bea7bd229cc5abc4418acb1b392372282374e2cbb2d9e03afab0fa223e5380381f848292ceb325c4c7be0e59e6f5aab75d3aa3403bab71a69a55a12d03d1454b4669c3bc0db7cc3dcc11005" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "7daeaf91e9de22f17ddae7fe3ba16b3f329531f060265c63e1860f750c9815ed", + "084ca34bacb038b2ec0173b3939f64c46a56b1c5c1411aa3e90cabb6f7894652", + "3446519075c74ce59a86a6a88db8d6d7e22f3c81559892dd6143f3dcecdbcc48", + "d270d863a2c7c063e018fb048e7d18ab3f024647146ec607e31f73deb2a0e3a6", + "4963eec1dd062e4a2ef9c79a2c0c589ca9d7d0e44ec8b6d38abcd2040be4054e" + ], + "size": 10, + "root": "bd9eac700bd4d8fc0bf55c32499b0b02099ebde4621401beb53571dab896564e", + "verdicts": { + "single_take": "chunk_reordered", + "aligned": "holds", + "complete": "chunk_missing", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "extra_chunk", + "about": "a part at index 10, beyond every committed chunk (§9.4 single-take 11); complete holds", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000a5bb3052df66e477917090e19215fb75b33aa27deaeef7d08be920c8c42567c9000efad5feffffff00e41ada007286e208248d951d45c68ce432de0b03e09a571404ed44f2e30097396a6a7f84b4a9cfe99666fe9194bfe4c1c73f149aa1478c5af223eb9e5e1c9d04", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000044f00d9b75dcdc074006e5e1b163a6897457896fd59a28fefe72df907f5a10e1602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000244f00d9b75dcdc074006e5e1b163a6897457896fd59a28fefe72df907f5a10e102000000000000000400000000000000d67d455440a25fbb3c893c0d912b230beb88b3ccd3343d1e6c5b9f4850acf152000efad5feffffff01971bb4a5138773e8fb9e9319fff52f386085ced015335addc815376e0113fbbaf39db17bb0728b9f1cc5ddab8fa5942c5c563ad04fd0ffec186542980499a76b2c923aa99f463ed5b90e28585197505de4892de2e36693d0f7aede3fe4fa320d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000f27e4f7a4bbf35758041ea84d72c5f1189ecbc027d6578b37f6807182a3a8f90e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002f27e4f7a4bbf35758041ea84d72c5f1189ecbc027d6578b37f6807182a3a8f9004000000000000000600000000000000b33584c3abbc32327877f8d09ce4cc5816a73657ba99feaea4c798db7c7746f6000efad5feffffff014a0fbd2a0a33d174de022794cd70f8f332df34a140fcaaacd7b049be49aa081d98c583f80286c4597b67a23c89238a2dce17f13b803178d8b4f748f756ef92d5538b2d9e59218215bd9331f86937f9aeab523fab491d726a5e3d320a821e5c05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000003b031225701be56f9f43b4ae951ae8d0d559a51a68ec7c39570f0de2e46a09696033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000023b031225701be56f9f43b4ae951ae8d0d559a51a68ec7c39570f0de2e46a096906000000000000000800000000000000f5c564bbbf28e7846f473b396c681b92488297ceb3253123a028131a961847e0000efad5feffffff034a0fbd2a0a33d174de022794cd70f8f332df34a140fcaaacd7b049be49aa081d045d692ef260463d13fdb16134fd141fcdf4f727178a1f9111069a13487583bed67d455440a25fbb3c893c0d912b230beb88b3ccd3343d1e6c5b9f4850acf152ac9be431577072475a93e09163f0eddb1b3a6347324c0d6f1a4de14ebbc6fc8b6f1c18b8d06c4c078c8d77820a8038b7764f39f277ea3985400cca57f315fb0a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000a7eb3c1e2262ac9b007d2a069910fce770dc2894eebe80a6487306b71931d65c803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003a7eb3c1e2262ac9b007d2a069910fce770dc2894eebe80a6487306b71931d65c08000000000000000a00000000000000181de0f96092649a9e3eb9cc094aa4bba8178b49e452dd9e401539d6d89536c8000efad5feffffff010ca4332522e01b9e82e153693732f5f6036938c3771d5415445e07ea9cae889f3c81b2d144ea3ec0e45321c4efbfd2e92b403a3373cc575b4e8bba8d8f92e940495d39f6c36c1ae507cbe2c42c3de0fcdcef2521f64cb3d185b6935a17f53f01" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000058e1de9fb87615f72f8e4f769d6eab576745abae558586e244039c52ab1c14540100000000000000c0c1702a010000000004802a010000005500000000000000f57e0beea35d24b4026af8bdf7e08364460788950feec17e6d6e26469318723e02000000000000000004802a0100000040468f2a010000003a000000000000009c62e27f72ac4f15b41a76cb4ec58f2f91e51777e87fdc2ff998df5e3899c759030000000000000040468f2a0100000080889e2a010000005f00000000000000f4943d275b02c01a7986d09c164a4be71893172029f115d00b610f1c56d6bc6d040000000000000080889e2a01000000c0caad2a01000000440000000000000039029fef87f36ce0346f4679a9933350ae77de31fb70cfc66e943b367f11c9680500000000000000c0caad2a01000000000dbd2a010000006900000000000000e8cb279924374c1f655f0dd13671abc16d4cd11267b92c820f11c76824a1e4b00600000000000000000dbd2a01000000404fcc2a010000004e0000000000000063f3c92c7deb7ba52f10a62957d6829e2063153c2749f52825d35d2829edb92d0700000000000000404fcc2a010000008091db2a010000003300000000000000bf17699238cfc96e0f331b7a2f75d7f47fadc3a402d0f5d4fd8d914917ba822808000000000000008091db2a01000000c0d3ea2a010000005800000000000000325250815b499f627a9e81dbc025d4843a71ffa3f1d98a73b16e8c3f25e333890900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000a96ed7fb4d5d13b2f367a2b69ebf8c05a77e99ec7662edc971c67c599d96910d181de0f96092649a9e3eb9cc094aa4bba8178b49e452dd9e401539d6d89536c806000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e644f00d9b75dcdc074006e5e1b163a6897457896fd59a28fefe72df907f5a10e1f27e4f7a4bbf35758041ea84d72c5f1189ecbc027d6578b37f6807182a3a8f903b031225701be56f9f43b4ae951ae8d0d559a51a68ec7c39570f0de2e46a0969a7eb3c1e2262ac9b007d2a069910fce770dc2894eebe80a6487306b71931d65c53b9ac1701ef00eeb38c0c121319c269a68545ffcfc6834e1b76b9b483fb79aa0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369952765485a5d174c195f74dff8c809c420089345dd86b76918dd1f14740e43dfe3aea99f3ef0935b8bfa5c66b10ae1da8b92c98b444a05336dd45cc6ad15b4e19688127abda54bd2552552229438fcaacb13a579c1bc102c853a3d3017ba41909", + "parts": [ + { + "index": 0, + "bytes": "bf9b16ab6d6e5f5d7311098a1bdb00931e6c601ab73b973d64313abb7f95839701ee29a649c214605a1a2047f6c9c699" + }, + { + "index": 1, + "bytes": "0694c980fd5bc7d997c0e5521047dce0f6534b24263981d88212abd8d3ae306cde8c2ff1c0849e239f753796eab4e8dffdc416d8ee097701ce3bbc4c98f26a4624b26a542445cfe93939d8b2c03c2db68c3fedbdb9" + }, + { + "index": 2, + "bytes": "a7f0dda5ed001afef552a8f49bd02f483e0eb5c17fdaa55de6e58f7b6bc7be7a0c439f80d854ffc15e66c097a9832d13e72a96b90ba91ea8a713" + }, + { + "index": 3, + "bytes": "75c71136a05099bac19c6042bdda6ace9a9579ac378a182d15a6a5a9e8e1a478af163a26c1b526571a02708252e54cab6e1fbdf526a0ac7944bea72cab77b2b831d5283acb3f2cd59797a145cc716c7840a99f9fed724e11e9de167d49505b" + }, + { + "index": 4, + "bytes": "c24d56821312c2ff0add7451d17eed0d01a4b6741dc6a2c4f93eeeea7ff2863cdbb82d654c5a4fada440a4b0e229843f0f94d7d56e68bfeac6af4bfa91149872dd402388" + }, + { + "index": 5, + "bytes": "17df72de2df764922218e84ee44c787ae90034eb84fd609b7670ae396509d9500ff5689d16189a15a9b736df1482657b203bc92c475993c745e53cc8e9c4c39dbdc959cf81b54dda9346ca63edb239a46286aa52841c3306e01702cc9ab577c2c2a39f72720616a166" + }, + { + "index": 6, + "bytes": "0560bb0a0801756d0d3e8ef5e2ab9c7c9d218d90f649126e7f9e13ab0d7cc10779a0605c68a291abfb05d59d0abb4b9043a20bbbfb9cecb3f68d040d96bb5ce01486a0316149df5f881e2c292a57" + }, + { + "index": 7, + "bytes": "2f1b5001347ca03d0b1be23c2e13303c4d33c08587c1073d60db0d3b5dced60452a3a1ad9fe3a8596acc869bd921340357ece4" + }, + { + "index": 8, + "bytes": "8db2c5e433a8c831c207f622c2da1707469ff18426b3bb3cb27bcd360606de151a7ce2ea2e2bb34594ed677b3b59bc5e52a26205167847881bfeaadf6d65094d84e25f6cba7420da38a9addc2794ebd2e683df3916fb8cec" + }, + { + "index": 9, + "bytes": "54557db1be356e3c951865e93e99d23837ae3604809574c99c61f33965bb32986847c23ab5fe19f7064f0d2710284e3c8ffccc3ccd014122657995921c" + }, + { + "index": 10, + "bytes": "3f6cd2f89409228006a60c833dda851985cec49f233ff6de70b49ea1523b17d0a0a6b5b7327594f9428ded202a78035f600668ef2480507f7d02755266d5f8ae02a98e551bb327df64bdaa3b3773523282bc149774adc224214a5e4aff32536713fe" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000181de0f96092649a9e3eb9cc094aa4bba8178b49e452dd9e401539d6d89536c84445ca1f34b75c860d3fa20d286bcf6cb1ff930bb72d326a2080eea2a4384eb2ea54b2778e2c38268386804a18c93644561741742f961ca1cfb635eadbc1926d2c07", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000002e0370e5ffd6185e156502fa3befaf05f8cdf6bb43567db466992337794badef80faf8d9e95d0600040a00000000000000181de0f96092649a9e3eb9cc094aa4bba8178b49e452dd9e401539d6d89536c84445eb318699d532addc53928c02c7a81cd16589e57656c9989049f3466f32f2697eb020658d426b11d4077d98b84d3b70b5f45fc7bd9bbf21bb5862daa8f1870d0e" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000001ba7da22171e30b3bd01442953d1aac0b82c1982272d4bfd9534c433dd1d57814a0436278e52d60ac53405277aaf60cc64b722155e5568e1e2e61c7429cfce697104dc6b3d8757c864a806a2800b0406" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "44f00d9b75dcdc074006e5e1b163a6897457896fd59a28fefe72df907f5a10e1", + "f27e4f7a4bbf35758041ea84d72c5f1189ecbc027d6578b37f6807182a3a8f90", + "3b031225701be56f9f43b4ae951ae8d0d559a51a68ec7c39570f0de2e46a0969", + "a7eb3c1e2262ac9b007d2a069910fce770dc2894eebe80a6487306b71931d65c", + "53b9ac1701ef00eeb38c0c121319c269a68545ffcfc6834e1b76b9b483fb79aa" + ], + "size": 10, + "root": "181de0f96092649a9e3eb9cc094aa4bba8178b49e452dd9e401539d6d89536c8", + "verdicts": { + "single_take": "chunk_extra", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "missing_chunk", + "about": "chunk 6 never uploaded, the store's receipts stopping at six held: every commitment verifies and single-take holds; complete fails (§9.4)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000016998ae44ebe40ac7a2569a2275c35081709759c28411b8edf3668f80de91297000efad5feffffff007f15f0960d2be9513e1810c151656c03685ac4e07c743212aec0d3fcbbe66c098d8bc81a9a80f9650c13c348c4c96b7a7ef5b85e9cd32a7b001baff5f259540d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000f0bcaa5a881e6fac08807315432342ff1bfcd325ba03c10c0bb6dcd653db21b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002f0bcaa5a881e6fac08807315432342ff1bfcd325ba03c10c0bb6dcd653db21b002000000000000000400000000000000bec08ec8ac5565fc4b8d4775effafdf9490afc1db34ec1a4b3cdc44b34a4d57b000efad5feffffff017764e6a1de4fa4090c9d24a8b015462db95e17cd82883d8ff29aed72cbd91d90d965bada8e348f7f61d2b4552b2d9b1b670f4d43ae2386c6713d2851e0a91923c9599ec3810cbe556af7ef79ec3a65a6e33c7175600c245a90a09afe8f625009", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000e0acbea753f2dd26be275f74abf0b3930bb0d45e87ca53c8a4bd8c15e42a26c1e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002e0acbea753f2dd26be275f74abf0b3930bb0d45e87ca53c8a4bd8c15e42a26c104000000000000000600000000000000258a282c11b3fb17029a8f86a231a502a2496dc49fe680f95a4ceb4253e96371000efad5feffffff0176a5a156317adf2563670ca73b168e4fa8c47d735de2be23da1161d55ef0f871b8c9e4c020be046e907dcd0c2db00d41f333370d0f628fbb505386fbd498ab636dcb3aa263533f27d93990d5aa4b131e4b1de29c58949ad8ccaa4df95e300b05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000070c7ce1cdfaad584c990a38222fa6b41972b44fb96ce5595e7489a29b6f648176033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000270c7ce1cdfaad584c990a38222fa6b41972b44fb96ce5595e7489a29b6f6481706000000000000000800000000000000eaf7ebbdb6c61d57ce4c2011476266460d1d27901c795f42c182587a307b92b9000efad5feffffff0376a5a156317adf2563670ca73b168e4fa8c47d735de2be23da1161d55ef0f8711d136d050818deab0c4577ecf4c85c7917880d059f7346588738fc2aa0d00334bec08ec8ac5565fc4b8d4775effafdf9490afc1db34ec1a4b3cdc44b34a4d57b46223f73198c6c1e406cbaabea0583de6c261b932a716961577f1a0badb42bcb186dda402f2b586d3b9e7b4e29cdc7ce4dfd3c23b4eeb273d0be4721b35dda07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000cc0b7a0360bee11cefd437071698bce3f2835eced20944d0a1d262559a075060803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003cc0b7a0360bee11cefd437071698bce3f2835eced20944d0a1d262559a07506008000000000000000a00000000000000dc7a42f07554cfa62ed6900f944c87f427893f10951a9348c748c805815ab253000efad5feffffff01dc1b5a06137a398a0979bf8c1b2c3573dc80b5fff17d60c072967de3230e0b464a9169a6f69825fa3866c91d5282c4b8f730d153f3f791d58a1169932768fd443375342a9437c0d2a551d960a85a2db949484b046bf0b2fb9bc518f1c28ec501" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000f877ae8f363194c931b19126ca48532337cb4acfb1e6b08b96c9c987b1e675b80100000000000000c0c1702a010000000004802a010000005500000000000000da74ee1a38d9755fd6509c2788b80d47678181690c8b0c861f86684f48c97d9802000000000000000004802a0100000040468f2a010000003a00000000000000c1b404d04b9c35ecee5e51b64edbc3f5f8677020221caff8e844f5dc10271ff4030000000000000040468f2a0100000080889e2a010000005f00000000000000f60c6e77bf8a1f074ca60ddc7463d4061f8cf2b889052c92684b073c337ef1c5040000000000000080889e2a01000000c0caad2a010000004400000000000000fbd65792e469fea83a543be8a3ca210d94804c45a3350b43a8a2792499ea57460500000000000000c0caad2a01000000000dbd2a01000000690000000000000006487594a40d2b75da30bc69de67e9a80581e8aa150cc31d2e53b7b4961701430600000000000000000dbd2a01000000404fcc2a010000004e00000000000000578f2ccfc619aaf1759927667154012d4694c312e4a3d7cfa1e92320865c1ad30700000000000000404fcc2a010000008091db2a01000000330000000000000020d779756a384fe0edd2cc306619a1dde0e0e80816698ed67e6abf0dee2e3bd608000000000000008091db2a01000000c0d3ea2a01000000580000000000000083b45856cb31e176b254ecad500f36eaef6b8df70c9da2dbaae85e4b8e4648200900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000da7526bf0ee3a78605f67138a640f2e82aab8bedb34d3c53c076bfb5a99596a0dc7a42f07554cfa62ed6900f944c87f427893f10951a9348c748c805815ab25306000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6f0bcaa5a881e6fac08807315432342ff1bfcd325ba03c10c0bb6dcd653db21b0e0acbea753f2dd26be275f74abf0b3930bb0d45e87ca53c8a4bd8c15e42a26c170c7ce1cdfaad584c990a38222fa6b41972b44fb96ce5595e7489a29b6f64817cc0b7a0360bee11cefd437071698bce3f2835eced20944d0a1d262559a0750600a258d32fb15f68e4edfa541cce451080b561f0e2cb76ec98165e7440f2914870159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369913e0404b1f179471877eecee55e47f2aa6bd32ea05c9f8565d88fc56dc2a9ed5832b8e566addc6f7af33406ab632adfb0290cd9cf676c00b428de70ce7f5aef7979b67864353cf53fe5c208d0add8a9588acdb584675f4dbcc3b1f1ceb1bde0e", + "parts": [ + { + "index": 0, + "bytes": "5d2e4186d6d791f26098bf0e71aa4e7b6916847f50823da010afd30d9d20c37c54f476987af854364c9fcaf07d545f72" + }, + { + "index": 1, + "bytes": "278c2523a3162b4a463b8a327a5af2858220a564a84a738be3868ee931256e84ecfdc99cf3f9ce6076e9f8d1d7575086aa3754d9d11b66623c2ce730d03d286a5f40f8506e602297ec3da7ed99bfa06c60fd365753" + }, + { + "index": 2, + "bytes": "a5e45f92ed7b1f86071452f87506de270b7fa0f3bc9ceb43cb5a11cb2f24fc1bb9ee12c2bea59a0681eb52a677d973765eabd7f4d61afee98a9c" + }, + { + "index": 3, + "bytes": "49549126e79988a822c3b0f5fbaa10f695507d2c2ce47966aa84b77e5271af6485a2cef93fa4ef2dcc0e2e79594bcba1abf5e4aa28308087ca49f3a4a76c1a95d15095b6813cc76a83d67622bd66c9ae000e7a8df20694d4338b957bba9ce8" + }, + { + "index": 4, + "bytes": "da23cd32175b00776b627c53721944225d83975da780103142094713450122c2d888913ccc4c0c26cca6c343b2b8b98cfb46be74c34ac10d570034a1d84fc257d823ece6" + }, + { + "index": 5, + "bytes": "2ec70ce7473c7066a93f99e0566bc6341173cba4dcd852bc7cc801c431814c9a5504f671dda826cf7264720800cd40d9866e8d0048a80aeaa2672dad443d3af6bf6cfb9e72c65d85a133dafa595a7e0158c002db6ff6b14fa82db75264c7d55107af02bcbe329e3911" + }, + { + "index": 7, + "bytes": "d1eb3fdda28e70aeae0526372354ecb8bc491ad2589067b12fe7919d6ed9944ac901596560199517bfc692ae688972c955f1bd" + }, + { + "index": 8, + "bytes": "a7f6b8a78755d85d300ecc30346f6262daaa184f52001f359262f117208d0f9c3e4728dd15cd146aee83bf7b6067165b59d6a486bab91dba2f00128c385b233ff937d6edc7b6fa8d718631fdc8344cff534e4c0a0a226346" + }, + { + "index": 9, + "bytes": "81e32b318aceaf167c337af9d462299de6d8392e85a84a4844292a9e45ee1f80332f5909ef0ce3c79cea561d8c4248f5d5d6996f30903dfcaf5273881c" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020600000000000000258a282c11b3fb17029a8f86a231a502a2496dc49fe680f95a4ceb4253e9637144459bcf19a2a4d4b71439653d0f8342cc808131c122514d6876f806f47b1c592fc09622b013436acbb26b3875ad4370a9733d59108bfa31080d3c3951f23faa5907" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000957dfea6158a222448f152624dfc9322a98abc99e9031df8c534c61fa804eb0c328af4ed85a11bd5deda1da9f1e517110cb02bf76c9578a500527ad3939bfe9cd358988e7079d91a22e68ea3979e080f" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "f0bcaa5a881e6fac08807315432342ff1bfcd325ba03c10c0bb6dcd653db21b0", + "e0acbea753f2dd26be275f74abf0b3930bb0d45e87ca53c8a4bd8c15e42a26c1", + "70c7ce1cdfaad584c990a38222fa6b41972b44fb96ce5595e7489a29b6f64817", + "cc0b7a0360bee11cefd437071698bce3f2835eced20944d0a1d262559a075060", + "0a258d32fb15f68e4edfa541cce451080b561f0e2cb76ec98165e7440f291487" + ], + "size": 10, + "root": "dc7a42f07554cfa62ed6900f944c87f427893f10951a9348c748c805815ab253", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "chunk_missing", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "late_commit", + "about": "commitment 3 sent 2.8 s after chunk 4's capture ended, beyond the interval plus the jitter (§9.4 single-take 10)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000c852672d97588f601a5d36f4876b45a8c29b86003cc198b7c45f55eeaee45b01000efad5feffffff00886418d83837e5289ae14157b7c4a24d6c5d997064a0595ff64b73c8a2b7abf2d1fd27bc503999ad11e59dfa61f7d09933187d3db2fb328a4de36c4797829100", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000030677dc2a168b346425703ac67f1f96f3b1f327f5f993f1dd09fad625c3fa70c602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000230677dc2a168b346425703ac67f1f96f3b1f327f5f993f1dd09fad625c3fa70c020000000000000004000000000000004319595899c869c6e797ce34025b8dfdbae2e0f052f1bceeedebae5ffc0b4e9e000efad5feffffff01f214af01a2691e1094b00128aab537d41f2f0e6fa27fe86aebea98d961bc3b95af8f6a68220fbff3a883e9ba0268407d4d6c91d54f43950658de2b6133c8d1e95f0196798b885df72708ee250580ad365597a71db24c529d78881a544dcd530d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000d2db9fe0ae62d2744afae6294f6913672f15e126d426c235112f0e37e5155bf84092d20000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002d2db9fe0ae62d2744afae6294f6913672f15e126d426c235112f0e37e5155bf804000000000000000700000000000000f40de8655ff2a419e4b04d0e79d2f648f26ac422dd91fce8c65cf72b5b814302000efad5feffffff01d7fc3fae56f629c0fb32dd8f476f489e53ce9b4f9ff27e541a6c6e1b22f63fb537ea52dda7370f32ec94864eb724a362a42b9419a366c2d1b06f7bddb5abb8a9453857bc92add16c366afdf5adbdca73deb106b736e918f9c9533dec47275d09", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000002b5aa6765041f83faf8d0e39494dd9e39736c0411cb567ab141763ce9813a9946033da0000000000000cfe0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000022b5aa6765041f83faf8d0e39494dd9e39736c0411cb567ab141763ce9813a994070000000000000008000000000000001487efc738bd988d9aff8515b8ced027cdddfcc81a7225ec58c8bb9ea15d1d40000efad5feffffff040f665e12a48a0498f326ff7bd846c8aa2af8c9cfb289321faeef159efb9b37a5a2bfeb0b88a90be71f2d008650d9071f7e8e79fb8fb9641fcfc8bb43fe73be0447f1d90e63fd9a248a18fc200cd0cce55220097d19b4a83f04d100874ef2a5484319595899c869c6e797ce34025b8dfdbae2e0f052f1bceeedebae5ffc0b4e9ec630becacbc672c6e722c2b7690a1c30ff7a2a790c65e0131b51c7fa7bcb243850c4968ff578101e43d962e2c7ba41f5157545d6b80b85c30c7f5aed1cfdaa02", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000c990e7420d9cd3e12ff5bc13d8a569e5ab0c363f8cc59828c768776c3808d5bc803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003c990e7420d9cd3e12ff5bc13d8a569e5ab0c363f8cc59828c768776c3808d5bc08000000000000000a00000000000000bda5feac659aefa19e92879c0e54a8c0553c191d000a7e08df74346c7029d0aa000efad5feffffff011bc14493af1725a1564c44fc616bfb687e46b49fe54d011a88c64711d2baa3a49b416016489d6e81f9692746a7a589f239d3155f4c5b7c8daf74e2fb0c52e50ba86985b051525acc36ca14dce87ce637e0954d665f4a169cb88192e586b7480f" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000f9ae891a2f61006873e29cd5d15ba49ae2d5a5b575b862f5dd1c1ec49f1d78a60100000000000000c0c1702a010000000004802a01000000550000000000000067f783ca2928875be7c30bbc92171d5039858ff8d69c657a3a262fba9f95134e02000000000000000004802a0100000040468f2a010000003a00000000000000d83a45faddc1b5848f014ea822282d23d33f7504e36bb59e1c2b7626ead501ea030000000000000040468f2a0100000080889e2a010000005f0000000000000041456a865b51cf6786df934a4cc2ad8f5a17c95674db91c1bb4db0464c6e610d040000000000000080889e2a01000000c0caad2a010000004400000000000000bbe329f3c384a6639c0c310949666c3fc0a1e6663f8acfd5a56baac147b6eef40500000000000000c0caad2a01000000000dbd2a010000006900000000000000fb0c25d2d9dede51060ee49dfd39f8dbf1f5df827d4ab837083102ebe116735b0600000000000000000dbd2a01000000404fcc2a010000004e0000000000000090d993b305fb08d9a83bb1b437e3c8e017a3cc2ac753d6dfa193edf8029f32500700000000000000404fcc2a010000008091db2a0100000033000000000000007a24906c8e80e842b794d2dd6c06f9ebf3314961dd2905ae9a49590eefd939fa08000000000000008091db2a01000000c0d3ea2a010000005800000000000000af0204f4b211a8c6c104e300747ddd64bdf91686e0832c34b9e65ef34aae6c1d0900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000045e02242d16a930f4737a13fda01d3f0b6343d9ed9c417ff63a200cd9d297732bda5feac659aefa19e92879c0e54a8c0553c191d000a7e08df74346c7029d0aa06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e630677dc2a168b346425703ac67f1f96f3b1f327f5f993f1dd09fad625c3fa70cd2db9fe0ae62d2744afae6294f6913672f15e126d426c235112f0e37e5155bf82b5aa6765041f83faf8d0e39494dd9e39736c0411cb567ab141763ce9813a994c990e7420d9cd3e12ff5bc13d8a569e5ab0c363f8cc59828c768776c3808d5bce0c494c523bbd5cd9f3c1553e8739677d8ef323b69f2f144d8e8ab5353a496850159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699d7987c3f39d839dc9667ab4cac79bf6935c66861006db6015c47b85ac3caf068835dd022ea528ffe565fedd870041c2df75bbde985211baa49b4935b93c5fddb216bd3a9e6f3d0179446840ed742a925a0102e9f444bbb646286b4460355a80f", + "parts": [ + { + "index": 0, + "bytes": "7ef727ad9d3e60adbfd92f5f2cd1c5dcfce5d430c0723004384c146f19d1941244ce977e4bd530c5fd21c124cc41bc2e" + }, + { + "index": 1, + "bytes": "ab203e9c6b364913e4313e8f39bb0659263f434968589fc6b4aa0939730a113831cf592f397a525c07aebe59cf16946599b54958a373e90fd80764c2b1b6d8118a16b8654f704952a158bd70cb77976eae7ab8ee2c" + }, + { + "index": 2, + "bytes": "2f5e6e2a2c8d2d3832981c9a327d255529df3c7367e0d0b5335dae53742a49f70f06ad4ce3694cc88f8524133963193e878d8fbdb7884f61aac0" + }, + { + "index": 3, + "bytes": "4c0a2acc26ebe86c2f668ef01cb588fb7a85791b130ddc635fe8b3fda3ceb0306ee091684293188487ff1dff057802f10a70803f49d81d8efd3405d1b451d39c8b4de463b7f8c58cd512340d90eba2fe198034a85bf2899e3644d89f2283ae" + }, + { + "index": 4, + "bytes": "e3e40e6b38db06ede667033791c9b87668ca9e936ca50368d3950f13c7ee0fd69ebffe6fbf50a31b5e95997ad0e4bfcc28dfae9e0f0ff3488308a8761132a3d023d05731" + }, + { + "index": 5, + "bytes": "d0e3053e3ccff7edf9525d61710399115957c0bf516c732b475b3ed54eacb1571ab7a6614ab16dab135347457683fd2b8d3cfd9525f5cc36b11b1e8b5312572a085ff432eff855a90a025b24bbedc43c4b0eadd95871ec653dccc544bf7d91de3d2df198e89f467160" + }, + { + "index": 6, + "bytes": "e1760a18d8dcabc35b528886fd1511debbc0aea75a53452d6dd647924689ef9d443b02ab9931c74dce5c8957412ec34f40fea9b1e01adb51518b09e2bccb0485aee5295b082f4021f5b1f1d9e3f5" + }, + { + "index": 7, + "bytes": "2cdb690df1c8361530078380cdffa6c4df8559b3a80401209e42262500693d88656e2f5dd63d783693e3e00dc63eb9498e8b9b" + }, + { + "index": 8, + "bytes": "bb9ceb3635b69ba8d45b9220974b65ac5c088c7706e25e6b52d60945ad0f8398f116e0480d22e7586d085e7293f6fd69943f93a74cbab89a1ce09f9d8319465a4c013cd39fec9d284c22be05b454dfc7e277c3456059543a" + }, + { + "index": 9, + "bytes": "f2f440f1e4231651e971a3825e661bfd24ae2b787e3c6dac4a9d7a2e5c52db398e8074382580da593a70154a26a9695e1e9fdd8e9fb74fae19457913dc" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000bda5feac659aefa19e92879c0e54a8c0553c191d000a7e08df74346c7029d0aa444558450f0f54c3c6a16f3ea034b2265051601d51beefc6b92cd06d17a5c4eb1d0844d5e6abe0c6c5b6b54318c5114b849a0f5d1c0aca34e22ec7f04ef4f91f0802", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000000000019efc58e96b97accabcef825945b31e4685ecb84bed6eea9bc53e3bc135d75fc80faf8d9e95d0600040a00000000000000bda5feac659aefa19e92879c0e54a8c0553c191d000a7e08df74346c7029d0aa44455d26ac8c1929e689bad8ba8b99addb73180f82e60c08b320b67b3421da505c89d5bed18ed2494f64924270fe66b7fe7b8a5a53f7540bfb020933c93e70ccc30f" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000000f0a9aa644cf758c44ca731660f70d1ae7c755370b65f43790a5cd53513aee61ccc09508e519c79dcfe83c51e106a6b3139e16fd0bdd3693f7c4bdd42be2ca9f8dbe1e92b05545677c2dcc25b17c500a" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "30677dc2a168b346425703ac67f1f96f3b1f327f5f993f1dd09fad625c3fa70c", + "d2db9fe0ae62d2744afae6294f6913672f15e126d426c235112f0e37e5155bf8", + "2b5aa6765041f83faf8d0e39494dd9e39736c0411cb567ab141763ce9813a994", + "c990e7420d9cd3e12ff5bc13d8a569e5ab0c363f8cc59828c768776c3808d5bc", + "e0c494c523bbd5cd9f3c1553e8739677d8ef323b69f2f144d8e8ab5353a49685" + ], + "size": 10, + "root": "bda5feac659aefa19e92879c0e54a8c0553c191d000a7e08df74346c7029d0aa", + "verdicts": { + "single_take": "commit_late", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "root_not_extending", + "about": "from commitment 4 on the device commits a history whose chunk 2 is edited, and uploads it: commitment 4's root does not extend commitment 3's (§4.3, §9.4 single-take 3); aligned and complete hold of the edited upload", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000062107325f83a911f562e08db357f037b240b2178b7cef34376e6c32e8fab7890000efad5feffffff0041a2aec82d4b5910630772da3606443fba0e7504a698106741d73bbc9e5b75c3b68b519b8d4f52198f7d3af7bfb21463633072eba4e4c58c7e8fefda59eb2209", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000010283995fbd72c01aacce1a5d530631f028c3601317a0fea47133b9e6b4f764b602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000210283995fbd72c01aacce1a5d530631f028c3601317a0fea47133b9e6b4f764b02000000000000000400000000000000680af6ee03694a18489c437faffc49efb8356c596fce13454592171c9c42531c000efad5feffffff01e0e926ed4d9bb95ffaa51d67d89fe2374195057bb6862842e85022f3e1a0be9a6c369dce870cfd52515e4feb2481e2a5fbfdeadba7277ed43db3e3798f51f4f92516e3c680ad159a7662350b248a34a98ac84ae25dc722dfba5ae15d51d98800", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000003c3f9085e73d4a95b15bc8babee451264b8d11bf5561c9cd5e4bafd7140bdbcde0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000023c3f9085e73d4a95b15bc8babee451264b8d11bf5561c9cd5e4bafd7140bdbcd040000000000000006000000000000004b40180616ff87041ea38a3cae1686856e37be82273423e1638428c798d73940000efad5feffffff01ec72b6faa6565ad7b6e48c3932b8f2c9a9e0dbe65694b3cf91ab8381d005b9d3a445935a824dd37c72565c50f402a671ede20f5659e9e6a9ba21162c787892790ff54bd5a9a7b5fe6a9c33764173d86d4849431e77d754eb14d1e817e9faeb00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000065f966db864428e571be6fcce190e73ce4fc13712a9c55de8508526f385f3e586033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000265f966db864428e571be6fcce190e73ce4fc13712a9c55de8508526f385f3e58060000000000000008000000000000001c4e56ef7c7b82abb35e955aa4e289feb18914ed8e73cd7380402408d0e73fab000efad5feffffff03ec72b6faa6565ad7b6e48c3932b8f2c9a9e0dbe65694b3cf91ab8381d005b9d3f8a258d662dcb720efe62a71ca9808a769030c6fb12cb03d52a2db142208336f5ae3a533add30da0022c5971a22c2a7c72a8b17aa52f3d7b80d88ce1d5fa5b875a4da3339bd20f91af17283d969cebd81e4df32b8c32f1465eae5e763ca11fd3d216ee6259b71379f407b65ad26d44694ae3d77e3840faa1c07e04fad12ced0d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000e36b90d11a1ad0d423822bbf4c3644e12b26d678f89f6e81da851d67a0d52e2b803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003e36b90d11a1ad0d423822bbf4c3644e12b26d678f89f6e81da851d67a0d52e2b08000000000000000a0000000000000003bc67f718aee2cab81c66393a7cc95d7125c5906d984192932804673c215ee8000efad5feffffff01b65dedbc19634c3de955db2c71a55b71b933dbd0ee2ec30daa2c394a4f076eb91aba7fd78f62b1c0d40fac62525b50253b4fa0d7ba4ed5cd00cb45e15b666101c6793a8209b97fb0d68db45fe0e613b859ca76989575b57ea9af68958d673a0c" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000074d6efe222d1003e922ac6e0e4c3f8ea7f96a8c340fbc3a5913db89e4b611f110100000000000000c0c1702a010000000004802a010000005500000000000000c70ec541003383548fa6977a3c914f92c850788027d726f699fa4473c251557502000000000000000004802a0100000040468f2a010000003a0000000000000035318b80d282c118723f8132a80b9d10ba9c31263ab1e78eadea2336f2d9c289030000000000000040468f2a0100000080889e2a010000005f00000000000000550bff08810e58db7f4134a707ddcb7010a32c1087c38fd31f656efa66c76cf4040000000000000080889e2a01000000c0caad2a010000004400000000000000164102b3e4d3cc83942b110e23b32e1d23741148464a43ea427e5c9d770177f00500000000000000c0caad2a01000000000dbd2a010000006900000000000000f44c81c8738a733f341bb6c1f07bd3342f5339c4ce0aa4a338627b2390b7cbd50600000000000000000dbd2a01000000404fcc2a010000004e0000000000000012e7e0f7b83b29ec8c472c372f33020897376e1b50d80a2b9e5782daa99f45b50700000000000000404fcc2a010000008091db2a0100000033000000000000006b28844044708d3c8521b9935e612885fb9a955167474d460708c36afb4314de08000000000000008091db2a01000000c0d3ea2a0100000058000000000000001bb44a6459317ce1dc3732ffba55599e1f72262332f786ee94c17a67a65bbfa40900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000f0562fc7fa656043b8ca08041a66950d17567c389a8892f96a6931fa691f5d8903bc67f718aee2cab81c66393a7cc95d7125c5906d984192932804673c215ee806000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e610283995fbd72c01aacce1a5d530631f028c3601317a0fea47133b9e6b4f764b3c3f9085e73d4a95b15bc8babee451264b8d11bf5561c9cd5e4bafd7140bdbcd65f966db864428e571be6fcce190e73ce4fc13712a9c55de8508526f385f3e58e36b90d11a1ad0d423822bbf4c3644e12b26d678f89f6e81da851d67a0d52e2b00ceee1afc0f8283bc00cd87988984eb676e2c9876ce1357a454f5861785eb380159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699054825709c33f68163208c6d22681246f8cd8446e1414d1b8878870efd7bd57e0c53e1cedab7debc2110f85620deffb7b7e966b4194b4348814d37cfb274540ce71e885921fdb28c7aa323d47d97ed83fe0bab9317120ce04814d7465cb1820c", + "parts": [ + { + "index": 0, + "bytes": "8f1d865ead1ced48505b3639abeae49d43de082c5e0ccfc442ef665886158b5c848283cd3a5afef2099a3e61668971f1" + }, + { + "index": 1, + "bytes": "00e62b10dd96f19be82ce70c7858c4702399899e7a29b5843e67469adce521efb553cbdaf7413f1c2948db1bf95c4b63ddddd279a02fd04e4d006bec180cb5d6f332b5eb08dbfe0b5d5e98c9d2a442ea5a4f194374" + }, + { + "index": 2, + "bytes": "4c633871addbdfae10c9008928c4d70eb0963a83aad27775066765fc0d317b9ffae8e6089c2b937e4f0746168d8664aaab329032a50b79117283" + }, + { + "index": 3, + "bytes": "ffada8f339541cb9f5cf156634b0f793ad6536e895c3159aa873b7ac88f6c68bbc34cd29f6b12cd4ae25ba38ef750e1b13044b79b7462eef8e323e9b8e662ede03ccfed1da813f126ffa6c543e1e96c473865d07a5dc91e76fbca3ede26963" + }, + { + "index": 4, + "bytes": "908922cb3bb0e5a0f1b5dbbe5d3a02630171d85adae46c8e412a11f2e0d8289dba041fa485483c26f743ccf7855d111987a215abde474b4b0fdefe4efaa8c743c2538519" + }, + { + "index": 5, + "bytes": "59d5392c13695cf91cc4af9468de36502ddf96199f5a865cbd5a75c52c86c373d456405a0f32511241585521d8ec07383e7e6e58b5c966c491d4a68ba4d7f8a52f81a2589ecb91e8ee9d40de1428c8680cafe931e3fd8bc0dc6da22de54ae261e991e421b165b93b87" + }, + { + "index": 6, + "bytes": "f51d920eb00e2b0d92757963edd0fd482225772eb3e529df78774c574421d1081ebd12f312ed3055c710a6921ae150dbb10b03c68e429d79b57d4fed36218604701c4d92108a39c7162bb83c3268" + }, + { + "index": 7, + "bytes": "0508a41f0e3ffcdaed528c9e74075d4e70863b3f4db66459ab41c7bb18fc5d7503d312d5613a44e6c9182cbd48363bbc1f94b0" + }, + { + "index": 8, + "bytes": "18aefd1f0dca5d74dce9331cd1d045517d34e68f4bf8613134c54047b8bfdbdc826ff0c378f7a6548f8dd78d0c2763d03dca688651b5e69d1632a2cf6c296b9a43e1b5d4a75902134243353873ad89e12e19dcba599be386" + }, + { + "index": 9, + "bytes": "1ff38ccd6f6db75bf0c9adb0bd669651bfc938648418771441b6bd94bc88aa909f44b1027c2bae5fd42d3b8b6b0bea97203a1a20f4b28dfe41b3852958" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000003bc67f718aee2cab81c66393a7cc95d7125c5906d984192932804673c215ee84445ddedfb408dd3d1471371b31b68a721ea70113c90ac456011aaf3ccf9f920a27a9c2e9d31389bd57a5640395e41951cb15df2288c72817eeee186052ff63a4e0b", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000007bf8d8d03b7c8f92100de1791756f298a5564344d8f7ce02b158102a7f18e3fb80faf8d9e95d0600040a0000000000000003bc67f718aee2cab81c66393a7cc95d7125c5906d984192932804673c215ee844455ffdd98c1ae46f57338db9d18594923a30190e41db6de1059c75568a592dc0f88100d948a6f52b27246eca8f404263f4f116ef13c897f3b06dcce84439c9f80b" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000232c2413408b5574f000583c1b834c2f030771c1b10eaf63184ca561f13098e3a5a8105ec79d34d48318fc971ba498892c3d31bdd66f18a462033a5c6efd901a81c78e5e405f723d6700681a5707f505" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "10283995fbd72c01aacce1a5d530631f028c3601317a0fea47133b9e6b4f764b", + "3c3f9085e73d4a95b15bc8babee451264b8d11bf5561c9cd5e4bafd7140bdbcd", + "65f966db864428e571be6fcce190e73ce4fc13712a9c55de8508526f385f3e58", + "e36b90d11a1ad0d423822bbf4c3644e12b26d678f89f6e81da851d67a0d52e2b", + "00ceee1afc0f8283bc00cd87988984eb676e2c9876ce1357a454f5861785eb38" + ], + "size": 10, + "root": "03bc67f718aee2cab81c66393a7cc95d7125c5906d984192932804673c215ee8", + "verdicts": { + "single_take": "root_not_extending", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "misaligned", + "about": "the device began capturing at once, ignoring the four-second count-in: chunk 0 starts 3.6 s before the capture instant (§9.4 aligned 4); single-take holds", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fdc0655200000000000008160004000000020e00727573686564207468652072756e0090321f2f891c648f4b82d0a362fb53780af7ca067ce4741fd70c69d3b47633c138cf4288ae40fa4a09ad92a5955e074e2671a13bcd27c23a2facc8439dd39008", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520200000000000000e0142a61a6edfdb8f68a33832ae95dcbb6463447940e851582371afb8f749f7ac06e8f00000000000008170004000000010f006c6f76656c79207068726173696e670088422af230b2ae4d657acf921239f6e5fa3891ecee904342a3445e3c4a8ce5cd11aa96064b20f99b6f675aaea2177c1b6b32da15908c4ea3d2e56ec285affd06", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5203000000000000002a492b991d5c2cdf7bd7dbbc3a350c943869598857b959d0f3d789d313fe69518035bd000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5029857e0fcfd8ad383e419e03f4c31847cce89a9a6f949673e68ffb2e1b5c346ea8a3c564e5f7de8db77e4e0755103a5883af33f15b7f6ad401bf062cd1520c400" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e660b7470000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000004f39b1a36a66776f6260f07fba92328a76c11d66ee366158a5e371856dedc350000efad5feffffff00f1ede85968ac5757afaa2e1c69a5107289e936d6ff1bc1055920579aa82ec755d15a2800745ff5b8481a97f8d8960117807e58df304c01855c3a05c041713009", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000003f450373f3ea1483bd73013f4f06aa119f354c5e58bb66e3fb1b717d6d6c7ba5e03b660000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000023f450373f3ea1483bd73013f4f06aa119f354c5e58bb66e3fb1b717d6d6c7ba5020000000000000004000000000000008b1ac628943355ecd37bdecabd725124a04ce0a0a46ed1b95ff6e56f1b3d80ee000efad5feffffff01c080cd80a14c2443d45785bbae474693091b5931843e2e6a1d130c9b1c7c38cbb6a760422dbb833523941bf49e3a624c92bc92d30331061559cb0f84a0b5cf9aebaff1a90714ae1949a58c513e866aa40d2b511cc88eb14ccf0db35af39fec0a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000ce54a9e5e3b11f26d06d0363146b72f2174ffba21222f1bf1dabf0294b1a456760c0840000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002ce54a9e5e3b11f26d06d0363146b72f2174ffba21222f1bf1dabf0294b1a456704000000000000000600000000000000c6ba0eb4b531f8f0783740586cdba410d020391dd948d39fc26139af9781d660000efad5feffffff0181ac52970abbb6ad26b1f49e570dadf1aeb0c974bd2d48522dfedf88c29ecdc633f8af0c71ede9ea04da4513edec28e1f7123a6d80454d475ac4a8ae50704189a929e31e031a291595e14f10db10a7fb77754dd44227d6430ee31e6f40e50e0f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000738b30e95585ffff0c25086bb284eded8b5034d5083c5ae61abec072c54d27c5e044a30000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002738b30e95585ffff0c25086bb284eded8b5034d5083c5ae61abec072c54d27c5060000000000000008000000000000004351cf2ed68ea4893141b5cd1de157f68c9a816a1d251c0656acb4c11009025f000efad5feffffff0381ac52970abbb6ad26b1f49e570dadf1aeb0c974bd2d48522dfedf88c29ecdc6c3eda541395367a0cab874bf5e28d4da9d3014f2b7ffee2700ea408100f247c98b1ac628943355ecd37bdecabd725124a04ce0a0a46ed1b95ff6e56f1b3d80ee4f5fbf94dfbea1c6fbc2172b88ae4c7fcbb84706dc4f0736778fd861bc5010e1d3d8c79c416f76c95260c7edfb2738d091124d64131fd76adfd691e9b5e3c206", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000003cbcb9ff6b1058e08eb7c089f08c66a0563f85d429247a10cf37fb4ad5176b870050c30000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000033cbcb9ff6b1058e08eb7c089f08c66a0563f85d429247a10cf37fb4ad5176b8708000000000000000a000000000000002170aa4d9f78acc990a3844348c059e1cfe052a08a0cd0a675fbac4d6d1246cb000efad5feffffff01cedf06cd473b4809307673e1c8096a2da53a6eaea6fcfaa9fafe9bad072a0ad09a64ae1b5f8c088fce1eb10eade09c2fc6c2e28ddead091e3fba4a3d7dcb2a863aaac2837302d8d08d1c46fd905cf99fd6714e31bb5777e5f9b2f2c459339805" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a000000000000000000000000912a2a0100000040d3392a010000003000000000000000b32262570c0ed712e2d46ef89fefd0a1b81269f7351d945f67255ca14d0061fb010000000000000040d3392a010000008015492a0100000055000000000000001911fe1eb321753ec822fc68c2dbc818140e8e17bf45f6364dc3fb57cfa00bc602000000000000008015492a01000000c057582a010000003a00000000000000008b50f797c831cf833d1ec9dd652690f6c563351149aa280f74a35d16f6df470300000000000000c057582a01000000009a672a010000005f00000000000000ce01c9fb32358e2f3a79ff1898face8ee111bf55a88f992a801f0db04103c20e0400000000000000009a672a0100000040dc762a0100000044000000000000004f15b5eda8cf71ad2e0ae51ce55afa4b32b54b038153f8eff7908ba17ac40c64050000000000000040dc762a01000000801e862a010000006900000000000000f543b50c29d9815dc23533cd41d5a2e14d4957e91f759cd8df3de03c55fe1f5a0600000000000000801e862a01000000c060952a010000004e00000000000000d6de9293e2a3559aaefab3126867e5e373913392c33ce1b3fe599f2e7f87bab70700000000000000c060952a0100000000a3a42a01000000330000000000000016428c6201c453982a260d1112ec5cffec7b268ce264140c0a14cfcb79604649080000000000000000a3a42a0100000040e5b32a010000005800000000000000ae1b0d1feccdc51b6e27dc1ec444cd77d6536a2f5359114e29f02e4c6fec88ef090000000000000040e5b32a010000008027c32a010000003d0000000000000004cb9d262a574312751137e7c15ed28cd77ee1eafeee961e91945e6abf5f1f812170aa4d9f78acc990a3844348c059e1cfe052a08a0cd0a675fbac4d6d1246cb06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e63f450373f3ea1483bd73013f4f06aa119f354c5e58bb66e3fb1b717d6d6c7ba5ce54a9e5e3b11f26d06d0363146b72f2174ffba21222f1bf1dabf0294b1a4567738b30e95585ffff0c25086bb284eded8b5034d5083c5ae61abec072c54d27c53cbcb9ff6b1058e08eb7c089f08c66a0563f85d429247a10cf37fb4ad5176b871cd8cf971d37fa29028d49c53c20f6065e8ba23a2cac837552ddfd7f33cfd8610159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699b74d8c72fd88dded5257fa3363b67ac83545b725710fd8d58441ebddfaf2239562da9391330f21057265a9c9982fbfcb2d389b73da508490143d41a03be7cbf4dee7e5829b4843443305d01a5a4f551726214907fa9d5b29af48ca34e3cea50d", + "parts": [ + { + "index": 0, + "bytes": "3a3c16239960cf40b83c635879e4e3a48a47cf8bc0a4bd1d313747b98edd1eebab88bd45b72c9705e40de69502be6e0a" + }, + { + "index": 1, + "bytes": "6dc472f6e960b4296de32e59a3db98431cde0f42793a56b73a0f54d0a2db96f49b472075cd0a27f78bc8170ccafc6d846a01b2ccabfd375358b49cb8c335d13313ff7e2a90497ebb0b4bd26596c5b416be44c1eb29" + }, + { + "index": 2, + "bytes": "25f714a47ea50292c8122dc308e5763d1735fb4dc2c256906acaf6c0c965a18f825dfde9709f91ee74ada579c9dca8bff44e1fe632348cfd3adf" + }, + { + "index": 3, + "bytes": "5775aa7110572bad36d1bede946fcd9b4e3ba557add5938c08ab3d258c316f539fd8c8327389186cb84240dde6c1486b414195d64c83613bec90c97b345fe4b8189525810c303813d10ad2e18b67c10f08b8826e8edcb512cf1e2425fdfe75" + }, + { + "index": 4, + "bytes": "bc1cb6a3b35fbc0ee3b67039fff58fd1f43c51064ae3a513087eca782420346f232760ce08ad6384538f775594c4f4f9bc080880aedee49dbb552395d3797beabf27e707" + }, + { + "index": 5, + "bytes": "dbb28e2bd6e82644faaf3e8eba2c0dc67080d9b155e61a4030a302cbbde4e0d38c2c4bcf4cdd02d385a5bca020c2849fc3a6ca311ced5666fe4ce18b8738f44eb4ece8fe9dd569bfb9c3b04ae7e7b8a0b35373ef7b88998141c3c3928a6718a78c71e05b0c6f9eb995" + }, + { + "index": 6, + "bytes": "fbf1608968201e96fe18f0445caf51e1c79766896085b463d9a7694e38c0ce6289255b971ccb4ff4ce38391bec2e32adc6f38e5230ec853b94029f49030df4a821850ca4f1f7e21b0deb96842331" + }, + { + "index": 7, + "bytes": "3424ea8312575eebd88a7453ebcb25af3426ffef3931aaeb053b69bd971d3129bb1991dd657ec22b25eac8f6b6381cd043de16" + }, + { + "index": 8, + "bytes": "933967460c5651ec93b86108a9394863825e525ec56bae738d3e72d3a96f4db6d96b0a0ca9b9187d066a107f9467362b0a51d96f2f4114bfa04f98cd676b20a3b0cd72e4804da7cea114db09d482f33bfb8aa0409864a671" + }, + { + "index": 9, + "bytes": "7d0968a933d0765d676a665738520c22edc7532b7787401063bbc0190e7fb3ef23d96a302c279c696cdfdff5fbd0e4cf42926797a72e78bf61fc325b58" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000002170aa4d9f78acc990a3844348c059e1cfe052a08a0cd0a675fbac4d6d1246cb4445c3a51a3a99e89aebcadafcd883febadd57e5988e591049156918a5f1f11a3f3354a2a2a0d17ba4a3e3672fce75bcc878c9980421423ae62dbc4061d14f28c70b", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000004f416e23e7512d322481bda13ff0534c47a99f3f8498fe45e113a363a9eeed8d80faf8d9e95d0600040a000000000000002170aa4d9f78acc990a3844348c059e1cfe052a08a0cd0a675fbac4d6d1246cb4445963cbaaeacbb6cf39256e83b0e3187727fc40ff729cac6e2c3b9b3c4379adbfd954328cf3b7cd67535b875499ee5d03c5ef978158ffa49546ee829ce747cd000" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000b8a202cdb26c6ee145bb145a02988ec1099e054672e3d968a933f0f7fc6515e15ac01c8866e91e977a8ddad5afa015c8a423266bc85874402f11a1fb181958754a25373db2a289c40adb295c53b7790f" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "3f450373f3ea1483bd73013f4f06aa119f354c5e58bb66e3fb1b717d6d6c7ba5", + "ce54a9e5e3b11f26d06d0363146b72f2174ffba21222f1bf1dabf0294b1a4567", + "738b30e95585ffff0c25086bb284eded8b5034d5083c5ae61abec072c54d27c5", + "3cbcb9ff6b1058e08eb7c089f08c66a0563f85d429247a10cf37fb4ad5176b87", + "1cd8cf971d37fa29028d49c53c20f6065e8ba23a2cac837552ddfd7f33cfd861" + ], + "size": 10, + "root": "2170aa4d9f78acc990a3844348c059e1cfe052a08a0cd0a675fbac4d6d1246cb", + "verdicts": { + "single_take": "holds", + "aligned": "misaligned", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [] + }, + { + "name": "consent_missing", + "about": "the manifest binds the performer's consent and no consent record is given (§9.4 publishable 1)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000041543049d573bdb07deb36fcfa785021d7fa6aa9d9fa8d2f71da110470fdf270000efad5feffffff00d671cffebe3bf63d3494b725c622d5c9d7cbe4cd1f0babc1df04fefb7a095156cf4e16bb5dee5bfc1721c26ef3819c5e4ce3b499d1c2f1b4a2c52c98f4efbe0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000004770e88ee5cb741b9f08b34a6fcd148318bd08d714080dc2ce8d1797ac6b58b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000024770e88ee5cb741b9f08b34a6fcd148318bd08d714080dc2ce8d1797ac6b58b0020000000000000004000000000000001b5f31ecb67c291de0655447189f0169f552cf42ee8de60539d41f94bde72a6b000efad5feffffff0184d3a0e33399cf796cae5da5b60ce841e9e3e44e75a10c8de0abac418550c66d6421e4d9ca6be1b485e6dc07f45cb2a2cf1839c735c00651c56adc6e5a6fa8bca5f3e6b596b58b258782005937ec4af336dad324275c86679717cc1f7da57803", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000fac90c688899ae6c5c953d3dcff5357d11c012a7c94bfde1897e83275034851de0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002fac90c688899ae6c5c953d3dcff5357d11c012a7c94bfde1897e83275034851d04000000000000000600000000000000528a504b9cb6f47f62b3a281594aaa50338a4d59d1c25aa8a50e59b3a797443f000efad5feffffff011441a7ed995f017200e639640cdf9d4078c5adfd3e059c889c8525409e59e887f7a069c399533636c5fe26eb7b380cd82dc702528260b1da19db7930a25cf709b0d9206c53fe2779debce3272881c560a4686910c65db603094ca8c74cf6b006", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000ac2536401be958bba289bc918294e5d459fc12f750b87ee1c9c17f51032f0f446033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002ac2536401be958bba289bc918294e5d459fc12f750b87ee1c9c17f51032f0f440600000000000000080000000000000052b822e46fb2b10bfdca664236a5b1ee589824360e7dc728864cce55eb85b99d000efad5feffffff031441a7ed995f017200e639640cdf9d4078c5adfd3e059c889c8525409e59e8876d181749557b083ea38aa1bd000ebd4d1d3d1c4b5cc89528958e0a3b413c893c1b5f31ecb67c291de0655447189f0169f552cf42ee8de60539d41f94bde72a6ba390290126f915f047a9573699a68711dd5ce8dd5874684cbe8f5f9a81dddd6f6df6865c5a3ddbee2ab489ac8c0c8aca28b69ef6f806a5b459403eb0afd6370f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000522e187b8ba04d5f9784532f15073fe710df32406b0bc1deb69d9d9cebbf3f82803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003522e187b8ba04d5f9784532f15073fe710df32406b0bc1deb69d9d9cebbf3f8208000000000000000a0000000000000029a4d38f6d8a45c31821c6c151615ee77e998d59b9874c6a86ecdab102de6378000efad5feffffff01ac448cb9ac1424a1b5f762e484e81e7a886827d74f2fe44a67c94428b48b873f0110747310744e139853bff774ad9c45699005fbbd0a083a4f8c273c3d40592be2e6af6a3fb763bda5b9dd48303e9665b7c3377d20d9e64af3bbc8aeaff72400" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000947591fddc0124d6a0d018c4e005b3d060af5675707e02efca72629d4124361b0100000000000000c0c1702a010000000004802a010000005500000000000000e7f21830e02e10789a37b595d270944cb47c0ce97e9ae15f75b33b0dde03493b02000000000000000004802a0100000040468f2a010000003a00000000000000cd11137ec9dea77f4f4b956624f1f1462cdc9f45093db74ff1f03548aa342db0030000000000000040468f2a0100000080889e2a010000005f0000000000000084609acdad680a0b89178d604d0d4b5714dad0e1d5ff0f05c684af8c13b79941040000000000000080889e2a01000000c0caad2a010000004400000000000000c377ce1b55e33e47381539eadf583c6f136a89844fd842ce0d0419fa8e1edeb60500000000000000c0caad2a01000000000dbd2a01000000690000000000000021312ee39019888d6e46d55c2fb9f27fe9c352342af321c0dcc44ff8e8b2e4870600000000000000000dbd2a01000000404fcc2a010000004e000000000000005cb6ba4e940a62462a423a07672353d89579fe860ad86d844dd75c3533341c100700000000000000404fcc2a010000008091db2a010000003300000000000000d994c23d5c50a9ee8a9ec47d01bf5046bd4d62ec3811c286f6f80c0daa789ece08000000000000008091db2a01000000c0d3ea2a010000005800000000000000cd078733ff742e61398878aa58454849559e8c2f13bc1311147ea19a94cb6a8e0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000ccfd22a3d71bb2daac762ccd94b418deb67161d6365e6629509631a74dc05c7329a4d38f6d8a45c31821c6c151615ee77e998d59b9874c6a86ecdab102de637806000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e64770e88ee5cb741b9f08b34a6fcd148318bd08d714080dc2ce8d1797ac6b58b0fac90c688899ae6c5c953d3dcff5357d11c012a7c94bfde1897e83275034851dac2536401be958bba289bc918294e5d459fc12f750b87ee1c9c17f51032f0f44522e187b8ba04d5f9784532f15073fe710df32406b0bc1deb69d9d9cebbf3f820dd26a489f74d01176d2f94c9dc2d29023dba77fcd854d61a505c5e814d07b470159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a99f139e076cb6bc1eec2fd2a5b972821d8156238b0ead69d85aaf341a7dbaf5bd905f74ee3723a7f8d3188cc78e5b01a80eb2000d8ec1f33b6b87d03b62e0119a9b6d3057ad894af1a0341a6cd8a8b5c405a319eccae69a4a5ca0334e569f05", + "parts": [ + { + "index": 0, + "bytes": "65908e6d5b0eedf5fcd990f3bf4754b921fd5d8b5f8a66e980651e95f2583748e82c9ca746acddc9415d352b78ae6ca8" + }, + { + "index": 1, + "bytes": "7cee2084c4ab1771cbb710291b3f9dd2871378ed61a50615154da0535cc20e582be37f41e74b9187fb8edd0d4b72b7ad45c6388f050cad66ed992e5daf63ad468fa6f68916a6a4814bbc3d9b187cb37104357396de" + }, + { + "index": 2, + "bytes": "9dd531b340cd687629f0790c2c44a9f6b9ca607e164ca16f0cc0c3a3b2bbc04ead56db77d03c3af2874a52c012a9d0bbc2fa205d30d0c926f2aa" + }, + { + "index": 3, + "bytes": "00be60bd39e740cf929059858d477a87157273f84e349fded6eb9561671fd4ae72878957410f76a7f144921b14b7d72a72be3508404f1e8d8e16a290507e4ec8d2ac705a1498190cbe521a015827351ea53de10dd24642121c3ac603cebc24" + }, + { + "index": 4, + "bytes": "7f90dadc22a6d37e36f187e28924f56415d1a0bd5b8c45971ee4bcf98f89d3556216b46cd3b6b0252dff4631cfec08389037065c792c99f63c5f4f024060b6fcd2c96a71" + }, + { + "index": 5, + "bytes": "880f9d5b2e9ce6ca27013254eecf9dff678d3176719ed3a31c0c8a7bdf22b9ae33e99430942f540cf501ebc74274efedd3ce553e69c2cdfcd5b48a6f71e7f63a90437993852de753ef08db7f96833bb6d974bdb6b29512543bcf7a6dcdc6633594a85ffd672ce62219" + }, + { + "index": 6, + "bytes": "fbb088a839dccad6f2618d1a13bbe1755c8bcaf94519e2531a52c8eec836d3ea3ac29bc623fb1835180669f7c9e57c9421ebbfad30c614e72be000c1d34937ae3862f066b6801866462780cbf508" + }, + { + "index": 7, + "bytes": "f9a41a6acb3a4bb7bd9d85e71805e6f1f1ae76a5f32ca0ee114a55eed96d7514a4c3d278189182c4ae4634f8b1152620784ee3" + }, + { + "index": 8, + "bytes": "69d935f8b34b7123149d36732763b7864c7a1d0ba50db13bef7958346a3bfbd001f093fc2260322036e147bea8a0e3c375c2bc1b6db4ab81a0232e196de6a0522d61472bf0b14b6165acffa5459c247d9d1418e298d9490d" + }, + { + "index": 9, + "bytes": "9849dbb88e2788a23d33415f4a24fd4d406010e6f2d92dacbce82ff4e6680fcb0c8713c173bc95b44e7d092c5dd9f6c9002a644c84e88fae915d2141a9" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000029a4d38f6d8a45c31821c6c151615ee77e998d59b9874c6a86ecdab102de63784445fda742a978f8c9f8c540d1ac61e21a00509aed1a7d69a4ce40483070b3b5267b33bd859e69d84a7517d5bda29754fa0388edc70b5de6fbbc0c983309ba818c00", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000000f9c465d79b15fd86da91e69a9d3acfa24e953bb5dc72bb4590f7118df9bca7b80faf8d9e95d0600040a0000000000000029a4d38f6d8a45c31821c6c151615ee77e998d59b9874c6a86ecdab102de637844452f24123c0901e91617a1a5e3511268a87f91438c7845e10f324ef3c87f7bf14852dd8ebfc0fd21c8138587746e867c4a95f4c3b936983220b39f819a6fe2ad00" + ], + "consents": [], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "4770e88ee5cb741b9f08b34a6fcd148318bd08d714080dc2ce8d1797ac6b58b0", + "fac90c688899ae6c5c953d3dcff5357d11c012a7c94bfde1897e83275034851d", + "ac2536401be958bba289bc918294e5d459fc12f750b87ee1c9c17f51032f0f44", + "522e187b8ba04d5f9784532f15073fe710df32406b0bc1deb69d9d9cebbf3f82", + "0dd26a489f74d01176d2f94c9dc2d29023dba77fcd854d61a505c5e814d07b47" + ], + "size": 10, + "root": "29a4d38f6d8a45c31821c6c151615ee77e998d59b9874c6a86ecdab102de6378", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "consent_missing", + "record": "consent_missing", + "distribute": "consent_missing", + "train": "consent_missing" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "consent_expired", + "about": "a consent that ends an hour after t0, before the evaluation instant (§9.4 publishable 4)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000d5f4f7f5e1dd8b0aabee3353d257b2b8f55463940d525bb0bfcdffae279f7586000efad5feffffff00f078160911737f8f00e0cc07979aadd4fd1e157fdbc7371f1da63e509dca7683f07ed8b28eee8043660ba66c25991f3a3e9cc96c1edc9fc2661af14ffebb7101", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000014cbe37b076a1c8cbe6f64a968a6e8c3b540588cd104639aa175fb7a6ab44158602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000214cbe37b076a1c8cbe6f64a968a6e8c3b540588cd104639aa175fb7a6ab4415802000000000000000400000000000000ec86ab3050e7541b0165acf5d2f01b3e462c260c9d5754e4c68f8bba9dad1a5d000efad5feffffff01ad90f3416eeb87239f1273bd971b434022a76d7a4b0c481d5c0b0c324e2daeeef5d07248b48a601bf1fa50be21793ca0ec4b7a482ca11842fc3ac8f5ef09eadaac1d8f007899c8ed72c05d0a7d7cd1d6b2fc769b705fdc7f075f6ae52622380a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000ff06e32409ee20a9e7c2e1da5f9fb347056a2db1c297007ad1b820dfde28250de0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002ff06e32409ee20a9e7c2e1da5f9fb347056a2db1c297007ad1b820dfde28250d040000000000000006000000000000008827358585ecc9e41c76eae41c08b777919ed47ecd08489fdfa73cde8690ac46000efad5feffffff014b72020b96a6299f554e7153cb303fc1041e2c056dbfc685cd55d3fc73ff8b3f156c13aef3126db9ce5e40e3c7f7a58752402bdd8e1ebec51c880f286635175e5ab46b649e1f5ec49910984375089f30731603dc729742ca2cbbb1b7700afd0b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000001b4c753996def44ab99761c26440d07160286e0766653902f4c367a35ab5638d6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000021b4c753996def44ab99761c26440d07160286e0766653902f4c367a35ab5638d060000000000000008000000000000009bb3a849b58cfec7d17064e2eff07e261635f959ae83fa30028e6580750ad09d000efad5feffffff034b72020b96a6299f554e7153cb303fc1041e2c056dbfc685cd55d3fc73ff8b3f5ed67b027598f9cbc01c6cef7b1b9451f31f328b4b9cf2f3d1260d31fa058516ec86ab3050e7541b0165acf5d2f01b3e462c260c9d5754e4c68f8bba9dad1a5dd4bf2bb1d0cb83d23009adf4d626b66f88b4e5dc615c003e9ce8183ec279abe421a982c677e4c9d5574ea64a8928a0f71a05210f1223df1189a6788b3c321407", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000bc548b55b18782b9704fe2fecd5fb8cc9bf7a90a961941f7f4d57dfa933b1519803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003bc548b55b18782b9704fe2fecd5fb8cc9bf7a90a961941f7f4d57dfa933b151908000000000000000a0000000000000030890c547a2108a4e31a0c625660f4b1bf9202ebd02e471d783e246b6486c665000efad5feffffff01a6f943813060066bd077b8585010421512ee136b5e5395d48a5db53a14d37754ad9edc6cd4f4bcc3f2cce6b3919b92758081da174cb28c6aa8fc4dba1957269b29a0df4378504f703a02331c03784fb9488700fca2efebbe3c19dcaab8510903" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000db5f5abaf7dcab985740d137f9c994d6a26a1b66a17b5cf2c5631aceafa10aca0100000000000000c0c1702a010000000004802a0100000055000000000000000ce89d776f9fe27f72c8606f726ccb3250ebdad61568657ebcdb1ead34fb177702000000000000000004802a0100000040468f2a010000003a000000000000004b77d555619d287c46ec7b335d93ae59420d435c1e6ed815de8f118357db3d64030000000000000040468f2a0100000080889e2a010000005f00000000000000b8f0e0a5924d6d22474a9842a8984e44eca9e3b96fe9d19c9aab7e23248e757f040000000000000080889e2a01000000c0caad2a0100000044000000000000004e57eeeebe6f66fb9b4bbef7da877890ce4e42cd119434c9448cdbcd955e555e0500000000000000c0caad2a01000000000dbd2a01000000690000000000000063dabffec0baccaf97c5b8ffb94e279ab21785b04543dd3539144f93c1abaadb0600000000000000000dbd2a01000000404fcc2a010000004e00000000000000e79751c366de17bb1b0cb40b191c6435332719bef8b54d77c12347c4c31f203d0700000000000000404fcc2a010000008091db2a0100000033000000000000007d2a0c58851ba12bdabdf1a8e03255885570b98e18d23c0c38b055168422157208000000000000008091db2a01000000c0d3ea2a010000005800000000000000f302833bf6318eab432f5248778ca54955c4bdc70c22eecd0200dbcd3567e5620900000000000000c0d3ea2a010000000016fa2a010000003d000000000000007524fe9544988a6ac3c225f8a4da94bef87250120298bf05f8bd5b8abe10af0630890c547a2108a4e31a0c625660f4b1bf9202ebd02e471d783e246b6486c66506000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e614cbe37b076a1c8cbe6f64a968a6e8c3b540588cd104639aa175fb7a6ab44158ff06e32409ee20a9e7c2e1da5f9fb347056a2db1c297007ad1b820dfde28250d1b4c753996def44ab99761c26440d07160286e0766653902f4c367a35ab5638dbc548b55b18782b9704fe2fecd5fb8cc9bf7a90a961941f7f4d57dfa933b1519e181c8cfb5d3bc67a8706d5a9ca22023c06a7a85a9ef2a8830b792ad589e5e120159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a486acdfb0ac5778ea48a9261be89fe6d7ac6533552ce591818394709cc133c1439a10f7f912dfa8395acf26d56277d4665806597ec29f9e6a0e8f750bb4cab34715016a50c3b1d0b2a25ed6d5d827415a55310860d8ec3c6b670cd4523f6d03", + "parts": [ + { + "index": 0, + "bytes": "1979ff35fcb057fc0fb5013c583404493d69c12d4dd9542c9d90ebe2553b385630dd57d62dbd8225fe4d43d99b69810c" + }, + { + "index": 1, + "bytes": "12acfad6386bd6aad5a91a5c3d208a0b908289905b01c4d647ac8f4b69988ce2b90abe40ece10953b5a0b7cf68a206604188bdb9ee61d7656da3f1973fa8e161099d34cfc7b5187a2396f3dedd182c1dce405dab9f" + }, + { + "index": 2, + "bytes": "134287db97ce5d0e2e0f1bfc4bf1d5ce18ab754bf51abfd6e7463bac321a8549df45522720999a27835cdc09e44704527b3bd3df23b01a4c216a" + }, + { + "index": 3, + "bytes": "3efd5839dbfd304bc7dbde658749739b930361926564af586b6e935dd6bfa73b558d03655c9db2134c3fa56031e26afe6e2e871639846a124480a191fd943bc133f2ece83b824b6e00018eef94abd5f56779f090be90b4528a036c3f5fcde3" + }, + { + "index": 4, + "bytes": "10129d10554040bbd17769b8dc2ca5fe31bcb9d3c1adca029eeaa745392cdcb942dab80c7bc44a5570c48b989725003d443d021f57079b024e77dfb57cbdb31853890bec" + }, + { + "index": 5, + "bytes": "15f2a63a8fa8b54334275eb9fb5dab5957708ff91d3c7c9a2e4c04b303f0bc9d2e0f225a6563240f169763e24b89c4d7e49de361bf3d267bcaccc46835416772b97b2adcba5bd566ec887cc7e0ea1a441bc2f757cd13c98110db2f95a36310f579d8c3dfc1a8a8d9d1" + }, + { + "index": 6, + "bytes": "8894643cd76dc75759a8be9597b88d00a5bfb2e99722ad43f2ee7fbd12d620040817b47c209902475937f31e7c84d6180e8d4f63e5b7e88cb93b3a1d094858afb660e158de320f02758bb093dff1" + }, + { + "index": 7, + "bytes": "dac51db44f35c23b9e147c83ea6f12eab68cb27aac5baf142fcb4ee5ccb45968ef103a2faeb1346bb04d9f35531420eae0df6e" + }, + { + "index": 8, + "bytes": "8efdd37d50c46a9401f69b94f0ad005eeb0853deac1b5321b999547bd6795688924bc75fca6cb50608d9961af18c2f55d6c9b4049bb63738b23933075270e6635b14e6842bfa755f076bfe7d77676e97b66d8e9e4c073b31" + }, + { + "index": 9, + "bytes": "b5870b7d22be548ab505a6a81c24d3d86cbe51c07d49b2f92b5458492c66407973f909ae3b97357b25141e75f1a05abfd01f59f3a2e49b088f09a30a2c" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000030890c547a2108a4e31a0c625660f4b1bf9202ebd02e471d783e246b6486c665444543fd279afb15c9b31c3d27b817a578f4b539479a1c7034ac938e875e2dc9a789fd9cc3c755aa186b2a9cbfbaaacdd01400a80f567b3f1bc2367a0eb56f4be80a", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000001aac811cfbf75d48840afb03400986ce6a67834927708e5714883b0f9da67ef080faf8d9e95d0600040a0000000000000030890c547a2108a4e31a0c625660f4b1bf9202ebd02e471d783e246b6486c66544451451d9b753d4e73ff015a76a011f06ac0a5e406b6bf387045536b6cc25c0207fa35838edc4b9c6d43de700deb182b359d9770f83fb4d8786b1a6ccb33cfdae00" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a000000001077d16a00000000b609a14a30f1f50daa5230f4871e7e6ecdd745615c26f16ae1bdf168f91bfb3f0ba3cfdaabd28330f6190e01935c8fa69b93dce82dc59a6c6748b7c613d704937118fdf89b1e2644137b9fe423b82404" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "14cbe37b076a1c8cbe6f64a968a6e8c3b540588cd104639aa175fb7a6ab44158", + "ff06e32409ee20a9e7c2e1da5f9fb347056a2db1c297007ad1b820dfde28250d", + "1b4c753996def44ab99761c26440d07160286e0766653902f4c367a35ab5638d", + "bc548b55b18782b9704fe2fecd5fb8cc9bf7a90a961941f7f4d57dfa933b1519", + "e181c8cfb5d3bc67a8706d5a9ca22023c06a7a85a9ef2a8830b792ad589e5e12" + ], + "size": 10, + "root": "30890c547a2108a4e31a0c625660f4b1bf9202ebd02e471d783e246b6486c665", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "consent_expired", + "record": "consent_expired", + "distribute": "consent_expired", + "train": "consent_expired" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "consent_revoked", + "about": "a consent whose digest the key log's head lists in revoked_modules (§8.3, §9.4 publishable 3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[\"ee40a226fa7a369ac8a211df4a348cd91f55ef7db87281bd1278c72161ff26cb\"],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"9b327a97a644137dcc5f6087f3b1a6258d8546ecf344f3aebc5c3faddc8cad6e538ad3bc500486823781145fda8835ce9bde3aed1d09c36eef87ee9bf7ca7e0e\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000c71b614c1328a1e6be266878349ff16e6576f128082a55ddb48ea228866ae186000efad5feffffff00a9a3f47210e16271826db0a9e8c13ecc20c27139ec8a9deca003e4692c4986bfb4de90e25a88f4057d6f488bb7c543d6e4e2e1e79aaf48f9baaff9f1dbd35e00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000043eab10293fd6fe8294983305d0280578b3f346967a31829b758f7aab0466d0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002043eab10293fd6fe8294983305d0280578b3f346967a31829b758f7aab0466d002000000000000000400000000000000bb752399e7c188ebe015db6a60d1f7444af626ec968cdc8b8e8af34077f2fed8000efad5feffffff014db3ed4c17c9317dce7c7a15d047c980a3eba5d0be7436cc82c9a82a09d086a5073f1c2769dfaf458c963fd160c39d027fc92a874f3b75997ecea1b97aeb1c722401ee6bb60d4fb73932fedacf05a9d6680e529f806e247616ff3295857d2302", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5030000000000000070c30c7594a56a1282745059427bce392d98fb8ca93b37aff8d9e8c0ba4c5bc3e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e030000000270c30c7594a56a1282745059427bce392d98fb8ca93b37aff8d9e8c0ba4c5bc30400000000000000060000000000000011721a56f85ce377baa73957db9a2047e7b77ad525af5da75b3873e8a4c5b3ab000efad5feffffff014bd5824e9fa595e55f62cfeba0e21ba00f44f674172f93504d92b4cd9d291fb10ca694602d762b9a990aca0a8fcab0527d6ce999bf29b723c6e76c36c5590ef030d2554c443314fd11f49b8c91d56f8133430cf3cea7742b51ae0982ea66d20d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000b3368344031fb46770df66e9ff69198da3d20797ea1fcb799fce957fab3141036033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002b3368344031fb46770df66e9ff69198da3d20797ea1fcb799fce957fab31410306000000000000000800000000000000e5b3a559484c0471c93632094efb22f8b3fde4b8daa59fd66436ceb4d3085839000efad5feffffff034bd5824e9fa595e55f62cfeba0e21ba00f44f674172f93504d92b4cd9d291fb132057394989a64f73e483655227cb970369e91dd2865f0fede533d74ce157343bb752399e7c188ebe015db6a60d1f7444af626ec968cdc8b8e8af34077f2fed8d65d2b0c1c595d78f23a916aefa27ace98a9523666ebf2fd9365ab091052f05ba1570d46ee7b80b4e70b9634a7f8359ae28608d02efbd1bbf0067be3516a0304", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000003d674591090d7dd014dd20e841695941da3e905f714cc95737cb06ffc028bc50803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000033d674591090d7dd014dd20e841695941da3e905f714cc95737cb06ffc028bc5008000000000000000a0000000000000029b498d20e45928a23eae307b460085de4e213b75c528f1620ce7a33d7578633000efad5feffffff0155d2c74cb0d0e80ba9234f84c02fb7404957fba08dfbb71b1e6e43e4f967152e36dbfdd2fa994a51f2e910de20797a63b3d1dfd30f26fe30506c52f1b222eccbda4f13c7372bb920ae7d6375aaca32ad1a08faa8c087de620e8a872a9f99520e" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000001fd89b55d2d3765d3d1c7c4723ac9c4e10445cf268b9a435f471601804a6bf2c0100000000000000c0c1702a010000000004802a010000005500000000000000eb4d22f3d0eefcfa0f75263559e8c1e5f9c44184fbdd8d07f6d7e3faadabf22802000000000000000004802a0100000040468f2a010000003a00000000000000e76b2c16ec98dce09313e8b335bfbcedae1d42aec81b95012daae84f5784dcf4030000000000000040468f2a0100000080889e2a010000005f000000000000006c136ca8bafe097302694e6bab2f0e4a61b0b91125e32e461414aaf54a837a4f040000000000000080889e2a01000000c0caad2a010000004400000000000000fb45d946a3ee50be3aaad35ad7ab4279fd1d89cea57deaeeabbf881e06ed38050500000000000000c0caad2a01000000000dbd2a01000000690000000000000047ddc740828b50e910770cfb44d6a702cfa1cabcdee0314e3e7a35b9ffcc61bd0600000000000000000dbd2a01000000404fcc2a010000004e00000000000000fa5e215e4439a897be0208fd8deb802f41a4378c2fa9ff9e5bf5d37d7a3b63e60700000000000000404fcc2a010000008091db2a010000003300000000000000d5a65bad424ab0fc1c10790b387c5886005e908ba20fe9c8cfd65a168edf0c9608000000000000008091db2a01000000c0d3ea2a01000000580000000000000092af40549728412451e28c3cae5be621d0a09309243f73aed57172ae9fdb6a8c0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000ef730a3bd41697dafb4e30074fd393fb813b679b38749cf495c1f71ed22fa6d229b498d20e45928a23eae307b460085de4e213b75c528f1620ce7a33d757863306000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6043eab10293fd6fe8294983305d0280578b3f346967a31829b758f7aab0466d070c30c7594a56a1282745059427bce392d98fb8ca93b37aff8d9e8c0ba4c5bc3b3368344031fb46770df66e9ff69198da3d20797ea1fcb799fce957fab3141033d674591090d7dd014dd20e841695941da3e905f714cc95737cb06ffc028bc50f94d69d4da7fe52a61bee8cbc96a76a67cf6c48f42caff8dfa2e74b1245427aa0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699ee40a226fa7a369ac8a211df4a348cd91f55ef7db87281bd1278c72161ff26cb37047e67bbf98f2ffd72c606c8c144a50e8e8ed5d55e41492b47e7c9b74ec5a8dc78a5429b98cfa6315bffecfe89bbeeeec330fc86c47674f6074064f180ab01", + "parts": [ + { + "index": 0, + "bytes": "c125a82ffbc893dc2cc8969d0a53cec027389a288133d5c51e4d512b3e454594ba5c76465467000845fab9941b71d78b" + }, + { + "index": 1, + "bytes": "fef3e7368c43e3a12f166fac72cd50f8858fcba65c30f9d8c090f5372cb23f7e93febfc5b907a7514f0e4c31e7fc4506485dc4c59ad3f4aaaa348c03256ad552b438d87c119727975697a367b7dba842c4f6cf1403" + }, + { + "index": 2, + "bytes": "6fa408afc5d0c013b63c290786f265a693dced3018e550896baa700bc3e0e405443d8f261c0fc7dfc2945291648eeebac57ffe9fd93e69e272ab" + }, + { + "index": 3, + "bytes": "647a940b7b3c6ff4f2c35b86671670b8268fc7c08b74f9b477b05548b2b87ca2a3de15ccf3c8e46964c587029175e4b519fd723bd2b60182cb231edb6247ffc3a68cd201d31de34390f7aae9074917d3a73fadc5d89d8e85a7476442ab84c2" + }, + { + "index": 4, + "bytes": "7cf1522c4e39668254a689afa8117c63706da7d8e88ec087058c40e609e754ff5313d22df0625db6f7db86ec6bb4ae361d87057303f4c220418f0572c373fb5a4a654537" + }, + { + "index": 5, + "bytes": "7f8744a2d3a3ea267e98b6c6d62dbb8f3bdfca38200899f6c3d7ccf72d26e25e82623d9f2ba0263e54cc23e3c00fb1edf701d65154821d25a6afc9d39a83010a92263d66d93084ff20465d5fabbc6b8742948c42387c5524ee61c0cdbc948845b228149a8c3fe7bad4" + }, + { + "index": 6, + "bytes": "7f36be39203f1315b744e496da6ec49563e5111658f7ce2c4d31340a60dcb9e1f70f18d73f996c72d849220ca079d2dc97c7a0dc25c3c95874e075ef3009d5b676f03e520d12d73fd063b2fc99a9" + }, + { + "index": 7, + "bytes": "8725d4f7b58ffd7a6eedd1d2cc50e58b4913dda98956a289df7bec62caa471e0e9c4abd2d349031d018a858725891f37cdef19" + }, + { + "index": 8, + "bytes": "e815e2369fcc882665ef3eddbb12be959b631184a3a2470e84dd8e32939527495d50950ce98605ce02bd578e1d0cabae78795128fcf3ab8b4c19f755cdcb2247ddf732fc46f5dd75236624047fe29a8092b1625c7924144f" + }, + { + "index": 9, + "bytes": "c9d4f48e6d147719600cf832f94578fca2759c632907018c64c6362cf55e0403852cf114c3ba93d50338d13b27ae2cfa0f08737bae3b4e6949cd580c6d" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000029b498d20e45928a23eae307b460085de4e213b75c528f1620ce7a33d75786334445838d69628c00db5410332ffdf4402fa0e9d82af22abe2b31f857c7caa92feb7515b133e695d4b0939c6450175937aa1ca2f1704718cf8f9b723349233062c708", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000003925a720947343978bfde9b4f78c5aa3613c3fd219b19e467b8169580f7f25b180faf8d9e95d0600040a0000000000000029b498d20e45928a23eae307b460085de4e213b75c528f1620ce7a33d75786334445f1974b47c133cba94538ed356b3f94fe8ff218f72aa0737b194a44b05459425073b55c9452da0ef6335c72cc5f8bcdbdb1b7d2291e5f13ca62353a2b163f800c" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000001b7662dc6d17ded5e41395931bea511094281d0ace35230dfdcec1357deb30e0b15b782be2f245a450125c8f147a8655c2aa7b638697953c0840d19d70904e9ee9bf0ef0b9bd378a64d9577439932b05" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "043eab10293fd6fe8294983305d0280578b3f346967a31829b758f7aab0466d0", + "70c30c7594a56a1282745059427bce392d98fb8ca93b37aff8d9e8c0ba4c5bc3", + "b3368344031fb46770df66e9ff69198da3d20797ea1fcb799fce957fab314103", + "3d674591090d7dd014dd20e841695941da3e905f714cc95737cb06ffc028bc50", + "f94d69d4da7fe52a61bee8cbc96a76a67cf6c48f42caff8dfa2e74b1245427aa" + ], + "size": 10, + "root": "29b498d20e45928a23eae307b460085de4e213b75c528f1620ce7a33d7578633", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "consent_revoked", + "record": "consent_revoked", + "distribute": "consent_revoked", + "train": "consent_revoked" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "minor_without_guardian", + "about": "a performer the device's grant marks a minor, under a consent the performer signed alone (§3.1, §9.4 publishable 2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655600056d696e6f72040074727565077375626a6563744000353934323534363530303435303030333264363839336639383061376461643438336166373062346531313661313062376361613465323035323539333639391f358457b8a6efb06e2153bbf2facdc74fe3d654fff361cc92031b40bf3c60220ac18fa13512fe54bc5c9d1efd8f1e4d49967b2350fe974d9764fe1dac68a10c", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f59c95ed994b3e1e6c455b2f19d35eb0fe27aa567025c61b6759a013b5ca13b6823dc77516e866dab051157ab0ffff3ef39f51ed783db6e3da30c31ff1ab3477e6ce2f39cb16545143086e8b902b2ca43ba04e0825d3010b2b567fc0cd87d0b908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000002b6334146fcb69388421c295b6b5b39ae52a42daf391ca3a8fe9d31973f3aefb20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbec39ff632bc339f538569b12932c81b01ea33212e4035a6274b91d9ddc96f4412c7eb74289944451fbad1ef4511db4f86071677dfdb3af0ecf5d6952c391bd690c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720300000000000000e03b08b74595aed85f6e19683606b329f18004863e1fdb4ca6deb072757badff40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50001010187a43370d52ed53dfec6e039e3c02b130ae65eef029d9927f6cd2e2f817f3751a2cd3bee6c6064533f0e87bbb6e1397055ad8ad7a2a39e95001b08603f68280b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7204000000000000002533c5e8d321a5a0ccc42cfc3b98b71662185d7f3c772c20e812f840e9c1c5b140420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500020203a5c2301832e410c6de5042abfa6ef5778d5673d337fee0ab10812fdd08021ce3007f7d2c0a3cffb3cdc4650cb2380d97e8bb91abbb879b51794480d3f4b07205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a112442baf879033f4aabdd7e165a0c8709ee7c55657ea7917ea58f3a784289440420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520001000181798385ea13c1fe205925ea4104b2041f463d6acb7c13f0575d5ea8383352e39cd75b25d9dd5b46b2d2a95299ad56b07b84a9c131fa2d79f0ac1aec76412f05" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000020643464943d6a08dc0ed8ad723738c92fdbd1edb286a26a65eadbf9f3470654000efad5feffffff0015e4deae167e0bef1eed3bd9530aa8ea71d546867ae5a90fa7f65dd4c5d313976ba03bcde3b19be8ca8a9622d5a0cf8f7e9b7d2863cd1585d3286a5b339d070f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000309a15af1f23af59962cea43dc1ad0d20d7f83b3cff239174078977636f35233602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002309a15af1f23af59962cea43dc1ad0d20d7f83b3cff239174078977636f35233020000000000000004000000000000004d29327dadd97f504a08991f0c9f6fe8cd0b85449e216c087be45202ee2e18f7000efad5feffffff01fa7528c2736fb3423d3993e609497b04e1631a461c020f0b5e21873fbbf2226954a220e74ca8298fb660385d7b1e1eea32bac39a81993a3989a4ca410a35bc0bc2c583f6fa76b7bbd65ec8e48e2de48a4c4cdcc22af33bfa44a3b0d63968c30f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000e361789d44d90b9cc56ec79bcd534bf3e438535ad80572acbc404bc420110426e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002e361789d44d90b9cc56ec79bcd534bf3e438535ad80572acbc404bc420110426040000000000000006000000000000007878cf0021af9a5270ab4eb14115765758eda6cd8318f8d3cb12473ce495a4be000efad5feffffff0187f622c67ef47820c4610871ce13b1171f7754160a2140b627c8a91a3df60653e6d169776628488473d1c25a07d865ace90600ae4f42794cfb36ac2eec6765db33f60d019a547545dcea90da78de77f912c1fa24d1e2dabf48b3bee36f011d0d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000a564df054d11121b27d4dd87317de9f9775401b157f0565c7d2662b3cf9b37516033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002a564df054d11121b27d4dd87317de9f9775401b157f0565c7d2662b3cf9b3751060000000000000008000000000000005d1e4b25dd73524d17b07aa815f74a2ddf3dcf0261b499d0f32f8976779915e4000efad5feffffff0387f622c67ef47820c4610871ce13b1171f7754160a2140b627c8a91a3df606533d910ae57bccf798cced72fc8774f3d5225881f33ddd58fe4be4ef29121cc5ff4d29327dadd97f504a08991f0c9f6fe8cd0b85449e216c087be45202ee2e18f766de5811de4d9019fdb93519d77e6efac9f763789b82ed181dafa228a638e705bb53cde0e1d4a9be8facf7d32ead48a1e30ace3346109ffea70e027729d64e07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000006a9431d37365a07bcc42592e0655dc39aa2c14b506ecf635df83160ea5bf68c0803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000036a9431d37365a07bcc42592e0655dc39aa2c14b506ecf635df83160ea5bf68c008000000000000000a00000000000000e5796ef5688aa9018bd08b622a4fa6bc23c93837d088be3c79cd74816aa2f5ad000efad5feffffff01fe7f91784b62840210910edb6747a93c6044be71a39fda360948139be69ead97750568a0a31260b856d7f874290442817a32bed6118b6d3a19200c65fe0138e53610d1a65cb4b50814e075f78c48f2fba1372cfd27c15d0e27a656adf7160f08" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000d7288a35bc3b3dfae815f8f6967cb5281cb661bd8d4fd53c99967b43078a4d0c0100000000000000c0c1702a010000000004802a01000000550000000000000003c05ed7d655f5f4594ec022a0307bc43070c36517a50ded6a91327bd58a7c9202000000000000000004802a0100000040468f2a010000003a000000000000008e982ea2eebcdda9b03d38922ae03cc0bff544b970f0eb7cd856494ade5bf761030000000000000040468f2a0100000080889e2a010000005f000000000000005854905aa89b5bf39ec70d26d38f5019f36b8f8a64c2c65d4aa31fd85b896198040000000000000080889e2a01000000c0caad2a010000004400000000000000f55d0150a4f267f3bbd1d09e320db59192e7ede3c5a0ffa78428ea845e18d7c10500000000000000c0caad2a01000000000dbd2a010000006900000000000000cca89f32d1dd88a41d6a5061bb28e9707b65ef0e18a45ca65352e55ca57459a20600000000000000000dbd2a01000000404fcc2a010000004e000000000000002e3e9d4b57b55b3f7a1161a6287b899c96efebe025718cb8b0a371216543dffd0700000000000000404fcc2a010000008091db2a010000003300000000000000b63cbc4548f78756596995f54e4ee08f10b2d274d7df16ea94d44981b0a09c2608000000000000008091db2a01000000c0d3ea2a010000005800000000000000a0cb17399a18fbf41a323d0101fb8e69380e67042d4eeb354b4cc9fbbd1519a60900000000000000c0d3ea2a010000000016fa2a010000003d000000000000002795ad14167d45b389c21009f83bac29ba3c2d5e08d57f29c107f4aca29c7227e5796ef5688aa9018bd08b622a4fa6bc23c93837d088be3c79cd74816aa2f5ad06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6309a15af1f23af59962cea43dc1ad0d20d7f83b3cff239174078977636f35233e361789d44d90b9cc56ec79bcd534bf3e438535ad80572acbc404bc420110426a564df054d11121b27d4dd87317de9f9775401b157f0565c7d2662b3cf9b37516a9431d37365a07bcc42592e0655dc39aa2c14b506ecf635df83160ea5bf68c0a4c529e959cfcc4fe0001c9a431e61959e61b73e5905bc1d88b327cf1c7ae8d90159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699972a89b01c5fbcf536b297a64a0082764b9ac8cf1c109d351aedbb1f44f09f7743ba4b8c831c93e3391a78cb621795e5f1ad84437bee4fce2855a10c9596f56bdc95305939c9ba20801b1c07846a67bd863279eaaa21ba874e70e1e6a3f17504", + "parts": [ + { + "index": 0, + "bytes": "761f5b814c69d4e74ecefa138346848e30aacb00ecbd6a9a9f7e83a271c75ecfef891582f39af9dc1c9c6b81f79741ca" + }, + { + "index": 1, + "bytes": "fabe18af43007b2d2d433c2cf1f7afbbd1834c7ef6620fc026d746f923a5b16257d2dc63094c23d6941587f0da377d0c03007901ddbb8f73cfc07ee471beaeac3f4ea908e82cb97f3264a074169c66d0cac54c9038" + }, + { + "index": 2, + "bytes": "21dd2c25aca22e036927b1a0afe6527220ac4675060d547453443321f19003039d1eeca6192fcb864153347fe391674b4af5a49431144928bb30" + }, + { + "index": 3, + "bytes": "0b38a5e461ad1f220f17b5b29dd9595905d09a47a9b62e36c0bc6bd6a060f09a9a56afb2ef90bbe1a2bf38b93594299f3d57b40aeb58acc4219415173f6b05caebf50b8ba9f7cd7085c26e458d5e860f0dbf7da3b3284a40964830774aed5e" + }, + { + "index": 4, + "bytes": "43e534df2c5a93358d6b90a70398aca630d7cc54b7253d35406551a810e51e0b7aa41bab7ae228d850663f913c17cdc9355c1728f9a8212457e0f0ff6aaab91966f44faf" + }, + { + "index": 5, + "bytes": "0ee5cfb45d2995abaac569e4d5a5f6ea206128bcb99b2436d1572c9192badf8f62c484a0fe9b39f1c974034912c031f744e471269ec0f81d3475dd495396f6fba863f8bab7bb2964c6c8bf9d2ffa4266b7b10a390328625df8eef853bb7036d17095a40927a358f689" + }, + { + "index": 6, + "bytes": "2e8c2c6ac33a7e33983e67c60da66d8619e01956ae956b9a430f0f8dee23604b4af54d349eb35fb5893225e5b8761d710468a22d47e0899587bcbde6ee28adeed5a7281ab9b940540e15c6c252f0" + }, + { + "index": 7, + "bytes": "535af678085e2e856992138654c8d26f6f2dfad73e2f7fdf0f3acef793b46bb0b64ed5c99f59f0ddf25622165f9a62a1b81557" + }, + { + "index": 8, + "bytes": "79fc9feb96f58380127cd4fb0995b61a1256d11c01ec02814c8f772995b63b107483a0a49d7745d120ee95995f5cf631eca3f2b3618ac1d252c75751d3c598f04ad2a1816255bb8cc0764754f0090f352a99425100d5492f" + }, + { + "index": 9, + "bytes": "8508f4a7f215043896573bfe1e48b03dcbbf1b48abbab5d9a15cd32d35d7353290d820ddb69bb02ad2cbe4127467b69b4b8eb169a13915e8da25a90975" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000e5796ef5688aa9018bd08b622a4fa6bc23c93837d088be3c79cd74816aa2f5ad444544958ef95760dbfb6acda28282328cf3c6a3f909b32a0e53f89de1961828b78fb65763fa889bee5be5b1cfc91b6140e88dc1b6b70b5de6dc0d28e46d56a2ed03", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000004c79f5c38e0b174ace936ae4968ede5de28272a389f49deb354918b6df2102d980faf8d9e95d0600040a00000000000000e5796ef5688aa9018bd08b622a4fa6bc23c93837d088be3c79cd74816aa2f5ad444554a5dde177c91f470d43620b772a7a1412aae9cca9e1238a23f5e7072746e0fc306cf277c9d325d1a73af0978236493b26fd723ac9864163e006bf7d9688070f" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000cfbbfec49acbd07a32aa1e87ad786dd418dabf26ef59e01467870e102844a2ab4f22750973af348b0fb5c93169acf46f2aa881c647da7e9f561402eea02e45f02fb5db946787105d4915eee70fb8460a" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "309a15af1f23af59962cea43dc1ad0d20d7f83b3cff239174078977636f35233", + "e361789d44d90b9cc56ec79bcd534bf3e438535ad80572acbc404bc420110426", + "a564df054d11121b27d4dd87317de9f9775401b157f0565c7d2662b3cf9b3751", + "6a9431d37365a07bcc42592e0655dc39aa2c14b506ecf635df83160ea5bf68c0", + "a4c529e959cfcc4fe0001c9a431e61959e61b73e5905bc1d88b327cf1c7ae8d9" + ], + "size": 10, + "root": "e5796ef5688aa9018bd08b622a4fa6bc23c93837d088be3c79cd74816aa2f5ad", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "guardian_missing", + "record": "guardian_missing", + "distribute": "guardian_missing", + "train": "guardian_missing" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "device_not_bound", + "about": "a manifest that claims the take for another principal than the one the device's grant names in its subject attribute (§3.1, §9.2 step 4)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000009588e24ec270ea59677ef164603ac01768ee6a199b8fb06d0501e9331cd79b9a000efad5feffffff008a0747a2211f0620dffc6bd7f89b805af435138b45ad74bcc80fbfb0fbe3e89a94d7a93cc2caf3b1c9d49bf800a236643268acf43cf1dfd797813ec95427c609", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000620fb96b06d2f3a507d68e74ea924e1d6708c969e286871baee6ad02109f08f3602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002620fb96b06d2f3a507d68e74ea924e1d6708c969e286871baee6ad02109f08f30200000000000000040000000000000045d7b414ee01b5bd93eb704a62d885c6e221c222f65ffddce35804321987864a000efad5feffffff011dfb08b76e5c794818fe41319e2fc47613a83a2490dc30a2a960c68103ccbf5125757c29e34e290a3cb89d3f986d8e953503cd8384c6cfaf0d1da805efa704b94e78b2055cac23fb73c6fa76ffbb2ceda74634d50daf90496620739ed538a20c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000f9a1eec80972f3110ac1a9c401ac4555fcd1e95f96903f5ea87b66965b8e77eee0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002f9a1eec80972f3110ac1a9c401ac4555fcd1e95f96903f5ea87b66965b8e77ee0400000000000000060000000000000005519bf2d192dea7853e59364a1116b4998d00fd1888a5b8490b877a5f0cdf92000efad5feffffff012cef60a6d3239e62c116f3fbe7d69a62f73ef94befaa56d741c15ee384e34867d49dbb6cb28cad10c6e491e249c45e7b37fde3a3e02b8c1e889dff25eb1544dd8c7d151cec76bdc9fee0aecbb4c93d8b6f76edb4c574b3412a48058dd7f19607", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000acd50c715f1d30aa569db8c3c24296b4d18804c915aea79be2110239506213806033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002acd50c715f1d30aa569db8c3c24296b4d18804c915aea79be211023950621380060000000000000008000000000000002fa9df9adf7a0768f70f8ef66c2e9d569eb90c87baa809ed2ccae05879626c60000efad5feffffff032cef60a6d3239e62c116f3fbe7d69a62f73ef94befaa56d741c15ee384e34867994b3003c8a53a5a87b24f3029f87ac5e25bd9a4c5186ac8a5ae9ecd1b6a40c245d7b414ee01b5bd93eb704a62d885c6e221c222f65ffddce35804321987864a0223d675464cfeca9ab4957a75a09271e3cfedd1786e1d057fd1a74b50908a46b2ee8e0873408d220ce524ebecf58674ac8410f9e8fe97cde3a10833c4a16404", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000006fea0803e89913bfd848191833fa43d01fcb225e76073f2eecc61650de3cc45a803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000036fea0803e89913bfd848191833fa43d01fcb225e76073f2eecc61650de3cc45a08000000000000000a000000000000002f4741ae799e9252f93cd8e0a24940cd9ee63a90caab7954b95f3abfc84358c1000efad5feffffff014045227790b5014219a16fb89dae6deb4839532ce75dd5f2829d5c126f7a5809dbc167341bdec429d60b797e9b1e4ef37b5b4db78dec4b0ac22f4756732548bb43cc4c203f52e5d07f5f94b9b5a0db87c7ccb2f2f39d4454bd1e505c3435f300" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5aa26ee0d0025f9b60f30a73d2c67159f09f6d1c678b11f3cb528d5e4f2d6f198a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000002a09664e56d5c286cf2b8681f7e8d8737d0412a44d16746d07450259f508eb700100000000000000c0c1702a010000000004802a0100000055000000000000001516292a1451ea495ae892dbef3455e0f3c314edbad61f7aca6181463a7a0be802000000000000000004802a0100000040468f2a010000003a00000000000000f6aa3ce338e94ebb0f69f068088e604179edfc6a15e5d06a5bf758b2fd4d7cc8030000000000000040468f2a0100000080889e2a010000005f000000000000004fe603f752e33fd9c728a2799c89b5f67787e29aacbad4a986416a8a38060449040000000000000080889e2a01000000c0caad2a010000004400000000000000f6f40b0d6bac453bea455f96176997b6e637df295e4c4eb7221c988050efb9530500000000000000c0caad2a01000000000dbd2a010000006900000000000000852263d347b92c6f0f7d9d4a6afc97b7d7e67af2686e82acf0c570b7cc34096c0600000000000000000dbd2a01000000404fcc2a010000004e000000000000002cc661909284cb397eee12621a15a4d2d9dfd9549a874c4e28da8b0df63a3bba0700000000000000404fcc2a010000008091db2a01000000330000000000000010adffa6b1e2a58b34f393f54d97f29a1c5b54cc56c7de1f92a39e97a37c25d008000000000000008091db2a01000000c0d3ea2a0100000058000000000000004e4bbeb9303d75a6059c53f6dea32b8eafa35881072102725e3ea06204f9aaef0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000052ccd27ae5b12049f44968a1be8e7783b95fcfe525bdd14c037ee3bbfa483cc2f4741ae799e9252f93cd8e0a24940cd9ee63a90caab7954b95f3abfc84358c106000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6620fb96b06d2f3a507d68e74ea924e1d6708c969e286871baee6ad02109f08f3f9a1eec80972f3110ac1a9c401ac4555fcd1e95f96903f5ea87b66965b8e77eeacd50c715f1d30aa569db8c3c24296b4d18804c915aea79be2110239506213806fea0803e89913bfd848191833fa43d01fcb225e76073f2eecc61650de3cc45a35c4a211468d5ba98bb2f4b304e233eaf92e7bb69e587498033c2b0998096f3d01aa26ee0d0025f9b60f30a73d2c67159f09f6d1c678b11f3cb528d5e4f2d6f1980000000000000000000000000000000000000000000000000000000000000000f8e4003b4d98d7fc3f2d4db7c05ae2f73f7d2d82ac988a393c9c2f20dedbc0ca5557497c63b933146012c3b9e37a8df76af2f216dd77a740ea3934d50830f202", + "parts": [ + { + "index": 0, + "bytes": "2d389996a1108701520b63dfccd799cc107885d8dd66947f11ec1c7ecb39bf285c1c240786c8e8be3e6c1454ee1aa6e9" + }, + { + "index": 1, + "bytes": "9aea29d7f05f9c117978543df1de1f21a48f58f522f2f60ef31bba9b10f52caae802a49c1e40c6bc9bc2fb1bbd9f492656f04d3adce93f70540833b2c1cfed19846c10e1f198edcef807e31db65bfb75ba68eff637" + }, + { + "index": 2, + "bytes": "95367bb449bcf06ee022574dd458f5655c168c6fa208758aba387c0390b198ee1403dca19cfccd480844cd89aa11f634ad562ff0bfe27f33d91f" + }, + { + "index": 3, + "bytes": "9dea406b5bbfd5237208ae64047ed6222a16309a93b0abcb6b6efcf93e6ea1f0eb48715c4f4ebddfd3692395ff9e2d94f3bc08e4e62cda199a926b0bad2e584de0f129e1efbd5a582e25d6e59ed33fc75c440e5a874bdd6b52b49e220f529b" + }, + { + "index": 4, + "bytes": "ccc744bd0776f7f837be4ef8e611974813431fa06f1c3afe0870503290fe2f6085f64d35c6aa2bd94eccf2ce5849524a0a4190934a347cc8c7580d1108a0af584477e1e0" + }, + { + "index": 5, + "bytes": "abaa4b362a51f8422473d2507110499b2f05d432fd4bc8b3ca598261f4c1a0e3b91c97b85acf4157e8f8f4974257b92241c3b68c9454f3bd2dd9b7710c39dafaa5c666283ea709ac2acace24f91d687681ed9657d58bd9f98970c04e77a2c172801adb658adcc6ff1b" + }, + { + "index": 6, + "bytes": "86c923c28ee50f775109f25a0724d8fdbf5183c1051fb2e340ecd68fd134741620a5c6ca68e46cef1fc5574dc31872e3a531c6ded5a84210aa00ce9c283c83d1c3c60ec882d32f665106cbab56f1" + }, + { + "index": 7, + "bytes": "12d9ea35448a505bbe8930d800c31f919aa0592fb3b64e7aad07f5b9921eea42342c1bdabcc87f1c62e6326c876ba06a1c0dc8" + }, + { + "index": 8, + "bytes": "7cbfe284ecf5a9268562fbe357865a1ca4b98db80f8961d2073dfdb57349efad92e7655126e56b78209a141c74b7a5c1a5d1e223310cd00cc386cd0d5539f43d42a9dcb090823d02ffef9c1a7d2e33f5abd8e73f21daca6e" + }, + { + "index": 9, + "bytes": "56e095acbcf0463ddbd25d21d25b4d9aaadb8f093363053fe034ad1bce3ace6e982094c33923a6613c4ef1ae51f182ff7d168854383bd6b7443c478999" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000002f4741ae799e9252f93cd8e0a24940cd9ee63a90caab7954b95f3abfc84358c14445992fb4eb46f9338d6edd46e1b680c627274bd42760d3e41bc2394511d32df69619c199908e6b6f329d61dc39967ade283588df21b3193bef26774b0453023503", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000000000080af4eaef9776b8f701da9fc6e4dcfca541463dbda3e83cf7a5b12fb03c50d0380faf8d9e95d0600040a000000000000002f4741ae799e9252f93cd8e0a24940cd9ee63a90caab7954b95f3abfc84358c1444519fb053f6534f74975943abaef49c0ee43d2e8b193306c76117c610ee371077c00cf037b987e590b495a7e90a47b56b6e6cd16114decef22d8a2db7eb2f1a10c" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000002031a6356376f4729a3b80001b24bd1a5a1f60377a608a5dd8e6594a325d375f40a8c675660187649dcb2cdaad8b01262bc5087fc9a9968176940b72fbdba6eb0e37c18754b0867ce0a6086293b1c007" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "device_not_bound", + "at": [ + "record", + 3, + 0 + ] + }, + { + "name": "recording_not_permitted", + "about": "a take in a room whose recording policy has mode 0 (§9.2 step 1)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e00000000000000000002444546525373fe5eb8fc3611b3dc664275b9d315863ff99c75f0243586f69ae6e8ef3826a16967eafaf2af651c85237cd853fd3a5528f046347fd22cc469f374cd02f30e", + "grants": [ + "57524731018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04bd927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c65000026051cdafa73910034114d278113e24f85651650c5b85811caa5bcf554e820145cc5a2d735bc9380cd3ba7f7aa53bd8e2c2c693977b5e502d6ab8ce5eaedac0c", + "57524731018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939ffe7e02361e3b12a5c3bac092c1042d2f20a67d6b16461b0e26ed7471b33a4bb50db65768bc96a96721c4b56462516e7d3a5ac2b355092d0d3a5b719963d6006", + "57524731018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c6500001445345e3230e217159afbbaa55af9f48da62f41ba3baeac7992cfbdb243a8a2a5d72efeb6a327347cb51b02216c53f2e8892260629dae9be994fd53daeb9a0e" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52123774a457b2610f95354382f0a137e80b26c13227d4edf3aae68af02c2a12c50344b5cdd2e6d7bb1344a7b3dea0e922c310db3bc13631e6854941ac5ca1fc1c9e3b6e6d146cdd68123539bee71d85a0cac22c27b79220dba67adb8f6b3cb30f", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000007bda5c30a34f7f85609e4d11889c35ef88be2687fe73569e643bf7abe58abda6000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f54fdfcaf02b37fa1f9673076f1e59f1e97111a7e998c8952beed72eb6edbb66cd5fa067bcb3b09ea25670282ce1f83e5739a3e059f1edc39b4d1a03eb7b628e388360b46ad1163876b643c6191c6f604d26089a177a53fb9587f909c5a7bff009", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720200000000000000f589989220e778745563b317ef3a940fc59c37944a210c05604742e397cbb1c020a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68e25bfdeb230df7187ecfaa4b40c653a2f5668bf47b0c977b046afa030439287b1f39a160ecb8297c85acbb556626ff8c070ee2b46d388ce2230c65924eab653eb9579f8c8c2c02f20887f3589e13fe840ef09ca4e6570d0b0f437da3ea4940c", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720300000000000000f45b04b91b0eea3bb38c5fe2bb60ea84b2d69f87c48d6677bc545a06fb06867440420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50001010165536ee007b1aec2b569173011cb4911599167430a85b08cbc1e2af14eba4aab83ce44d91c453fb6f0bb0d1bd8a533088e7aef668b809bbb1e3eff79dcf55108", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000fdd55518a7d71f51b494b783609255870cff5cf1e0ccab2099a5de6031bbc30840420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500020203d9eb7b3ed6a385c95e647456bfe328d9e3227dd03b183f452bb513c7c350bc1444874c2dc9b3c4157fbca3edaef72fc5f8457bc18099dccc80c3bb13132fcf03", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7205000000000000005b02377f918deede26b3898a52b088297ce7600c21e60c6efbd4afd8601202d540420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520001000184d2df4dfe765b3d6d3e74bfe7c9ae30fa0e7f9bd3efc1055ff84f8ecd9f09628f313b26db2e9c6ad14fb3ba3a4856b51f2357eb8a4fece4a6568dfc250b9608" + ], + [ + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04bd927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f000039b1b8cf8c89f8e7c9f49894d1f39a562f2206f2228384259a11839a209714e21efc5cd030cd9755f1c792975ef4383356325b2e4e8b5909761f9c4576f78700", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04bd927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5201000000000000008c80107558b18b424ac10f0aae45eb3c41f4f2117d6d7072c02a533e0825f20e40548900000000000008160004000000020e00727573686564207468652072756e0006c124d1d867a330e8ca58e3935ee344d52485d5dbd4310e365c1b61c7022b5c3291ec26025cf08587858ca004f3da4c697b457909ec7ee5b5e5e210601a4d08", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04bd927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520200000000000000c501caa59dd49d508671f1eeaf8f5f1b479713a2e2616c3e7d0b4c51f718731f405dc600000000000008170004000000010f006c6f76656c79207068726173696e67004cd6b20b42a6c179f27f0b9fba172052a1f3477d2d82e77841a5b2f4d95c553aa6d9465f59677c22dd6000336b2ce90d7917bb324afb51c56fcaaa29da811f0f", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04bd927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000025ce394cb5f60a59a6fb496474da6df59fbb833de7f8f86e92f43476b305fb3c0024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50272951c0531270efa421c2be4bb298430014bac264157b53e182ee34d6f380617058673fa5fbcaf5c9d21d22f3181c8751e45aad2ef588640670414d388927307" + ], + [ + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b725e0142c5bbdd4adec60372f81041d39cf44d32caedfc039bc3681966e6bf28dd39d7ff73ee336f2b85dffc7efb12b1d4508ce5a5a9de2c8382ffd63c59b108" + ], + [ + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba481700000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00e0f626cdb2da560f6009cf2dec853cb0f783e45f434a2aabc0cefc9b0789dc67ab2e701d5e49f02488e88fd69ca7492a0b97d0a28c6da6d690d8e3dc1c36690a", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5010000000000000034cd16c7f6458a1982a46206cda6c7cf3efca2aef458d3bcb871f6e8cfa008a8e0a57e0000000000000c7e00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba4817010000000234cd16c7f6458a1982a46206cda6c7cf3efca2aef458d3bcb871f6e8cfa008a800000000000000000200000000000000d4d1705358898593e79995631cf56636e38c62bd40eef01f7f1e87d68e3d0fad000efad5feffffff00218d42ba9deb9b80c2fcc721d045c8eed402749887a0209459dd3d82a8d918acfac58b9af7c24fdc405f5b9403290be9dc5ee303ed8e6215d7ae798349c32803", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000111484be007e11bcf68df2a969ffdc0009fa28326a4cf3b4d951fff58b2563e7602a9d0000000000000c9e00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170200000002111484be007e11bcf68df2a969ffdc0009fa28326a4cf3b4d951fff58b2563e702000000000000000400000000000000417a0cdc1f58424b277cc3ce7de8b7ff235a001a887a5f2c57829d72a55287b5000efad5feffffff014a2d714fc82c0417595949af836f4f3b5cc06d1a266a0feef9326be7c6fc6fb1c4d3f884ddb834efe32c69e57cc922140e6f04b5dd0f719657f04ac05e9016fc6018b8c5c0af6ef45825f1cacf00af3d221262b2b5c8abddfd15723204842a01", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000c45a4adc5be02c4b61a9dc68aaf9d0168a308cdef153a6a8572ac9e23672116de0aebb0000000000000c9e00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170300000002c45a4adc5be02c4b61a9dc68aaf9d0168a308cdef153a6a8572ac9e23672116d040000000000000006000000000000002d836266aac51c5d8152601dc3002cd53e16d099a33ad9475fa7a34d708276e4000efad5feffffff01e7216b191a4274161af860b9b0bf77022b1d539db7be28c2eb5326fbc48057b1dd1ed354e0c1298dd75c6445af10908f73848ae8b5562ca7e3244884d90b1cadeebc7247a60fb0dfcbb336c1eb04a668393cee610ee74a3b653649f302518f0b", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000cca2b12e85e9623d3e064914988b255e94b3a89c43210a4c257a6070e8c3a0976033da0000000000000cde00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170400000002cca2b12e85e9623d3e064914988b255e94b3a89c43210a4c257a6070e8c3a09706000000000000000800000000000000c3f458f9c3227ccda47166f6c6710bd07af3e8118d7472083201da5cc31c526b000efad5feffffff03e7216b191a4274161af860b9b0bf77022b1d539db7be28c2eb5326fbc48057b144686dbbb3539c1fd3ce696897f885c91adcdac067298a813b0ed9f03299347e417a0cdc1f58424b277cc3ce7de8b7ff235a001a887a5f2c57829d72a55287b53966ed0a9cdbadfcf233abf958b4f4f4d577f22a70b871c4674546614fc9e959029be2e8ac7d7c5684cf7b8df601c559db805ebe7155c3e85c5efbe33e38e30a", + "57455631018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000462ea9bb745902e26919592552b74a00e0fad815c9647125765dea963cadf407803efa0000000000000c9e00c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170500000003462ea9bb745902e26919592552b74a00e0fad815c9647125765dea963cadf40708000000000000000a000000000000005a4177eb0f5ff00f144a031f71c1728670c7daf509b6acbea90619f31a83ac13000efad5feffffff01b29d32344d729fcbb7f551a474ff4d0ceb0255e2ea2331b0fb24ba4cf6802f708acfa3e906ee472b089abebd1134616caa61a2346ee8cb279b14347d8a1dc280a318ebef098bd587631c4776f683cd085f7d8d40d4739df51a2bb00134d02909" + ] + ], + "manifest": "57544d31018982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04be57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936998c80107558b18b424ac10f0aae45eb3c41f4f2117d6d7072c02a533e0825f20ec1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000d47ab8b2d898141c2d2b155cfe26bebaf589f8d2cfe9db4333cd8b1ab631c03a0100000000000000c0c1702a010000000004802a010000005500000000000000425dae03d026501d4ecfdebc4855f972945bc7d0b67863445f45a8c94a1c857902000000000000000004802a0100000040468f2a010000003a00000000000000299a410af4136fdb344e4456177bcc0e59abdb19d8e7cf9199ec4f06b38259ec030000000000000040468f2a0100000080889e2a010000005f00000000000000ec595d2b6d443bc81bc42ee04bfbbca04855bf0646455121828aa0261f0d8525040000000000000080889e2a01000000c0caad2a01000000440000000000000077bd05add56fbe961498d14f28e1c721e4fd1b25d64e25375d12fc4bc314af660500000000000000c0caad2a01000000000dbd2a010000006900000000000000e76dc69c6527955722403577dbfcd7ebe5051bc95090826e9d3dab4f7b3dd9990600000000000000000dbd2a01000000404fcc2a010000004e000000000000003f5ced7d4064c40ced507f792073f7421aafef8952c27af5f5506a44da0752130700000000000000404fcc2a010000008091db2a0100000033000000000000009b4dcc518e27b2a4304a7ff270e1905b42f3fce0414378b9a6b0d3c0bada71d408000000000000008091db2a01000000c0d3ea2a010000005800000000000000ac762b509083ef022cbf41bbe51807babc1dbcd5678e879e3acc3ccee16881ee0900000000000000c0d3ea2a010000000016fa2a010000003d000000000000007f25fdc82937bb509bae25627bbb67db7eeff99824f508329c21ea22188ffcaf5a4177eb0f5ff00f144a031f71c1728670c7daf509b6acbea90619f31a83ac130600000034cd16c7f6458a1982a46206cda6c7cf3efca2aef458d3bcb871f6e8cfa008a8111484be007e11bcf68df2a969ffdc0009fa28326a4cf3b4d951fff58b2563e7c45a4adc5be02c4b61a9dc68aaf9d0168a308cdef153a6a8572ac9e23672116dcca2b12e85e9623d3e064914988b255e94b3a89c43210a4c257a6070e8c3a097462ea9bb745902e26919592552b74a00e0fad815c9647125765dea963cadf40744ed43b72a326b771552f466bf16ba3e6f6daf4ecab773ae6b940f2fefb302ee0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369975a1446ed0eb048d1be0098c89dba4f45c462714c11574c725522f5080eb18c00e34126cc03a17672c1ac6bf5c5149bee849224e6aa4fd719a89c6676d3759d559015d099a8756e3943228e0a2d4e164f9b0f3307543b035d221399feb80090e", + "parts": [ + { + "index": 0, + "bytes": "4d06bb6bea02373c835800565b63d2d2810ec6aa63a10a0fcc753829a699f4bf2f778b04070028cd1350df1bf4c65301" + }, + { + "index": 1, + "bytes": "6cee04f27863b458f46c830ec3e456684883565cc11a43f024efb2c6242cacd441090efda6889ce487c482e3a6ab4791ed6cec66d0cab4891ec46dca3b4bcc494af757428ffb3d0bb5827b9f92c7b4016a056b36e7" + }, + { + "index": 2, + "bytes": "a512982cf8848f3cd2add7dd15c802867d6037e2fb41bb02ed92ac90906f855cc359e5e199a22667489e7521d510dc4751972ced21a49466637e" + }, + { + "index": 3, + "bytes": "8d7f762670f733222316c39f1cd6a79a3bd85ed9a61dc05f234774b7dbca457fd9b8a29dd565160bebb036e5cc97a62bb74ac938d8e78b7ae454d7cd88d5335fec00517af2d7337d63a4a29011ecc4e871b78dc89491467aad133846002019" + }, + { + "index": 4, + "bytes": "5fdfca3e9b2713eec36d8d9d099f25c30cd548506f5615644f07db5ef1dcf92ee85304e9d845905e990b1b48e48bbadcdeb237cf4a3b2d6b91b73ad27989a97892acaaee" + }, + { + "index": 5, + "bytes": "a6f9910f8f17a80883e8da3d0d71c8b56996cdf93a268abbc63f4ec945363ff5aa936d09d686256c3c5af93f789ae35e539bf35aa19cbe4382ea4c04e0a10fe65544180e83d6141c0b6435c2fe266d27199948b8a00a5e454a1038d3b17e4c7725baee3de2f6d74e8e" + }, + { + "index": 6, + "bytes": "b2bbd6aa82df5f570a8d05da349fa434109f965a2f46959d84a8b03554fc5654f77654ee87aee294c5ce93736facbf7fb4cfa4986651b3b01b63289acf1703ec4eefa19265c78aa6daddb8abc0ee" + }, + { + "index": 7, + "bytes": "8ce1408639a3051cbc549eada72758b5e5ee258ca99e2816d1dabcf7bb6297508b3ff73e6af096f9ee6e7a9bd0340dc18778c2" + }, + { + "index": 8, + "bytes": "bb19613800a8195550f2db75a88407e9fb7be4d455d6f504dff1783be9055f45013719b24e75f7852da17e75abcae817a379347099ab27e33437992a7b3c64aaffba0c3ef5fd803d1727f06addc00caf1fbcd016afe83e14" + }, + { + "index": 9, + "bytes": "c401d0c8482c00c8ddc03fbcb576074c1b7dca120f753d3ca67020b4ae54223d22371c7f630b1de9cc672beba6ada859bdeb9adf902022faa768f9a39d" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba481700000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445f07c37edf92b2bf08acbf53834310a01551a279ad6e2df7feb2c27e471b5a119bf53f59bcf819fe9c8ee7b10de5d8e222a551390a4ecd6b2e33f186c2f98c60a", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba48170100000000000000538b541bc26bd4467deb2ebb081aa9dc6782902d98d4d5a288a9dc01566f9091c033cbd9e95d0600020a000000000000005a4177eb0f5ff00f144a031f71c1728670c7daf509b6acbea90619f31a83ac134445fede9b358adf29843bcce8858f7f809bac6a378dc1b82404ca7fd63a53e2c1a49ae4874c2876408276d4f859b746719a4ffe6544d8a97010dc7686ecc46f7f0e", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13c1cdb14b783ccec5a041dacb39ab1a620b28de0410778323449cd17b75ba481702000000000000000e592513ceb90984974cdfd21cab04aba5cb6bf19c3e21b7f0b29fc7b0e3301880faf8d9e95d0600040a000000000000005a4177eb0f5ff00f144a031f71c1728670c7daf509b6acbea90619f31a83ac134445c37eb9c58ae10c0facf9b9ac4ba2139f0a2e320eb2f7dc1411b13962fac4c0bf783438d0c48048646ebf920624cbc79b989c5cbab514edd43b0fc5de3747670c" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000078982b00ee7491ef69852b451763a96df42fc9059e99398e725637693b927e04b8017d06a0000000000f6f86a0000000065935ffa0025aaedb41a8b1ce8ab7813657c83af85b22f4eb567374ccd07680bbc6d01d9f51d6b4784a12a21e1ec1a643d86f69c5632dacf891cc4a7936c76f43f84e8296a28070a20b8c9be38578907" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "recording_not_permitted", + "at": [ + "manifest" + ] + }, + { + "name": "take_unknown", + "about": "a manifest whose start is the digest of a chat message, not of a record_start to the device (§9.2 step 2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000006babe523b408e739f6f41ecb8b2d939bffbd5c344e4d6af635cdfe30c892d56d000efad5feffffff00fae38486087af83fa5376af7772af450f2b148bc9c026fb37bcedf8333d21d23e117dbba174ca27656648d5d53de284561c31a97ac73fa3f2309b4a52a1a2f05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000000a115ed41bcc7b92f628f5a15fbf70cb23633092b234c992a97bc9e15ca8829b602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000020a115ed41bcc7b92f628f5a15fbf70cb23633092b234c992a97bc9e15ca8829b02000000000000000400000000000000b83f42181c2e845f51c117a9fa7cb869b04ce47bf3955d71e57d5a22e2d8477b000efad5feffffff01fe41704cbaf9942ae70f43d8711af18336962d34bfa3c4b8d750e5871727005cd559324346562301cb0f777de013847d72067fd162c2184d5f19ced6f61f2fe3d5dd5b66fa1ea14a124988fa68437e96590f4716c5b0236a8cee77037229e902", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000e1f6e5a97b29512f4e369887613c712f408dc0fb0f140c658164f3f685829fabe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002e1f6e5a97b29512f4e369887613c712f408dc0fb0f140c658164f3f685829fab040000000000000006000000000000000e15371841bfbb6bac5886b1a4dbd977b306ad762b201e12312a18941716436a000efad5feffffff0189e9b130ed77585c58ec1d89c5a0aa990cacadf85eddffe5de7c8942b885b20d5a8abad86647174e7f71cd0703b028c0a49c61829d4200f86c1a8baf842a6796c13e08768e04c8c0c9fcdacd9e68bbb118ba100ee91cfd2980cbeca809280e04", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000084d296466aecb0aaa9d5c4dc3a42db18b9675202f722da4671ffff9f6b10704e6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000284d296466aecb0aaa9d5c4dc3a42db18b9675202f722da4671ffff9f6b10704e06000000000000000800000000000000a24eb2a588a9503b7799aa21440abcb692d0471df22ccd01cf630f118ca93913000efad5feffffff0389e9b130ed77585c58ec1d89c5a0aa990cacadf85eddffe5de7c8942b885b20d2d05afb19651f74134525116c3ce5d417be678424a707fbd25d1f8f5eda95904b83f42181c2e845f51c117a9fa7cb869b04ce47bf3955d71e57d5a22e2d8477b4c2e04303e1af4228373c7c884aac70c49b364dd222930bd3739e80420dc76065bbf0e7813d786462fcdfae2b08e674aef94f7a0df54d4962ffe594a532eb10d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000071aaf95aa31411ecf18380023027cd035fcb58d2e3fe87a64f956f6924331b35803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000371aaf95aa31411ecf18380023027cd035fcb58d2e3fe87a64f956f6924331b3508000000000000000a000000000000006c08e343844f6ee635e1aed68e2665b52fbcfe6e1ae67f7af5cd7e6be1bfa27f000efad5feffffff018444f3532084d86b3588d20a5956f7c1eef87b700f6aa2656743856f291f8fc506a524b26541d45c6937c08d8b41b4b3e578a2fac7a45a7018a412fc6aa685c7f67c2657b38ba0cae78755710704972f38322a0c7573349cb54b20a65bf26007" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699d5009aaa37996c5630008b34e79ac11bb8c1123284da50e8aa55a3247c9dd3569e4a54897a878b5e3abab45167d809743609055c82928bf2f5d06c26f26cdb3a0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000e0277bf9f20dd91ddf2f0e4df5db504cae96b37f78342f19f603d95790a898e50100000000000000c0c1702a010000000004802a0100000055000000000000006146395a3b52425159e9284f882a5bb2a5d0c8fc1d3dbef6548f8c14091b217b02000000000000000004802a0100000040468f2a010000003a0000000000000031e302ce92c8742462e6c5d0cfbce1b4032dd3db3fb4136ea2839b98560ffcf5030000000000000040468f2a0100000080889e2a010000005f0000000000000045436281de1c09bb1ea53681fbb6c18092da758df62933df1d78d89387ef1c66040000000000000080889e2a01000000c0caad2a010000004400000000000000a04034ecb4db5ad5b40cd21bdaefb312d55a03c466fcdcc97d3940ff4fe18ac40500000000000000c0caad2a01000000000dbd2a0100000069000000000000003fe86247fa50ac46db15fd3fe8631ce96442c5b8226dc648172503212d2c729a0600000000000000000dbd2a01000000404fcc2a010000004e00000000000000b77cc6af5927e7763087c5c2af76673aed5d4faea9ab561e9be45b794d3698c20700000000000000404fcc2a010000008091db2a0100000033000000000000006e537399ceba78af949189b9563062ae2cf2efa0892e593e9094fd1b30b61f8608000000000000008091db2a01000000c0d3ea2a0100000058000000000000004327ca3d1648810bbd644420f4b8dd7644d084bf292474513fb4a7d148b40f230900000000000000c0d3ea2a010000000016fa2a010000003d000000000000008e9d72e5ae0585d0a2eae68b30cb148f0577f4eed8e82bc816419cf09cb11e276c08e343844f6ee635e1aed68e2665b52fbcfe6e1ae67f7af5cd7e6be1bfa27f06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60a115ed41bcc7b92f628f5a15fbf70cb23633092b234c992a97bc9e15ca8829be1f6e5a97b29512f4e369887613c712f408dc0fb0f140c658164f3f685829fab84d296466aecb0aaa9d5c4dc3a42db18b9675202f722da4671ffff9f6b10704e71aaf95aa31411ecf18380023027cd035fcb58d2e3fe87a64f956f6924331b35d29d4f60f1543f274c97aeac07f814589101a2d810c8f690ba65f32eb317ee5c0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936996ab83263ecda0a62adac72229e51eeabee3ad576422e3c4635ec555e20b339d0dab0ac2923663dd7e6280df6e467e8da9a71bbcc00fa1a80ca574ca867e060d49e7cb2652f44de42e00a652ebf44c6458b7eac5e274f3d8d08eb172c271a6106", + "parts": [ + { + "index": 0, + "bytes": "882b4793bc8a8e0d4d2dfd935f0d8acebefb4ea7d54293759abe8e491eeb946a3cf6c65e32444b5f3bf3c469a93c2560" + }, + { + "index": 1, + "bytes": "d837baf2cb09168ace281645c2222cabbfc470499eeee15b3260d3185af7345745cca0efcb1e906dd754d801d4bd840a1c40e853afc1ae398ca1fc7a0e3b687089d20db9106edb60168169cef4993dc0d57b1ffdae" + }, + { + "index": 2, + "bytes": "9599df25d237204040a911b1c1bb5249ec04dda791b8e4bfa1798642227387141157dc90a7ac05ff092e3d51bef4b9c5522724491376e5bd9867" + }, + { + "index": 3, + "bytes": "03bed9e737489c457efdf06f5de6ad5545dde744fd61bb3523220410d794c87b33dcc1685ac748920e49118d83411bcebe7d6ad46f3531b4afbbe4720a9d47d965b5cc5eec07c53eb46e7db148a56516ace7bb2c6aa4a14008d74119993721" + }, + { + "index": 4, + "bytes": "2c64460649ba5d559c85f6871d9cd60c6e219d7bd7d3262020a570f37aa2410492149ec6fd4960a03b72edfa54d790f4054905f35eee03b13ca50819faf0bd5e8489ba25" + }, + { + "index": 5, + "bytes": "eee8073bc7dbd1924787b44f623308558eaaa57d87417a1b23a5e27b36e1908e1a34ed784d3450817706834b33ec6045c542df0ab19da038a8f8d62697cd7591a8c56c27cfa42476e8756eb7234da7b1903be84d59736c6c46995ae8777015662697206385f2e15f20" + }, + { + "index": 6, + "bytes": "ec5456b68685b5c484cc45d8585469ed7eeff1a27057a4552edc5594a43a7f04196f9ff5c9a4272a4bcc858e20585f004a90a528a4a100f802ce0295f09e6c35308b29dbef4471fd229c2d59bc6f" + }, + { + "index": 7, + "bytes": "9b9e86b9b472e917abbbdd8412f6f2832d5a44317f7b0a8c001d4fa75a3e3944faad4ca66d407e8d51828e8ef5b6cdb1617d54" + }, + { + "index": 8, + "bytes": "7d33d087e0c99c075d37a4d7fde6ef3e348abe16d2b47b4ad6c81ed5f66df2e061b5e6843f482b1bb5e39f943c68e1c10bd4f97b144a32cc8aa7ba2127988b8428d8982042a7cbf179a02dd9507784d61f4ef323aee9195e" + }, + { + "index": 9, + "bytes": "c6e20aa9829b14e7ae681062f66fc573f40fc844c6679787d529f57866d49c3107191cca6b7da14eb067c8d4f7bec9b6af33216bcd1c2f6342e4cf9bcd" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000006c08e343844f6ee635e1aed68e2665b52fbcfe6e1ae67f7af5cd7e6be1bfa27f44455ab15d5156260d07f89c7b78f6289fc98ef9d764e235d74b26cd080cea6882df58eeec9ae2daaee54591cf57f66a6369abddb4063bc7ea590b8bae46bf9cd302", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000002d552172fa85e77e235927b1d80ed767eedcba938994f317bdc1e64f9d6a213080faf8d9e95d0600040a000000000000006c08e343844f6ee635e1aed68e2665b52fbcfe6e1ae67f7af5cd7e6be1bfa27f44457744ecde874faa974abb99f485d98f26210de094f1805e681577a157c063ce194d4bfbd3d34cf0e141a15e301ecbae8149424e601f8bc97c0fea3c3d4189f003" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000001f62ca25893f05abab179f70236219a9964eb79f4252e9edb6d7191609f3c94d5c103f67a6a3404b36e9651b9bb1414bc447351f8a27f4a3070b6aa51a520d7761dd68850105e666e8c6374fce40ce09" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "take_unknown", + "at": [ + "manifest" + ] + }, + { + "name": "commit_malformed", + "about": "a take_commit of the device whose payload is ten bytes (§5.2, §9.2 step 3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000eebbe3c61ac9637638e92aec917fbc68ee26efdda6271a14f884fd750c4e1a14000efad5feffffff00094255ad7ccfb7e2e0b1b2117738e45addd08a3dfafef82e69a9ee7f33fa0e128b741915f2ef14ad0f12853c269feb54a5749aa69b23ca4021ad0d27936f9606", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000b0f5c3a544815bb3dc88b7809b3da66e5bbacebc33d3e95c3181fc0b33290437602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002b0f5c3a544815bb3dc88b7809b3da66e5bbacebc33d3e95c3181fc0b33290437020000000000000004000000000000008909250c0ae624610b6de7980b454fc3967d8c819eb2f545aec2c286c56e7fc9000efad5feffffff01fb40598b6a8f4d0bf18ce93cd019108cef36a54da32182867817c7020aae4673c88e289c245bf06ed3b28f93e3f58be0489ea25d0a81647097f5f7bd32f2b9cd18b72ab7eeb2fa232c3321c0cb8963980218527ff029f68df9151f5e89e62505", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000a8f8b447178918caafe0f056cd32be99c042edf6d6299a6e6019cd0d5ef21dd7e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002a8f8b447178918caafe0f056cd32be99c042edf6d6299a6e6019cd0d5ef21dd7040000000000000006000000000000009835ce0bb254c2c698f7538d874c7c2ac56af18321941428c71b65f2935a2ade000efad5feffffff01bbb9e235848dc6b1e3b82f412812cfad27a8e0eb92fa5f09f2124a6beaa23db412332694c3a47f32a40749b3b361ea6dc0afde7fea5a6b7e31b5cff8efc90399fec7260a55ba75cc4b16c7bf240cb556891dc3fa6d5ca74dfa58e869880bcb08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000a3fa0dc8969bb1f7c0ad46a3181100f7c24c1259304343b5936df8392819294c6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002a3fa0dc8969bb1f7c0ad46a3181100f7c24c1259304343b5936df8392819294c060000000000000008000000000000002a17582bd9d1b09b8056636f787b0de0aa6a248f281cbdfe12a62b4223c855c8000efad5feffffff03bbb9e235848dc6b1e3b82f412812cfad27a8e0eb92fa5f09f2124a6beaa23db40afe3780e22b21b2311b326605247f4d8794a0a57c73dab1f8547fb97488a6b18909250c0ae624610b6de7980b454fc3967d8c819eb2f545aec2c286c56e7fc94f93b02906eacdb7be1d804f2f548f0e24b0919c5d87325d683a7f0e9a516ab70872756fdadde16443382a7aca22a55ed13ea1f07c0a4d3dbc8f3f56c4404a0a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000002d8e4da21e7a8ebaea8f34b620cd1814aea3360832df87013cfec1fa64862bf2803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000032d8e4da21e7a8ebaea8f34b620cd1814aea3360832df87013cfec1fa64862bf208000000000000000a000000000000000b14dfe325978445a226c05be688d95e7566b259e5cd7d4c07968a7968a751f9000efad5feffffff0104f52ed17f8bbfa5856de9464f1b3e1c8858ab49c69f33a78787d535f1a2c81a1c64673b75b34ac470a6af5a4d119301e8a13eba64e1f64fdeef85b78a17172245a3cf1dd11e7a817f3a623165dd48323125a7533b197802c230268179604305", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5060000000000000061e4659f079b407503366c85bbed71dab84c5aeabb98b63a339a90f82240716d4066030100000000000c0a00000000000000000000009d9bd90e88568efad02a05e85474d0c15e8b7d4f069b42ebea0c66118543c5cea6c9a04f6ce612b82cf50b29b6f983234ef6933c7754b0ead9ae69a2953f4f0c" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000002fa2f4e87cdd083eb6e5e8767cb577255cced2d05fda0590302636821c9f2bdc0100000000000000c0c1702a010000000004802a01000000550000000000000020697f81f26812695fd57bf3ab0bd5b9e056748e66f78879cb8fc13c342cde3702000000000000000004802a0100000040468f2a010000003a0000000000000025e4696cf63b522b5e558b91b3a1789b8e5d5882b6187efc83feacf7451ac813030000000000000040468f2a0100000080889e2a010000005f000000000000009201c88aeadd0caf929ecbff9cbddadd4720f8e00fc7aeb18fc4d7bd0034a985040000000000000080889e2a01000000c0caad2a010000004400000000000000bc1798a48086435617ebe498bc9aa323c34815cbf6c02b52a286b9ea31afc15b0500000000000000c0caad2a01000000000dbd2a010000006900000000000000b90c977bdff94efc37fa43add38841a9d7391b9442548db5b385dddf934a7bf20600000000000000000dbd2a01000000404fcc2a010000004e00000000000000c1bfd4ed664f22ef1715ef41b42d3db116761a688dd7c1d17a988316493c9ea00700000000000000404fcc2a010000008091db2a010000003300000000000000c9a4864a5ae708a71d98b8d35c105b5c68ff5095367362413eb23b19d752526d08000000000000008091db2a01000000c0d3ea2a010000005800000000000000187348b6870aeab9f3e917bfb88fc7f280235cffd533655194f93e503f3742bb0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000eb76ef2989ce7c5753e83a77865d5cd8a5dbf19a21152a502dfbfb8b5a9f65ed0b14dfe325978445a226c05be688d95e7566b259e5cd7d4c07968a7968a751f906000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6b0f5c3a544815bb3dc88b7809b3da66e5bbacebc33d3e95c3181fc0b33290437a8f8b447178918caafe0f056cd32be99c042edf6d6299a6e6019cd0d5ef21dd7a3fa0dc8969bb1f7c0ad46a3181100f7c24c1259304343b5936df8392819294c2d8e4da21e7a8ebaea8f34b620cd1814aea3360832df87013cfec1fa64862bf261e4659f079b407503366c85bbed71dab84c5aeabb98b63a339a90f82240716d0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699eb282b9d85f0bc76b77cb16f68eb394ed3ebedf3c4c20436a22ee8ec67f9569338c8cebaf0ace69c20ef48fda15fb6385e5937eea457ceb34f47021118cbd1ff893b93b505640ecf5df8c209ae156d1957fda2485781cf7396163e8043a0b804", + "parts": [ + { + "index": 0, + "bytes": "4abec62258e980fb76b445538e7d6e7bb376d54377a17e0c8067a8c01332e3e010a9b261237db7f52ce173dd1eea0e95" + }, + { + "index": 1, + "bytes": "6852bfcdbfb2d3f4acdedc289d35a83189c088a2afeb5f7b9d9efdf36581ecd7aa8cf4c6370754d00be7d547a1177ef38f4eef2b2137a65073baa9eeebbf3e3e9b2865cf2bf476c52b9eea8e64a44de5bfed154951" + }, + { + "index": 2, + "bytes": "12d88e65ec76f4515a86fee43e4abba6c3117e74da41026276a9feadc506f767e59dcf18461b5a869a4d13c485bb94ccbdc6824d85b7066d83cc" + }, + { + "index": 3, + "bytes": "fdd4085a2dd2266ec8da7f13e014b23a63d6862f98b0f82f7580c093608a56f793f270177a5afbd1708e046aff5a4d71a462ce8ec65ec383975cf3768a515e4a759b6ff42a8131424ace781f9f0f728390d03a1d2331391fa2685b40ee340c" + }, + { + "index": 4, + "bytes": "e9240cc9b0aa26c103e8dcc4daee44ddcb794e9de24732929df5398a7222172215fb07e09dcc1253efa58cdf7abdf3d142fdbf81f8fa4df28de90485c18d14d31777ae1f" + }, + { + "index": 5, + "bytes": "54f29491f4f50f8b9d7b790446d61f7e7f6124a0c3a49aba71ce891be4e78f8fda149fed1906040e8da6514a0ae5e4ffcd1b2339b94c230096eb1f123a854757e7d1cce907366f331d0d1889d66fdebb9c31aca6b7d0b9a128342d285f5ac0a1a6eb3dc7fdf6d59459" + }, + { + "index": 6, + "bytes": "2d1e155f87b9e10c55537ad12b9244fac67888e3090c4bca2465dd4196f3d45d071cb1db00d06b7c8b75f17c7704e7f98b95dbe66f89d97c0a72792ccbedc5733338f1964ad99986bb4ecd7e9cec" + }, + { + "index": 7, + "bytes": "1e51ae343827e4d97b2636bd60931f953d7ea333433938a19c8679811471792e39d1937cd7f3e9d5c5c34f3ff24a930ab730c0" + }, + { + "index": 8, + "bytes": "f1d946f74bafda0c409c4cbfd8e8a08447b03472dfef0e98ae35ec94c9a6b02ef31c476322ddea2f1a6c63daaa68a8abe28d0e8fdd66211dcff856fcfc1290232b951f09e2aa02cda60ce82580ec60040125200ba03fe9c4" + }, + { + "index": 9, + "bytes": "73811570ba8bf2703fbfca4cab49f24ef79378c2f6712e915f3c0ca1d95e01c33baa98ec04477f4dcfb6f1e6aaef30b97f3bb0c6bddfb6b274ca69e1b8" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000000b14dfe325978445a226c05be688d95e7566b259e5cd7d4c07968a7968a751f94445e743ca96d650ed0f2afb8714e52b770493088c4712ec32097d378d50568d10b1ae8d7e9875071c3ea5e333e182fce6b277a870baffc7dd04cc871526cd29090d", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000003619ec601e30cce97df7c31a573710f4c11cd4b758491b81a3b060ebc043c0d380faf8d9e95d0600040a000000000000000b14dfe325978445a226c05be688d95e7566b259e5cd7d4c07968a7968a751f94445cff183b0b2f8e1c47fba6a111d9911d35c503737437827d570da6c0bca55e6e256c5e7ae13a8a35aeb9f9f0d2e903655ef7882589315e6aa68409ffdf903d601" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000feb469a705c7509e2d86b8dc33692086f2a15134dd2e2329f49f783da22c032ba237fb811ed5fd57b9008a3780a7be8788361af114b1a3c1a432a3f73b9f59416b6da24da2afac544b898a6327cce10f" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "commit_malformed", + "at": [ + "record", + 3, + 6 + ] + }, + { + "name": "manifest_invalid", + "about": "a manifest whose claims byte sets bit 3 (§7.2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000acba4f18c2dc6cbc8dfaf93b5c03c61b2e9287ee8f4dc3e508198a15dd4af989000efad5feffffff002301738839af54bd6765caa104b6a8c9139261b133eb7dc2293fd8b0b700d2b97aed608cc42582f4c5afb4618ed4f2eb69f8a087f64c8b94971ded6ee303b306", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000051c4692b446363ac00ab4143e9d4dd0c6f44999937b3fb723f0c9c3ed3103774602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000251c4692b446363ac00ab4143e9d4dd0c6f44999937b3fb723f0c9c3ed31037740200000000000000040000000000000062f15d4f1b2fc728cc907aa6809df1afddf903a1c9eb286fcbf8f3caa2224250000efad5feffffff01f961afbc8663b6574b763930e86b4070da55640b3d8da8823640b8df77efdda00405befd8a4e06ef1ae28898fd58c7abb06a79014163e266652292592c29fe0faf22e507818168e9ae4af1465be240d78ae206cc860e081a905251bd8803af09", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5030000000000000024724b24dffb5f687178c5e7201ffabc7e951ecc301caeeae5ed1162ff7cdddbe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e030000000224724b24dffb5f687178c5e7201ffabc7e951ecc301caeeae5ed1162ff7cdddb04000000000000000600000000000000f60665b0ffca54f4a56e2622a4151d3aad61a9efdfacb91510f396f991550800000efad5feffffff010b83dc33ee12f86b33354b68c2413fec6f870c2bf2d9509a53fc16920bbb10540644f53983f592e4368b8d8387183a84de15f77135625308bdcf5dc9575c0417aa8ca0db0577a0d8360e13f20e74845db5547c9fc0c2023c092831f01cab7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000005853ea8fb28d6adc5455d5e5a216d1ba6920af2e895ed91d998061ab85bfc7976033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000025853ea8fb28d6adc5455d5e5a216d1ba6920af2e895ed91d998061ab85bfc797060000000000000008000000000000009c017071252a255e49fecaa4e65b13992c21656734f5450e6cfc21d5d2258ef3000efad5feffffff030b83dc33ee12f86b33354b68c2413fec6f870c2bf2d9509a53fc16920bbb1054a3799146f8804320963f44c997baeb1e53570e2b4aee3b2e220efc10b860b0f862f15d4f1b2fc728cc907aa6809df1afddf903a1c9eb286fcbf8f3caa22242501feca1103545b34c1e93ea26bbee31dd78a268ef53a543466926e26853119acf8ac7b8c6e71f69b5b0f8407067628e6c4cda7bbe8e11cc7bb63253edfe4e9408", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000003f34dce5e0cf8b19053b30e7cfc97080a9f9c2bf4478c81a30cd40511c87d2dc803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000033f34dce5e0cf8b19053b30e7cfc97080a9f9c2bf4478c81a30cd40511c87d2dc08000000000000000a00000000000000370426a07743076057cf1c8c906815e2183da6b2633cf69873436eb41d230743000efad5feffffff01be6ed371527024d56511608d1164333e039c0ed26c58cbe0b9b8520cdfb7e0b24b65d147c0ec343f5d704872d4efe300d22f18e0386fbc2af969533755b01a7646ad561e4115bd3261d660f3b8b9a5e63c02196c42dc94132ab7d269fd1b2800" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1308060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000c9548432efc51b95c9c77ce3ada0c6d3c938d27ed4ee16d6a32d3d96484294590100000000000000c0c1702a010000000004802a010000005500000000000000bc07f628901429a50ff947c13e0ad89a2122a353acaa73233286ebfb8f47f65002000000000000000004802a0100000040468f2a010000003a000000000000008f4ef53a46baf8a258449f23a5942a2f8733390cc3ca1d9350b1f4a69d6e2ccd030000000000000040468f2a0100000080889e2a010000005f000000000000002d21d40b61fd24a2a3e8ea14be8b4f57014afa9625580909a8301b7489c6389e040000000000000080889e2a01000000c0caad2a01000000440000000000000034c98e60fb99dbe45b1628ca2c89843024e328999c80d78b9f9b416e219de1f80500000000000000c0caad2a01000000000dbd2a010000006900000000000000d202af719e03b9609a6d9d5e8a12a6469576a2981e490bc72f30037f56cdeedc0600000000000000000dbd2a01000000404fcc2a010000004e0000000000000077e47b8d6499c36a69bc607beb2e5d8fd4848610232a6a4d4f8bb5e8d3f3927d0700000000000000404fcc2a010000008091db2a0100000033000000000000001827535ed23986860b4fac73b77aef10872ec58f11f07877c50a08932100827b08000000000000008091db2a01000000c0d3ea2a010000005800000000000000be93b0881f38c9dd373d05d61d55c63c51ff7b45d4c8ac041fdebb759112f7ef0900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000262ba40ca34a2989dd7f6f595dc4ca6b7757eccc96ff05b6d33322f8b0711d5c370426a07743076057cf1c8c906815e2183da6b2633cf69873436eb41d23074306000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e651c4692b446363ac00ab4143e9d4dd0c6f44999937b3fb723f0c9c3ed310377424724b24dffb5f687178c5e7201ffabc7e951ecc301caeeae5ed1162ff7cdddb5853ea8fb28d6adc5455d5e5a216d1ba6920af2e895ed91d998061ab85bfc7973f34dce5e0cf8b19053b30e7cfc97080a9f9c2bf4478c81a30cd40511c87d2dc063e73ab005b6f4371e2d7d6e8dfe90ee9084910f354794774e4f7616a30bde90159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369992a551249f91baf8d5012d5371d74ccdeba1692d7e3dfda33641581cf5818e39efe4b0773fea42234582c8fe3340e362e9f30b2e6a890d40d11bc1d091a28659347f78ad3c0ee868b62d45892e95fd93a726220191d938f31cf331dd14966503", + "parts": [ + { + "index": 0, + "bytes": "08c7f3a0aa22b93c81ec9e9661b9b6cb56a9e6051b19781eb728608aaf80b314627da4d31826c82e9e6154b473272c4f" + }, + { + "index": 1, + "bytes": "80ee94ef03d0d32deaefa9a729df734a337d126b7ca5c3c854d670dd9a77b388ecfd0872110100ad55babb0e2bd77a9fbd697a8f54496177734c39e0498978c7ed470a28d784efc1574ad7d581f431370c1d6f05f5" + }, + { + "index": 2, + "bytes": "f8a268811e6966319b9379144945f0312217a45be02cfd749e3387a98fbfa8c173ea977275fc16ae1f24505e9722c0f76e72de988dd0fc25ca99" + }, + { + "index": 3, + "bytes": "b7a45915476847bd6e94bc73cb3574cf614b690ae12db34394044ab213a598d64447cb4667856baf26de2550a310bd322b87d7d643376ef5ea71f20b4e575896029a7afe2a7abc3c7d1356cbddcbb9aaae254a8a446184e4d6cac807866ec2" + }, + { + "index": 4, + "bytes": "87ac532aaa2ab35df2db1c53e63065061f7d60136906d6fe20d5c7d7917ab30206f085838ceabf5e51e3fca1e512eab5335008ec6cd45b42241bde550b72658599ea0de0" + }, + { + "index": 5, + "bytes": "a363c683e06cadd614bc3bd755c6d1e02198b349a10c5523a2b991938134f7af852a513f435fb6cd437d016ac91c084fc77fd5e9d57149030379d6664b05374d57185049e78213721638a15cb40a770af5c725b4aad44d71bb658e7138379daf476cdec5ee69fe520b" + }, + { + "index": 6, + "bytes": "a78228e73d5c979bb13495f04d00411e136dded0552b6c81984aa2a15bb3c9407a13fefc3ee871d81e04a6c7f07a674b1ffdcdd0a56c2c25511a5cabaa9c9ffb8aabd5e44b5f93b405fc63e73b3c" + }, + { + "index": 7, + "bytes": "aa8fac814218b8a4a7056b1f626eb7c61a922f2e3d621d961296ca70af2880ce672e012584cb5200f9dd88b499b070d5e84962" + }, + { + "index": 8, + "bytes": "ec5a2e4eef1711f30c0a28e1f6605b1c2b8c97970ec933cad76f22542b56df865e80c659c2e256a3049a62df6371edfe6e5e6dfaef954af033ed8a5b8133d78bd393333fe0cb9c163a8b13071fa48253daee242d65f55408" + }, + { + "index": 9, + "bytes": "f7fb91852cc21ae0a4343159dda5aee8e38f7f374ed1ccae52b028d8db0b40084fd63edfedbcb33d1d2a670695449466cb443e58c1c1a6253eb6ea150a" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000370426a07743076057cf1c8c906815e2183da6b2633cf69873436eb41d2307434445d720cbe4b9bb72fece14cb9e2af4fa2e9e2aaa596a087aebe33ba72cc60a534fcb2c6c54ae9066437d3c397d13f02b93b6198eb7e888a6eba4864889cc2a1f02", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000e7ba02b937a3bb9fc54a39b3ad30dee41b977b1b95deafe130c7253e971e0e0c80faf8d9e95d0600040a00000000000000370426a07743076057cf1c8c906815e2183da6b2633cf69873436eb41d2307434445f17c43a6092f2feb9c8f07734a57ed6f9c12f2ae7bb7898a63d655c7d1af67fa0bf4c9cb1cdb450f58ec29e27c667fbf10d11797330c530c06b30433a71e5108" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000076edd61f5ff580ef052f339b802a6e839504ea9d8c0854f238d1018a9b991633fe673c6349febeca4bc02af85f6d25b0f5107986bcdd5107202d6b3dbb72d8adfb946a9bc4c4bc051c024f53c85f1a05" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "manifest_invalid", + "at": [ + "manifest" + ] + }, + { + "name": "manifest_mismatch", + "about": "a manifest that leaves out commitment 2, which the room holds (§9.2 step 5)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000f9d0369b39b17ab6951600d19b4a0aec62424c6a5e709d63cc35151966d0c788000efad5feffffff0059776d51f0c15d8992cf3c5b26600a6693c4374b6c4a9cd7abf1903c1d3312caa2b37667586af0698a4796e6b849a3b15ea34261ab3096aad77725dd204ce608", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000007cd087b45a36ced182ee77ffd5eae770045a396ac270ca7e35f6bed88ae61474602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000027cd087b45a36ced182ee77ffd5eae770045a396ac270ca7e35f6bed88ae6147402000000000000000400000000000000c9fde0c2d6aa0e050e2ada5a2f547368c519b4b6a95d39c3ae224dd17f1627e4000efad5feffffff01ff0ae6dd0b124919e7ce1e7cae9a5075a1d04a81a35fc81d6c35d6b117538e95444b2d37f7e9518000d3d86e6d5525eac6b4abef09df568c0f62bff9ea1dd3237ac3590b81fff87694b1cb66c67e8ef6b90b0e00cccf6ed15ee1734dda377f02", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000c64f00776ff116232c774618f9fa2176ae110d3c7257c8d87ceb7dd33ceeacbce0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002c64f00776ff116232c774618f9fa2176ae110d3c7257c8d87ceb7dd33ceeacbc04000000000000000600000000000000b6f0350ed3b5807689cfa7f22d75e49240848c20286bf9d48cc75a7c576acd80000efad5feffffff0171707ac5106dd9bc014b163a3df5eacf0f7a960ce5dbd54688a18611feb04192dba5f5812f075310658daa6003e3a77643acc768415ed3067097692329b27d9972d123584b9fe8ea5629b4519e7c76672d7893092b4ba9e4c858b8080425d300", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000234e0df91d0df8f120af88c176a65f4623b9416d12bd009ea51e74c72a23a86c6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002234e0df91d0df8f120af88c176a65f4623b9416d12bd009ea51e74c72a23a86c060000000000000008000000000000006509b90f42bfd8fa84cede647b4dd852bcd8e280424fbf88eba8dc6a2d29ab6b000efad5feffffff0371707ac5106dd9bc014b163a3df5eacf0f7a960ce5dbd54688a18611feb04192171e86b51b24af5010bccbbd875d920830bf9f2ad8b992bda0e122a52b054667c9fde0c2d6aa0e050e2ada5a2f547368c519b4b6a95d39c3ae224dd17f1627e42688b868f47e8e51ec2dbde0b7fd8fd7dac2de4d03710fb92261de6e1381f6e7a90f2fa1367d91f82c3289468f93f833bcd829791d583cb2147b2479f9000803", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000010bc6f152910413d883886cf20121aeff32b6ac32e74804f050c610dd39fb7f6803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000310bc6f152910413d883886cf20121aeff32b6ac32e74804f050c610dd39fb7f608000000000000000a00000000000000860f9b1ac8918013cda347e908a71790adc2db6925a1dfa428ca63296079d400000efad5feffffff01e6016880fe2143ea461159ac131e22dbd965117f32ff106fc054167199075f28a0b568add1060bccfd45dc660d369f822ec88a3e9266c81249166af8ac8c901a1314d4ae1cd9c5bf3c920383b0ce9f1d7b497aa0b05e77141b5c40bfb9d89306" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000788e4515e9a236ed7fbe6fea69c991c2865d97a18ecedb72619530b66eccc8e90100000000000000c0c1702a010000000004802a0100000055000000000000009886711d4c26f98ccc0fddc5aa13838ebc896207a677e4563a8cf5943eff65c602000000000000000004802a0100000040468f2a010000003a0000000000000068b89c572f4589c8a3d16b264be451d86bc104f3d05f17c5d74b71180404e16b030000000000000040468f2a0100000080889e2a010000005f00000000000000e94a50bd4948289935fe52381bc5b28c463b65db5802b29c0973ad3b866acf22040000000000000080889e2a01000000c0caad2a0100000044000000000000005dbef2ba2a731c00d2be59fa9c774324126c57904ecf5e007e28db88a82d56a40500000000000000c0caad2a01000000000dbd2a010000006900000000000000ef2ae4b0044655a1f06bdf1646e14e1bef790940d01b163e434340a2638386ec0600000000000000000dbd2a01000000404fcc2a010000004e000000000000007e2c0f539df949a4fc970f25e230e177f2d52eb9e8e7c584fac4550f1cb166dc0700000000000000404fcc2a010000008091db2a0100000033000000000000003058e5dc65390c5781ae1521e2dfb19cc60992a317e639e925f80c104e3b669208000000000000008091db2a01000000c0d3ea2a010000005800000000000000fb1c1f48bd8c8dc8cd08e3b964d987b53095b0cd48805f257c7b6fc8febba7e20900000000000000c0d3ea2a010000000016fa2a010000003d000000000000005b1416932da7e0495c26cf75decc0b87ada09a37c265d6e4542f935812759cab860f9b1ac8918013cda347e908a71790adc2db6925a1dfa428ca63296079d40005000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e67cd087b45a36ced182ee77ffd5eae770045a396ac270ca7e35f6bed88ae61474234e0df91d0df8f120af88c176a65f4623b9416d12bd009ea51e74c72a23a86c10bc6f152910413d883886cf20121aeff32b6ac32e74804f050c610dd39fb7f6e2ddf5b8aa53f88aa3ca89e63029e52862b0ec931d7c0603744bd48d349b0d240159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369963549bdf974bf510a8ba1843df33534dd9eb67fd2028e3234e511aac3407fbf868b07d47ec5ddd726876dea3257f38206d5061d9d9a6439793144cc64cdd14fa59b5ab984dc9538dd332bc81063d38afd47cd4dabdee389cbf46e3ef42b92b00", + "parts": [ + { + "index": 0, + "bytes": "f9a890cecab2859aa0c6a9a913be41724c7635e6c6f4bd2a5caa06c6263b9031f69584a7dc687ba6d58271fb40805bf5" + }, + { + "index": 1, + "bytes": "40138b4c29abe464bbffabb243abd2e599309e2c686bf85cc2f9874d86f47d25871217e92471dee5ed09fc4abd907bfcb05914074093383c7e9f50c27caadf82cfbd76d230ed1faec0a11e8a7c766e3ebeb613f45a" + }, + { + "index": 2, + "bytes": "7e7d6265f106482653684e592c8d7f9eec4d0cd0723343821b30dd9a1d80867b6d319a4af7d692c479ecc58d82bbd435b34487eade759fff796f" + }, + { + "index": 3, + "bytes": "62d8abae51e24691a4b2a6aefb10cf5e0d37528771c2f7c403b99721210153b487592d40bd868af33592e3887a19d5c9f7dd30f570f459d65bb7527b395577ec07d22a59df50082da1dbd3b9420d6f036eb80a57182c41579b8e7cdcc2bf7a" + }, + { + "index": 4, + "bytes": "a6cca447fad71a86d369b9d95dab0dd64793f4ae60bf8c4baa506e3b3889d9bb0783697bdd65c6ebf3a934aebfc9397eeeea06f0185cb9983d9cdfcdbd400fbf5492b762" + }, + { + "index": 5, + "bytes": "193e0f7cc099d832290480f519dce1f194e0cc26c61976ce97af8c990ffa4842c51644b43d25c3c7696b946d78efd735c61d5531998e766ddb1175b373437e9edddc3771036293e0c85c3228651c2a7da6099a9b5041c3ebaf44a9ca678b27c7b6df372aac379bbffd" + }, + { + "index": 6, + "bytes": "29919d23e75ea88635cdec5b426cd551fa1c1dd342790f5233595227ec11a4d1833026c5b153a0d96093d6096a6c7d926c67a52dd81d9fa4d7f3c996c3a4746e8038d42f4f449daff86289988ea7" + }, + { + "index": 7, + "bytes": "1e731bb52082a4d003051e27d4a9b1cdba4d013491899a94389babfb08903462a47fb4ed6745248658c77823070007e2bb6658" + }, + { + "index": 8, + "bytes": "cf6954d70cd66ea84ecc92b3a2decb299560210dd292af444c9b30cf4481d36535639cec3a283a96983e7453a4c5aecf56274ab84ef372292b1d6b4597c9620b2e2e1be23e5840a40750a3a11e916319f9bca5402b6dc51f" + }, + { + "index": 9, + "bytes": "31064e82fce1a023df32dfda1613b555c787f5220d8dcda874036b22c3ea5c793403431e8a8f0b1d19e9915c9ca09d25d61d126b05df6dfa7da695d713" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000860f9b1ac8918013cda347e908a71790adc2db6925a1dfa428ca63296079d40044459b485c4585306f1fa2e27b1035c9cd676eba38e1d3771cb4c46c4e59f09903803815e39784e4c726f3beed50beef1220b17ccbc57a6c031b9d89cf6e2c1b6e06", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000ae9e0c387fd0fe3e9ef11d06d6094b70bda2b7725bea26dcff07180c5c43929880faf8d9e95d0600040a00000000000000860f9b1ac8918013cda347e908a71790adc2db6925a1dfa428ca63296079d40044455abeb2387c3143553acf9391eceb860a7d09edafaffa9c66c8bcd876620998d81eeae981d9d3e274df3694a397028655f5fcc08f6e8d8dc9dfffc71949581e0a" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000363d9c6ecf74d7b402e9951081387293d074ee1ac3e4d5af986864e1112a72c258c0eb462f40ed3a7d1a90d8504f18c8d497574d8b986356eca5d1ee3c1479f36739a95503ac220e4de4267348546e08" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "manifest_mismatch", + "at": [ + "manifest" + ] + }, + { + "name": "manifest_bad_signature", + "about": "one bit of the manifest's signature flipped (§7.1)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000e51bda1d71fd55cb4b78ecf0fdbd3822435d4f4ad5257efc02bc3caaed60404f000efad5feffffff0000136ec522aafc69d5162f0027849a7c6d2d4ac991ea3197cc76eb615d76cb96d0ef12c1da5053e78d0c793da6f81f5b138e90007eb3b93c2b3f87283923c901", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000053b2d3bc56622a4a9f35df2d14a7f12a7209670aec895bf493cef1544c16ae46602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000253b2d3bc56622a4a9f35df2d14a7f12a7209670aec895bf493cef1544c16ae46020000000000000004000000000000004fe92fce9f8937b66399ae26264d93e31190764ab4b32a0e40e141e9eacba78e000efad5feffffff01188c9276668468e53c72787d17430cd30bd87b2c7f0c540cbfa2cc6e0b4e3982a78c95d417e70f43d806381bfb6308ad2bcef1129d6261024170acb8c801ba4d5c5be6bc802d8c4682101e20a733bd869096d02b48ac7b5b6eafdd7ba8f4ba05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000008db8694b8501ce51ee5b489e01255b6446cf6f9c7e64304e5e284ff092ae1a7ee0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000028db8694b8501ce51ee5b489e01255b6446cf6f9c7e64304e5e284ff092ae1a7e040000000000000006000000000000002894a80d3402edbf056721b69989f91aed750b928100af410ddc978c1f133aee000efad5feffffff01ed33ca3ac4f37e0840785d8a8a5f6894cf7043b3c7fc2a4ad287c217d9d381d2b874213c5510fe8079f01e38716ac12bba379dc5389a3de01dc686f9185e37447c890f99d048566569e5a9db025ba26a718cb230ae05f271840c038d9042520e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000015afde381404681ac5c69f27d4dcd1ce5522a54eb6d78a213540fd649c38725a6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000215afde381404681ac5c69f27d4dcd1ce5522a54eb6d78a213540fd649c38725a060000000000000008000000000000003d6a1043de14bccec4c032d04a44989b6fb742d8c07868a60ba1f95ae8442eb4000efad5feffffff03ed33ca3ac4f37e0840785d8a8a5f6894cf7043b3c7fc2a4ad287c217d9d381d2b4c93833a4218b8a5b6a0160610f823c67db51226453feded493e12ffcec01d54fe92fce9f8937b66399ae26264d93e31190764ab4b32a0e40e141e9eacba78ec48c4e689c2d2f3ef68004bce2b8f71c14ceb03a72ee2ceb189b7238d1b5cf9213164c25f9e42c5ecbfe0dcaa846c247adbeee08979d6f5adf11b116d49f020b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008211b34d643298a0e7f2a17d8f376afd40eae3d3ea300dc9dcafaae2cbd43bd5803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038211b34d643298a0e7f2a17d8f376afd40eae3d3ea300dc9dcafaae2cbd43bd508000000000000000a000000000000007f6f68014c7190467741e39239fde6b2e841210419c08a06a9c58f63aa6a6482000efad5feffffff013175504c42637c5435264324f913d7c534df6e275b84ed16911121858bcefcba31d3f7819db67f7c549d6a4a3e73efb1c5df5518e233d0e5b289a2b6bb5621e19ee3993dd0710cd1b6dd70d5c3a036302e9be13d7a1a85605cc3e42ce85ea10a" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000cd7e4599d386380133814e0576c78bd549657861404495257602fefd6d5811b70100000000000000c0c1702a010000000004802a010000005500000000000000413fd9788f40e042b37733f87a6474a8fa0acda5dd64d4d797223451687b512c02000000000000000004802a0100000040468f2a010000003a00000000000000e0e866e6c56a7d87505b41db9c90e6ffb1f1a93d6ac63f18367855cb072edb86030000000000000040468f2a0100000080889e2a010000005f000000000000002688af591f1da21b152dc1c5d9b464ea9b4691ee2932effab7dc886c24dd0ce3040000000000000080889e2a01000000c0caad2a010000004400000000000000f13c2aa9f1e992124c386039a33db6e8736d13a134a55f2abe18e089a600495a0500000000000000c0caad2a01000000000dbd2a010000006900000000000000a99c8fce745d710e37f266ffc4751cca5c4f2a68f4b636e252a2a9ba526d621c0600000000000000000dbd2a01000000404fcc2a010000004e0000000000000058351c1d945adc10edde514c1eb3e75e7b8633969773a99ca1d10cfbef82890d0700000000000000404fcc2a010000008091db2a0100000033000000000000006d842456ddffd33d14d30a7b286a938c59768659a372dd5fca91cfd60292b6be08000000000000008091db2a01000000c0d3ea2a0100000058000000000000002b2ff6f0a326b1a650fb7f6ec3e6dad2b2cf704bba493731c1b8a28e425f30b00900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000078cbe8d2b4f4cee00f345a72a947e4d38c76a8ae97e59fdc99c18d0ce5bffda17f6f68014c7190467741e39239fde6b2e841210419c08a06a9c58f63aa6a648206000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e653b2d3bc56622a4a9f35df2d14a7f12a7209670aec895bf493cef1544c16ae468db8694b8501ce51ee5b489e01255b6446cf6f9c7e64304e5e284ff092ae1a7e15afde381404681ac5c69f27d4dcd1ce5522a54eb6d78a213540fd649c38725a8211b34d643298a0e7f2a17d8f376afd40eae3d3ea300dc9dcafaae2cbd43bd58580e4ad5f90d749f1e2dbef0a46470f70e997e86168f8750058ce8842bd8ff70159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699c3372dfcfe937f53c6f9aa588b7a022b5b2276e658bde5aaf3f32626093e9e17c34101d91c945e35a8093aaf59a87869ab76177280a0253441ed77206d606cb4cf42b96ff24abee1b5f6d5b9b54f87eeda44f2bd91162e41963ce9a33096cd01", + "parts": [ + { + "index": 0, + "bytes": "27d6cad21565a6c96e2a5c41929c487e5d4abe48982ecf5f6c3e99efc4c34d634598c43afad0bda5d7c55866c6f15845" + }, + { + "index": 1, + "bytes": "2eb473e461c343cadcb4f2be1a00389b32a5cc3fe7190689f549cde5732f741bd7d4f58083f7c618542b4dd7ac69bd8e02c8c3111a6c6e7606f93cf23496e129a5b6d0677654ffc671f78c936368983c88feedf1cf" + }, + { + "index": 2, + "bytes": "4def53bf264941b0084aa87c7b2ad958e52d20aa833e3cb0a17bdebbb281ca51c0e7d03feb096a073a72e20cea117c05e72b710dc9f4b67b2ddd" + }, + { + "index": 3, + "bytes": "489fbdf4ae9080cef96e2ad50631ddb70ebbd77ce649d80d61ac8e41821b13299558e8986997b79869aa22b992ec7685c9b52ee7de4ee0fdd51ae3677dd982371bc18e9f453ce2d47c21a1e2249b1d51bea109d5e4a9b797b95b2a7fc44bc9" + }, + { + "index": 4, + "bytes": "573b54b4e58f692206a80977a8e3a24ec09fd9e6bed365833bfa46aea5416a27254dddc8e791d41fb4b76ffd27b9b4250626d718e0278bf240646b37cbe80ff78db4eb21" + }, + { + "index": 5, + "bytes": "282f54f3e969293272ec0002219450ae1fb2b9b6ead80e04de1173df6937c0e21ac5154a1d23cdf67cd4175e948c3e749db5c40c4395d24e532ebb6b75acc1d590feebe29fdfcfb2a2421b0beae0a73adf0bfb9c2b4bc09cdeacf9f693f0c4f8e5dd475e3de251f184" + }, + { + "index": 6, + "bytes": "78a88a2f4b6ddd213ac89854eba47987fa7d68329a6c4a23881040e138f46b1bcb408ed33f0c7078ac3682d36d5b2f81f270b9df5d1023ea6e3506287ff568f0f3e3f3604d1d3126504571fa9c83" + }, + { + "index": 7, + "bytes": "945c707c569447426db31184e6e004b9fc7fd9d723ccf8d3d5d2764d3d6307f6bf5cc5d90c34e03bfca2e5c8041152a342562e" + }, + { + "index": 8, + "bytes": "987abab9653911d681696687a774e6dd41b82d1a11117a5376f77d5c945879b1e5a0114b1c312afc3d27362ece08102a97d83f485165a747256c7b45a578e9e97ae0025d9b61f19b2198b36ee24cbf3d7adf197f4110c770" + }, + { + "index": 9, + "bytes": "9e0cc353a40da49d0b18b38860ad46678490516fdff8126232f2d0edde8c94f0a53913384ffce98b811558174f212daf78f93e159a92a93872f85680ef" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000007f6f68014c7190467741e39239fde6b2e841210419c08a06a9c58f63aa6a64824445385a85f938f11e40f0a4246a6372234c704c084cec4f2dea0ae298d23758b00ba6223e72ca94a9503ed3fcafb296478b56751e7ac5c43f3e77b5450f6190c50a", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000000000021fb6e3f86c93122bd9ca4bc19ac200cd3cafb3f350a8a3b8df091619ac9941c80faf8d9e95d0600040a000000000000007f6f68014c7190467741e39239fde6b2e841210419c08a06a9c58f63aa6a64824445b14a760577a3efa57116fca5713d724967fd5f14f402e5663287e077449f3eda5dd3296326ae35cec38f56f49a65e36b41ccff904f7e3813864565d803bc5b0a" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000000da5d4f8bbcf4d314b5c9aa24fb0b806d67de5be76be1093f72c04c44b433ea23c5b5ba2338ef9a89cda4fa36dc9b90561c442849c3ea19d78e85063998129f07cc630d815eab09126c11d7a2921ea0e" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "manifest" + ] + }, + { + "name": "manifest_wrong_room", + "about": "a manifest of another room, its take id that room's (§7.2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000071baf2f146711fc0e3828846a63a711307b98ace7cfc99a547a6128686f9e08d000efad5feffffff00cd418255786a07c682c6c72c1a369aa7f27a5a5bdb124fff43bbe868075c41c276773d782e8da27a2d60f8b6e290d13b1f5e44b65464de08c44444c5033aa80b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000003d1ac72a6b5c1705c2d8ceb30d28d51b6ddbf3fae2295115dd29b8cbe7730184602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000023d1ac72a6b5c1705c2d8ceb30d28d51b6ddbf3fae2295115dd29b8cbe773018402000000000000000400000000000000eb01c32a1b8f299fd1e10c91ac7e497cba4544284c406d05cbd6dabb7603e8fa000efad5feffffff013b86df7f825b9b1ced1801795fd53f2e381a4b8d3b210599a3d1e0664e7b2ee5a5a58ea7f632b76eec08e35339bb956e51ebe4a2fb83b1c5963ba31d3da6d103a884b3d15b1aefb5ebc2407bcc6e8cbb149736bcc78d0766b3e45c2fbdb83b09", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000007ef65263f6460516e560b31d5a8141ae8826d4f5837b6dab8f544463efc057cfe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000027ef65263f6460516e560b31d5a8141ae8826d4f5837b6dab8f544463efc057cf04000000000000000600000000000000d0b00ff04827087b3566e7f6b0646c6d2d5d17d3db0757c410a9d7ffd1e04f73000efad5feffffff0120997d9d6f48a1be7a5b59ac52d2f013745ef3c402203ef5af44a8ac519805b7a84337e7135368ccb9c1ef4f15d41ff9ecb1d9be6751512261d5dc0c64e45b40e2d7f3256f1fe9240cf581d21cc2c514ade4a3da8bf4dea9be14adbe1c04130d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000455bf9f0ea7923db293f01d8d4fb0629cb883ce4e08d0cbf64bbeb8ea8de5a256033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002455bf9f0ea7923db293f01d8d4fb0629cb883ce4e08d0cbf64bbeb8ea8de5a250600000000000000080000000000000043de2d9c087064c5120404fec1200e512792dd543a77a4f1383cf532028e7fca000efad5feffffff0320997d9d6f48a1be7a5b59ac52d2f013745ef3c402203ef5af44a8ac519805b76db875156cb7c42aff904da75e4d4f54bd23a3088d1e5cadf3a88b70fdead4e2eb01c32a1b8f299fd1e10c91ac7e497cba4544284c406d05cbd6dabb7603e8fa50f0a105473bb2f4b6caf84f7dc17b1b5eca6d2638d5bdf49b999e01a2f2e7d4c1b741e362d4d4bf7d75c0fa4b80e4f7e0ee67182fa344859778052eec566706", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000006402141914d1a9c4763e54707a66ec3de8b6eaf56c480df71cb526c9f44b6cf9803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000036402141914d1a9c4763e54707a66ec3de8b6eaf56c480df71cb526c9f44b6cf908000000000000000a000000000000000f7e191b0798bc8fb3ab5c859c69ffaba7ab2534967663b187ede18bd94d2dc2000efad5feffffff016b87ae6af0b75f75e8f419ba94fc0bd29292e58ec035796fba75851777d6e579e7393038e42190c9e0d743e35cfaec4f8898e12ab9ca72a4123a19cc3f2c0ff36d7382fd656da29395f772e84749dbf59e24a2947bef0b0064a991e7e3b12807" + ] + ], + "manifest": "57544d31014bc3fbe5175eb47cd486a59e4857affc0601be20f1bc2e76aa28940717b33c14e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd908225c5c70faf0fed5fc6b89611b7df973b50df3d93545cdf96dcd42f1c7ee50f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000bbda49dc832b282d6140cfbe1e6f5cef6263b3b534489ea6387e1c208f31fc1b0100000000000000c0c1702a010000000004802a0100000055000000000000003dd9f96faf36299339742e7207af15e29eff8adcfd641f785a5e04ea74c0af0002000000000000000004802a0100000040468f2a010000003a00000000000000d2b4607a659a707c6763deb0d797524c9423f36aa02878f34103318cb1b67e3e030000000000000040468f2a0100000080889e2a010000005f00000000000000c448d47ad6a3e55c973d16956a9e4c21e49083ed45e8ca9e164e3446c0707178040000000000000080889e2a01000000c0caad2a010000004400000000000000833acc628434c2755bca47520af70f33609932b6435df867617852cfb546a2be0500000000000000c0caad2a01000000000dbd2a01000000690000000000000017afbd652947039df5f48b97babf1e78ee8b35e28f8a95c79b5cec89885622760600000000000000000dbd2a01000000404fcc2a010000004e00000000000000d8ffb1d53e7f9e3093c0c3f867789ce1fc13fcf537d131d2c9d9c77fb2524cad0700000000000000404fcc2a010000008091db2a01000000330000000000000056a03ca2af7abb72eeaf12872b1c35e104f19c5d259627a45bbade950c2e1ff208000000000000008091db2a01000000c0d3ea2a010000005800000000000000b3b901f87e7797c8173e525b95a2c90f6db813872ac1acc2494fab9f39208dba0900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000077bc16e51771240ea20fbd1bff8ecedd937c17b4120c6b0833d670429f3c297d0f7e191b0798bc8fb3ab5c859c69ffaba7ab2534967663b187ede18bd94d2dc206000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e63d1ac72a6b5c1705c2d8ceb30d28d51b6ddbf3fae2295115dd29b8cbe77301847ef65263f6460516e560b31d5a8141ae8826d4f5837b6dab8f544463efc057cf455bf9f0ea7923db293f01d8d4fb0629cb883ce4e08d0cbf64bbeb8ea8de5a256402141914d1a9c4763e54707a66ec3de8b6eaf56c480df71cb526c9f44b6cf9bfdf5f40a58a5370e58a16edcaa67aa49d6fd09444b744d5f642c7947758e5670159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369979152d93bc81168032c1266d5329362d1410dd5aec7f535ea19aeefb61733b44711b57606ef442917f0befe7f669c187a4f0ff9e2362d8871858ba7fc1d8642266cbfe02160a7f6558a305b19a4d0c31e3a630eb86bd0f871df5e9ae1c5dae0b", + "parts": [ + { + "index": 0, + "bytes": "0b320886b437359a3173d1c05f0a05a9e8ad87debfc2eb934274e3324643bb5b29399d16ecd057d50a5670beb413afea" + }, + { + "index": 1, + "bytes": "2ed4bf55c925cbde6b07d12515949093f36a0a321e8d740211bac90ba2f10aa8a8a1d116e76011d4716d96fb7c25f23e0e723db6754a51d54afad685d156f8a514e19caa0d9519ea9ac6357b8812b37b96974cc287" + }, + { + "index": 2, + "bytes": "ab9eb9b03f49260125430edd9b4abfbb67431246948c95850434e398268ef01206aad991ba4ab886f79f671745086e18e99968c49f7aae5a3ca1" + }, + { + "index": 3, + "bytes": "e610e4313d5cb842d42d068d66173291bb9c05a3fc975a94ef6e121ba3fc29419c255dc9af78c6ad72a22c0e7c6a52888cd7667543bdaa28df409fe66e8313a9e6543ca7a9674ebc9dbe7c3ed606f2c98f2e6802c36855e7530c560ac620d9" + }, + { + "index": 4, + "bytes": "cee869e98f195a62b4670ca944d67590b91c3b5d6730eeb93411059903d3a0e5d8fd09a7a6a4fd7c2c54a614cc8109fac1d4f5b782a3b281b9e291d60d357f2bdf9d486a" + }, + { + "index": 5, + "bytes": "c1f9424ee191a681be9667815af34c11f7fb310ec4804ef610bcd1a7e74cf5bd468ea3cea9336b183503d15a71c3ce305a88ae5a21090fbedad2b2984a03cc2b078687654938087c4bc4751d2d1f03675b76e4882eedc91d1df2eda5fa144b51eb5a18ed2badf4c604" + }, + { + "index": 6, + "bytes": "89c526e1886d5b4f87b372a5e2798c6fe285c2b72699f9d6066b2b4f6cc4a3160c0fca482bd533f58c3501c9fb7f86065fe65477dce989566ba0954118e42d9a350cf0512405e8263d55b3745127" + }, + { + "index": 7, + "bytes": "f89939c3b5f137383bf0eb3350409a3b1546f30a1c15794fe711fd9cde7abca000432991fa84a19b078bfef095adfe8611ed2d" + }, + { + "index": 8, + "bytes": "56daed1279b182aa8064babe1caf256e3957b1b54dfdb218d1c025afd172479707535645aa2d9e878087c9c14c942d45e557cacb647c845dcf2ae1fbcd9e2df8c6f9e69ca7e4f2b0e0f1b9e9496dd2151b409ef268e5d3bc" + }, + { + "index": 9, + "bytes": "4d7821a4bb0d3e83fdb07747d2303477fa916af9083c82bb52cf4997c9b86de4093b81a4de27617061df11b8ab0820317c42ee9129bd20ce7a948ddb02" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000000f7e191b0798bc8fb3ab5c859c69ffaba7ab2534967663b187ede18bd94d2dc24445b86fca9dae1ad93b3f2fb4ec4a1bf23529022ca9ff925c95e7e4d640287a3a12f5a9404e657d47a33774d504d6f2b10f10a24a053aaba48e99f6fd2b9c2dbf0a", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000006ff3f9d0297d74fda4a6ea026f0da41bc9863df23b9fdba25146a0963d32d16a80faf8d9e95d0600040a000000000000000f7e191b0798bc8fb3ab5c859c69ffaba7ab2534967663b187ede18bd94d2dc244458228a0a4fbe328bd913e3c88b1842148ec8e53e63d64bed1a60c2f3070d7a9168b46b98e035ad63348d7b5a9b82e7bd0c78d94e24be0fee522d4c366ea2d6705" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000d527b5959496212ad43e7cc13e9966e28ca5d5288780f2f4f901cffb0a61f3d1f28f6a33d5d6b9402f63c4c8dc042362ce256cc1d078a4609481e179ae034d4803346a22095dd07964465b76171b0a01" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "wrong_room", + "at": [ + "manifest" + ] + }, + { + "name": "store_not_listed", + "about": "a store the key log's head does not list with capture/store (§6.4)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"bfed77503dbc293582ea10048873bd36a06974ac87d418f14dd1822d68a24527041dc29d5acd3aa3cf70884ece124a120ce98ab9094f11bf487079ad00f47d07\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000021f8c52d64364f3d29ed66fa99c4ae3a07c65e3522e4065c7f187e167c5ff510000efad5feffffff00eb71671538c08b324dc0e914f09681c9aee4b3d8877999985e74940bee3a95085c9c521ac9ca2600bbaeb3e7d0428ba208142a8addaff1f86c8a28d22f741f03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000003e51b1dfe8854ce545aa64103deb51ca47bc6a7cd86cb169a25efa14ff0a4c9e602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000023e51b1dfe8854ce545aa64103deb51ca47bc6a7cd86cb169a25efa14ff0a4c9e0200000000000000040000000000000087496cd4165052a14fab3e7389f0cd87c81ba9e7714efefa8b7744b04a06ea79000efad5feffffff017e270e163e9ae479cadb5ff1e293c4e605351397b59207ff1892c915b5f1189ea3322852aaf0659f17ef681e109faeeeca341e5782316e21f7905f5906c78333890fc40da46cb7871c19bdaaea998b41adf4426024d49678863d4b00231ac102", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000816ab351cef362740418e4d3b0d786c07340e765d897139271b538d7eb5dd789e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002816ab351cef362740418e4d3b0d786c07340e765d897139271b538d7eb5dd789040000000000000006000000000000002628f047b84788595008dffb602d439e312835637f3eeeaf72b590540835cd68000efad5feffffff01146a1604baa41b137a17aa18108914633b91a1ea4e9f4a56e400b1cd76964e1b1c2f9d800bef7e1ddf9dcd8dd8de9ab998fd73ff8b5fa56f2611a95ebb4a0daacb84ad54fc2f1eaedbe76274bab5cbd108ea0d09de888d297188a43f5e3f8701", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000006de7e210c3c1c5271676756d2670b348b7d1b74ea37ee7eb8b971d803166c6646033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000026de7e210c3c1c5271676756d2670b348b7d1b74ea37ee7eb8b971d803166c664060000000000000008000000000000008d88895ce1a9d76bc6b69d787a3383cdbbfb0e888931fbc1130405ffa66d5047000efad5feffffff03146a1604baa41b137a17aa18108914633b91a1ea4e9f4a56e400b1cd76964e1bd46e1b823a2e13fc0e782a4f85c9fcbf473de9bcee83ccca640d0969260ea52487496cd4165052a14fab3e7389f0cd87c81ba9e7714efefa8b7744b04a06ea798e23950a7b75359edf432ef88b98d1e668be08caa4ead00a64b01d1b60c6beaeed49c0a09b4c624e53163f28e688e849f622b1841f6ff643d4293f90876f960f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000d064c67d006923670122e962fbfba6b7321cfef9d36d31a2d0e4a36d787f55ec803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003d064c67d006923670122e962fbfba6b7321cfef9d36d31a2d0e4a36d787f55ec08000000000000000a00000000000000febd1a7e5d479959d4d3e8cdbbcef67ff0035d10f6b9b8f76f8912afc31e8325000efad5feffffff018ff904dc764452dc8715c1c62091a90e70dd543fc42a5cf3bd53fed3c09488d52bf9f32d40c191d49f592e971ca08f3942f43cfd8618634a81f3cdd4f9664567c89eba2b53eb82e80719c53b16913503895553d94862f383fb5d887f1ad0d50d" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000002d9c9e4ce18f6d2d15d41631fb801f1c177755cf66fe390364200c5413901e230100000000000000c0c1702a010000000004802a010000005500000000000000b7810a8fd9e12760c1e7f023d637ac924ad9239dd569806c0e8266fdd097709302000000000000000004802a0100000040468f2a010000003a00000000000000702045fe57215ec4b9eba58a8e5bb48e61211c00d8919f481dda42cb362fb4d5030000000000000040468f2a0100000080889e2a010000005f00000000000000d3fa956c2205f4cd22a7a0cae69fcedeb2bee21b6d5d3e37b2ea0f1a7afee972040000000000000080889e2a01000000c0caad2a0100000044000000000000004eb09f255e5c07508bd41d3475192dc4f97ddbd3581ac9aa0f103e762899271a0500000000000000c0caad2a01000000000dbd2a010000006900000000000000738ef0b4058bff5d12a94b10c14b571fc5a927cc287978e6cabdd633abf439860600000000000000000dbd2a01000000404fcc2a010000004e000000000000003a877a0eabf0953967c0d54d561b06cd3896f433722310e8d3cd04bf7f4946b00700000000000000404fcc2a010000008091db2a0100000033000000000000000e078857c2bdca817863489923a7158c1dfdd473ae9843f8319f7bca37180abb08000000000000008091db2a01000000c0d3ea2a010000005800000000000000653f1517b49c5265787d45711c7b9f456063409c222fd3f80daac5138106eb680900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000bea7366d22ee6622ba11366d0354db34fb13520cb94a6cc9b232fdfdfcb2a7eafebd1a7e5d479959d4d3e8cdbbcef67ff0035d10f6b9b8f76f8912afc31e832506000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e63e51b1dfe8854ce545aa64103deb51ca47bc6a7cd86cb169a25efa14ff0a4c9e816ab351cef362740418e4d3b0d786c07340e765d897139271b538d7eb5dd7896de7e210c3c1c5271676756d2670b348b7d1b74ea37ee7eb8b971d803166c664d064c67d006923670122e962fbfba6b7321cfef9d36d31a2d0e4a36d787f55ec5b2703af7477b269803093863ade01dd7abfe75105def5346a713825b34c60110159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936997ecd86bff00e168767200fdcf4f488714515cecfef94023c2f24269758f8fd1edbb0dc24093239d79b0a78db19d81180a5a3d76c2aec4bf130a44644ab55d19d3315247887caca7d35e54317d9daef0ba86d6e6b73b1b90eece2c8761778b908", + "parts": [ + { + "index": 0, + "bytes": "f8aa5a5c4f700434c4e499c61bc826493bedc24673eed08fa470e6943a4778509a10694fc137ba46f2758b83478bc308" + }, + { + "index": 1, + "bytes": "2c54a9fa6e3d27f3233a9c2c81517a2373c672ad7ca352912b7e155c88fd5ce6046796a0664bd49b7630c04ebbd830adfdcad9db35fd78765350d87a210b7dbd7c2d6d390483ecb8ddb1fc17ea4a3b9ec6a444ff6c" + }, + { + "index": 2, + "bytes": "c5d56d54e8eb6ac9dd6a69d742ed120bacaf2ac82b38aac3f00da4a2988b2eff03ae66681f08f329104b493897ccde7ebbe05277861ee0c8b7f5" + }, + { + "index": 3, + "bytes": "a5bf5de65fb08ef8bd3caf56cb26320b11df9d374649834c5ea64ce3c237fd5e29540d2eb2bd24000d91852a8a420c161afd90698746a7970da72ed1d360a156f564196053afc40d331798d9183cbf50a2bd422a8c0b83373d3878679d5d5a" + }, + { + "index": 4, + "bytes": "1277abbfd0097f674694dd88d20c35af0e1aa0e34ee89a98a27972f50837042736d6217d260642a986f57f68610a29fb40ebdfdbffe90ef4c13d278c2aeb4bcfddc41cde" + }, + { + "index": 5, + "bytes": "457ecebf731f03ea89f5b49e455c44746e7f9f44677243da7fc5d3e283b33f8d723703432cbdb1d2eb31a9855d12ae495aafca42b173ec1f900f5d0a23acf0ead236eb03286d7b933b656df195c4b17fcd72a33f7e4d9cd8d0cca1f453f3628d001c481c91143f4b1f" + }, + { + "index": 6, + "bytes": "4f698001ee994712b66e5a23fd61eac2f56a69310fb4210fb6ee6d33d99aa00ebbe43431d056455aa453dd8440e1908a23b93c7af8f4261c5eaf36d6ef5f8d7def1d3b119362ff7ddd22be11264e" + }, + { + "index": 7, + "bytes": "a586f2231164a1c8598c9a36f3e7b0fff0d127de3b17f38ba6877972d0cf8ac221f5a183c993eaaf7c1d7c0ea206a7c3e5ae4a" + }, + { + "index": 8, + "bytes": "2c8740f27f43bee255256a8559fae31acfaea330f67c8f47433dc575c16083b430157f5c00ab52b597d86c8f27020544e6970d33ab4e49c3f56dc235338b0edaf40e3be6c5f4317e933b9e0e3947b81b0169a11f045f3f6b" + }, + { + "index": 9, + "bytes": "a9d0e80b73f1e0d9a9936320d7149af48af1747a344f7578c51f600769b22335b8d68652c38313176bb1fcbac072b7a3e17412e4600eaa0cd9699a86b5" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000febd1a7e5d479959d4d3e8cdbbcef67ff0035d10f6b9b8f76f8912afc31e83254445a2359ffa608988376c718ae6e4a6a3c3d20494c2f1b6024e08b4337c850d5e62bb719449717dcc3d49c6c055f40624cf54dfea490f2eb95590ebac30771ecc0e", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000006e33e48173fd8e076bf5343af73ff9a9864a18f74e362617b7e79785fd48b25580faf8d9e95d0600040a00000000000000febd1a7e5d479959d4d3e8cdbbcef67ff0035d10f6b9b8f76f8912afc31e832544457211ba8d1fd28982b2f6172dc2640c824ace0f7ceff78034a84a0aa9497523058649e5dff2f27684cd77b3aabaae2f2fd13d05397ce9cb5d882349c5819e720c" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000015ef405e5153564d278e50a5849d523b0ffdfaf07e04e8ed852d89d9903502ac290b0c0b372bcfe3ff94fa5d87ead2cb5dcc853f0c2c2bd0f72e915a79eb1393d73ed540fe183df59526bd744bbce607" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "store_not_listed", + "at": [ + "store" + ] + }, + { + "name": "upload_receipt_invalid", + "about": "receipt 1 states seq 2 (§6.3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000003f0d6138ef84ebf05b5cd99506700e9a716657292da089f85e586ceed7ab70b5000efad5feffffff00de8fc50f1e20b0fb3c9463c8795f6c7cfd218a9a9a942d7bee5fe48f31d31d0af3159929391f7e08ce779f675f615dff408d6dcbde9f85f2070ba0538c810609", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000005ff58cdc106df2d26e4d340b8ea2f75f8b56d6fadc8d1458547a78fd9be6a2ff602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000025ff58cdc106df2d26e4d340b8ea2f75f8b56d6fadc8d1458547a78fd9be6a2ff0200000000000000040000000000000061d7f4739d717f545edc736788949b1837a0397eec95b6a5405173793b253394000efad5feffffff0118f5e8cd6b284324f755ab38540c49c83dcf810bc2462153ee0b857d0d5337e6307a0b79e91379ad2a950aad70f36caa61d3db3f24af216ecf34dc73e5a07da34602f30fa0fd9f2332febb2019b83b84db9be396b0c3eb861467b4e283643209", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000eef07aefc1175c976be79041faa262483274b9e9bbf0a96c35bbdc59ef8d14aee0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002eef07aefc1175c976be79041faa262483274b9e9bbf0a96c35bbdc59ef8d14ae040000000000000006000000000000000384d93baddf3f9facf604f5ad17a4307ac7a181bd5f52143b30ac6729b1e16e000efad5feffffff013b84185a667e6a997312a8e3e9515fe944b5770bb7840e2c1aa3c15804857f70b0d57f205fec11f3f609092aae03820b6c8bcb9482160c22d9ddab2a401ef5cad43a4374a90c9f5236adf963426fff525e01a9d021cd375358ec38e352e6d409", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000078278c7702ddf873172e6a860592ecc02e84045e7c40d08cc039d98975c64a146033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000278278c7702ddf873172e6a860592ecc02e84045e7c40d08cc039d98975c64a1406000000000000000800000000000000f1d0329170f9984279fe8dbd78dc21c6cff34f3db95fcf0d6d7717ca9b54a2c3000efad5feffffff033b84185a667e6a997312a8e3e9515fe944b5770bb7840e2c1aa3c15804857f70df3de360821ca2a59a62e45fc5c9b7ddf4cfc613e21236783b0ae17c00bab06b61d7f4739d717f545edc736788949b1837a0397eec95b6a5405173793b2533940bb1d3ca87fa046839bd35cd308da431f5ec78a39bd1bc0eb1d7fc291b79a8e8688a5241983f843008c5d7dcc1cf969fc248c795b5d129b5bb5a300f3a70bd03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000035031cb6a62b905acc72581dc3b0cf2792854c5a2c674cabf7837c93b2b4826c803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000335031cb6a62b905acc72581dc3b0cf2792854c5a2c674cabf7837c93b2b4826c08000000000000000a0000000000000095de6484d5a626218fac030d238b078479b16e5a197447d4639cbad0999d11e1000efad5feffffff01f369e23ee1d55d05f8add239c28a0f340ce990134cbb21c68fb367952a5d7386c0072d4cd477f7ab8fd0e45b7df9dc2a6d353ba4c0403b652a0d4e5fd3210d0aef7c017a2d57d5215f07a7d0ce29f1f4bd3c5da35834adddc4d67c7c23e51c05" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000007374de6ab5bcc2b5f6e0fb7bc0777a5caa51e07c8471c1fb0dc7d9c3b728ad570100000000000000c0c1702a010000000004802a0100000055000000000000002f67bf0c481f7c503c67c2e2e22fbbc98279316c7d813e3b1092787d9b5edbcb02000000000000000004802a0100000040468f2a010000003a00000000000000db01f9a5162b2ed4e884a62fca7aca24976df2fdc1483008aeddfd9e3876a19d030000000000000040468f2a0100000080889e2a010000005f00000000000000bbb8cff5e53fb03553696dcc6c1843bdff627ecd31ab64180396049cb91f5521040000000000000080889e2a01000000c0caad2a010000004400000000000000db4428e83f3ca3bfc9c0d1bd14b05bd36c168afecdefbf6b9682086314274aa60500000000000000c0caad2a01000000000dbd2a01000000690000000000000064e4200d067b239ec1bfbd2399d1065ae201c902792f87909760b029be3a29710600000000000000000dbd2a01000000404fcc2a010000004e000000000000002189e2a931d7d52660344d7c1bda7e75abbdbead77aff5fc2f808a18b709166e0700000000000000404fcc2a010000008091db2a0100000033000000000000002d827ddadfb7cbe5f48c2bd41cbb2b8e6c9670aba707fecdec81677824969ee608000000000000008091db2a01000000c0d3ea2a010000005800000000000000e1ab79a7e8f7c3487423bc1152b5b8668fb079edd24a6b036e5c4b83ef0c67390900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000b0e0bff73f2a6dfdeae8bf4fddb6c4d7c2390a16b040795f8d8cb1824158bbb795de6484d5a626218fac030d238b078479b16e5a197447d4639cbad0999d11e106000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e65ff58cdc106df2d26e4d340b8ea2f75f8b56d6fadc8d1458547a78fd9be6a2ffeef07aefc1175c976be79041faa262483274b9e9bbf0a96c35bbdc59ef8d14ae78278c7702ddf873172e6a860592ecc02e84045e7c40d08cc039d98975c64a1435031cb6a62b905acc72581dc3b0cf2792854c5a2c674cabf7837c93b2b4826c8e4568f4c2fb3d5b2e5e5d473daf0868849b085c833b8b53263d6fbbc5cf4cc50159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699ded34d63883b750a9986206f91e932a5f9af8bd209971182802aa9e65774ada996811285cbc47492641574c1d1bc92fc135f1d460aa0559af64f25223bdde93da68aee170b8035303454b6f7bf36058a3fee2007906b12dc89056a7c243a7806", + "parts": [ + { + "index": 0, + "bytes": "e755eeae90ebbee8ba5b72e577fd443284fbe47a44ffe5a8baf8f96d48e62566aafe968da930e32742b364a69682fa8a" + }, + { + "index": 1, + "bytes": "bd9167087fce434e2a3fd71af25f1d3246208f739bdc77b2b6a43cab183cc8a009747caa4c19308e9dfc2a880cf7c52f6fbf1bded102337f6ac8b126a9c41eceea14b99ee9cfbcc758b51a9f495c2b8dda2116cf76" + }, + { + "index": 2, + "bytes": "a506126331dde74bea2ae7a6c6b201e8bd00efbbd4a053d75014249a8e38cb7f1d5ffb9793483dce8d8c59fcc8a2bf090f6003b4a0a45192f663" + }, + { + "index": 3, + "bytes": "998d1783604ff065c22402d0c4e993d3a83336b5eb07e323bc91d77b598febbbb5eaabcfc824ba69c2131ce795f68888011ecbfe26ab2501167d5914e4e52969f050abe8e2d0d62eac429537e80c7be7ee714be7e55eafc092113029ad02e8" + }, + { + "index": 4, + "bytes": "22d871d2ffbefe33eb1fdd2bc37301d43c0aa277c18ae86749e50cc0f348bec2f88e85e4380cb6ec8e29fd7c75b649e98602f3a8d8211d2ec16043ce8bd46fec1acf5179" + }, + { + "index": 5, + "bytes": "bda55c10605515325b7923dc05921ef2bbf2e4ad92a01f88e80bb8b342f155d1b45dedb15a2d5713c6bec6adebc440845daab90009d112c894c929aea01b244d096e3ee5e36fbcab917ecff41a991bde8a1acfb07b98130bd008e25fc54b65f845c7c1e70c7da7f5e1" + }, + { + "index": 6, + "bytes": "a679fdf639c64541665406f069fe2dbc3f4a9568c4d207cc2a42ce33f033410b56270986a3f827485964b33f47ff6b5decb96de955bcba75649181693d3acb8d09ff79bc9af87f5fb5a36a18f39d" + }, + { + "index": 7, + "bytes": "d6e1b5645db7c12fc31d77fd5d231a726fecf56473908e20305fabd77510439acc399f7b9098e02818d1a916147e9f33a79190" + }, + { + "index": 8, + "bytes": "680715dda18c0b90cd32a7f893912ff234a318a12516d54360ec9c821dc17daaa4ecd16fc1ecada37825150610c26dd4658cf150ed746f352200701a1476c2d45f0f4570a5535270b0be5079f901e71cda179d180612346a" + }, + { + "index": 9, + "bytes": "1ed23c918943190ca08dd56689c237ecb4740d56ebf3af32e0639d01f3787889b4e43a729797916c51c51bb405e1aa6a7503c65abd79334930d1fc251c" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000095de6484d5a626218fac030d238b078479b16e5a197447d4639cbad0999d11e14445ca18db9a4138a752cc63739fbb1941fd45cd3e82d5a9fa356903959bba0b3945d3773f5bac581bf0e37a09f021ebf3aea203016418708187cc6b6355db830003", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000000000082632b95f5455ab48165c2d8eadbc7e6c47dd6a589e2da738554d44c2b65e6ea80faf8d9e95d0600040a0000000000000095de6484d5a626218fac030d238b078479b16e5a197447d4639cbad0999d11e1444566f8c424c14e74213458ec3c8184e48d011a315466e04729e852db0ceb697a069e93d58f04b2f6993c46edf8c442f951ed6b528331e463df8520ce6aecd6cd02" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000002e148a7217cf973d32678677828b69fdd283b0b08de1d0c7bd1d00c32fc44e31860230ba21644263f09229b80accfdc10b9b9be0dcf9b3215ed8199e9927b9b84d28e743a9398dc7750dd83662e9f108" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "upload_receipt_invalid", + "at": [ + "receipt", + 1 + ] + }, + { + "name": "upload_receipt_mismatch", + "about": "receipt 1's root is not the root over the chunks it says it holds (§6.3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000007afe310e0a2fe78dcffd17d0e17f68c36a9477fe85aba12466be2afd97d16726000efad5feffffff009e8143b6b051e0dcae50f0e3a3fd5a177e820e060c6b0b7a65e2527f69b154282872ebbd0e2fcd12d566757482b5d75f8acaa0c4b8bad8ceda4f478f9921ab06", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000007f2742b8ee5ef813864941ca7153596e9ed5175b766f967c6a06e73e0567212e602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000027f2742b8ee5ef813864941ca7153596e9ed5175b766f967c6a06e73e0567212e02000000000000000400000000000000ae2fa4768f017d0b9b9c606052b9ff389ce6e5ebf9ad6592a59e5c52ebdd9e29000efad5feffffff01ed6dc3e641946f84b72e90ac26e9964bb49b1f0dc16d73ec5ddc45d7c24d0a45d52b01854701038004857d481762144b22bd2949253ca3e500a99ca39cd6d126e88099959eaf210fb9af321dee5e1a1a710323362532be79f33f896b5f7e1f04", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5030000000000000017260c5b9d6983d81bf14fe50f3c56a49342494d2c5f3ede7ff89f78582d325fe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e030000000217260c5b9d6983d81bf14fe50f3c56a49342494d2c5f3ede7ff89f78582d325f0400000000000000060000000000000060051e10726cb586f30350287c177f19c75d8e77979bf31a7480a9ded4d91caf000efad5feffffff01e0ea674acaa7735b0bff3554efca4c24ed13e0ac16467983237210b41d9188916babce8316a7a42164007f3810a3c5d36439159fe6ca447d29632d3d02d9eba05ed0a76d2aaddbd559ebda91cb3b2adba04b184bcebc2192297dc1c0eb93ae01", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000c15421dcd7d56017361740d8574127ac3a7eb1d8a2f8ba6865c47a5f0f5b2e216033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002c15421dcd7d56017361740d8574127ac3a7eb1d8a2f8ba6865c47a5f0f5b2e2106000000000000000800000000000000913e4d3dec690fac74ab5f10bce7dcbd6a82559286fe65f95de35ebc820dd981000efad5feffffff03e0ea674acaa7735b0bff3554efca4c24ed13e0ac16467983237210b41d918891f651a31e3cebf4ed531373257160f80e2b8e5881ae57adce38c506d6bb6b93a3ae2fa4768f017d0b9b9c606052b9ff389ce6e5ebf9ad6592a59e5c52ebdd9e29608bf2a5e7f3da9c45ef507c3ffa79f7fb3618d0e913b137c52508c956f0b45f943d3c50a7e63745e471442a93652e452d3d0a76ba54fda855896636ac87ac01", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000a6756e0fa1b3653af8a2417c4ce07506f188e79f4749c8ebe392403ab754229b803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003a6756e0fa1b3653af8a2417c4ce07506f188e79f4749c8ebe392403ab754229b08000000000000000a00000000000000124b8b68270f37657b6bccb37b474f635cbf0ae2c58e357d0b9233c9ced28099000efad5feffffff0140808e6929541ee2541443c87379159645b4be718c0ff0d4967351e6aeca77612ae6b9d86a3828becb98148c2918d62dc82fa3187b5db8bf3189a82d78fb9c00a3c21338f7a72ecfb526032c31444141a7139128125c9986ebc66b26e2723e02" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000003dbdc00a71df47658fe19aaebd5fb528f5b8011e6757e7eada8603997a578ebb0100000000000000c0c1702a010000000004802a010000005500000000000000578ed51fbcafff3ee05369a0fcbc5a60eb59d4140af2885cbc0a13a253d8621502000000000000000004802a0100000040468f2a010000003a000000000000002c90ca2b6e9c775015a67afdf26c459924b7dd2031bec5768087f6ecf4dd54fa030000000000000040468f2a0100000080889e2a010000005f000000000000000b3ff92a5bd580c8502c786634d121b2ff76388818517e6956aaac6e8ea67d5c040000000000000080889e2a01000000c0caad2a0100000044000000000000001f4f90210507f3cddf1176357838a6784a86d152332ee8b4dbefbbee9eea05e40500000000000000c0caad2a01000000000dbd2a0100000069000000000000005ea9cb2491d4e0eb2f8f66240d0c5712ccdbdda9722f7a60916cd17d4b248d590600000000000000000dbd2a01000000404fcc2a010000004e000000000000003ee2c5f7d8d146039b995365e64dbc0bd2d205b4f6dbdbac32ccf16987fdda0a0700000000000000404fcc2a010000008091db2a010000003300000000000000d1ebae2062b04545ae39e07d0972db0b2ee09cfacf7b318ce9f318b32cd8fe3a08000000000000008091db2a01000000c0d3ea2a010000005800000000000000597035f74b79b9b598d473a7be79894215bc6adc48a4ba158f57492eb44893430900000000000000c0d3ea2a010000000016fa2a010000003d000000000000001e66463c5658da65cbf4456f7101d530c32f59133f40266f54c6e287ca0fe2c8124b8b68270f37657b6bccb37b474f635cbf0ae2c58e357d0b9233c9ced2809906000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e67f2742b8ee5ef813864941ca7153596e9ed5175b766f967c6a06e73e0567212e17260c5b9d6983d81bf14fe50f3c56a49342494d2c5f3ede7ff89f78582d325fc15421dcd7d56017361740d8574127ac3a7eb1d8a2f8ba6865c47a5f0f5b2e21a6756e0fa1b3653af8a2417c4ce07506f188e79f4749c8ebe392403ab754229b9825e20e409f26431ec852660c40b12b2a953eb1b2e92c30878adc7c2f039fb50159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936994e9bedcc15b8f7a95f6ab77917cab66873cb7804852f6dda5644479059184f0735603dda701a3e1baaa989a9d2ecdae1f8ad0320b6cf46ea10288a0bc275c8146e8bba0272559dbee93ac4332aaedd5d603dafbf95aed6da8508456aa8cc1c03", + "parts": [ + { + "index": 0, + "bytes": "bb1664e10523de5820227f9d8d42692d9a6180640d542a4cf9a7a87f1e3f1c5920e40045e10886e0d3c9154e627355e6" + }, + { + "index": 1, + "bytes": "123a31ccc7c2e1123933edb8146b7afad89379b60728ea4444d85037dca1a9a262b6bd35fc1eb78e62fc91ddc55d97af92041098018d67030f260e4a01f073f2fc3cd6c7ada7853610e5373d2e33a551c05565e91b" + }, + { + "index": 2, + "bytes": "953fb6d924527b23f266115c0c538b1b8fc95af0d8bbe83ee5c35521fb15f6e2aec3e8402d8d6e742a678ceccb9e52b56daab4e1b2fcd2c42c10" + }, + { + "index": 3, + "bytes": "e802516a161bf1a226f0dc02747cce7c51eee2cc81169e808b7b9905a0055005b06fa9ffdcd17b4f709015d73ddbdd2810123e631ed301c26671ae4d13b9ccb8f719dfcc7078fdb917eda5e66c181cfe7537ae49ad4c1af029e9b0397dfa59" + }, + { + "index": 4, + "bytes": "41c75ee1fd3dac36ce090a3f788e830fa5d500a782f50c3ae45d0887bc197bbf3d2f6d22931ae522f58803d6735237ff2e74a3ccbc1a47538976cedd639210c3ca4ce7f0" + }, + { + "index": 5, + "bytes": "0dc42a1d2f165a38fedfc1a43d02144c9ad894e7854a7b70eab42a149df70fadae7a7d2dc49941bd6f2c3c699095558feab6c0741f37e586bc755d3fd2e260c1f7b68a95a2f0acbadf730ace765c77909782df33257b6da72cd00080dd2bac22c6895d36c9f53c6956" + }, + { + "index": 6, + "bytes": "adc9e0200846d40c80428f45ffb31bdbb34effd009ac3cf9bea00ee34a5b640472ec47ce42527f171f1659fc6dd3e42bf7c239d61c48ca9d5dcf66130fb31765d819a21b5181b5f7a06d8c0fd385" + }, + { + "index": 7, + "bytes": "33df85a19e3eab98f7bccbd1ece57cd8bcfd7614121e68a0b51be6e8f7b90d344d5ad75750a07516c21cd1a99e160eef9a7969" + }, + { + "index": 8, + "bytes": "5f56536fe2090df47a62ffa6f120ecea6f5725e51670846aa8ebe50cc9d3ef7e2b089ae65adb294e5ece232bb5e636cededdf9656cfcf82dead4c0dcc6102331c651472710cb694baeb051afeee01e097d9bf86224ec95de" + }, + { + "index": 9, + "bytes": "5c3ba761128927581663b40cfbe1b766901112c2072b7458926593b804ea3749b0e00f859fc0c30a10a1e9288682ed0ce22a2a7025bddd22b99e6797dd" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a4445f90d259cf12668d8d4ba516eb93d2c37fc5b330d7eead730e7c1e3651aa11d60c1663c64c4ad8a4adbcab61beee2d39a35ee63972a0bdd8b6ae2cdbc1426770a", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000001a8386b32c1c447bac7e2f00de34730738af4a0aaa3a80b7a97426e5ca50d5c480faf8d9e95d0600040a00000000000000124b8b68270f37657b6bccb37b474f635cbf0ae2c58e357d0b9233c9ced280994445d61ec4a35d478c92bd5a3d168398ba32a40c0c3aeb1f552793712302386bc8bd376d322c53df6e2667f14effb877ce4d6e48f6280a42f9d1029632211d691a08" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000048e285f78188b652b5532cf77dd446997c7cdec28e3610203488370a105ab1a1075035dd0f766834b746126c4c66bac494c7c3a063d2a0a7cbf70a31a0bb2fd16f4d60bfc1509a90e1a08b6c3a16500a" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "upload_receipt_mismatch", + "at": [ + "receipt", + 1 + ] + }, + { + "name": "store_outside_region", + "about": "a store that keeps the master in US, outside the room's region pin of DE and FR (§6.3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000005f8bc0fe101a8035f7efd18f278805f1dc1bb1e4f6a2afca7f24a4c9c6f19345000efad5feffffff00c79ad4c7c8f82cf1a9d69c239935fe74fb4b20da87dbdc388846855d15c56d4ba146af086e9b3ca76c26b381303b0b1d0cca5c69b9b1f33cd763bf2aa1967c08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000002c292858890c888de8fb3591e44259da8b1d2c9442c56087c5f56a46fda7bf8f602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000022c292858890c888de8fb3591e44259da8b1d2c9442c56087c5f56a46fda7bf8f02000000000000000400000000000000059373f75a5b431fc92126c9a4277ea8dd592c00b4f72200595969e345eda45b000efad5feffffff012fc7893c4fd43a2535670bcaf40fa7b2bdee31c17b56ba239581bd528159b381ca9d56f3d4faff660059ee4648b994d23f549b846ff60bca6281bcdeea007e4b80e1578013c81c4afd0c29a0749886602cc3bb6673fbc0268569cfbcc0d45e00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000e99a7c901d25dcc06ccbb0a5aebcf540f1beded30a9b191e373840afc1cb8915e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002e99a7c901d25dcc06ccbb0a5aebcf540f1beded30a9b191e373840afc1cb89150400000000000000060000000000000012793151ffad00027f2a1c37d85143f6674febdaee75dedd8976120b432fd872000efad5feffffff01a831dbc3902d50ae575ddb280d4e07480fe43242efda8bb6bec9d66bd0070cd43497b31d30d58f0fa1eddc81eedf9e371e03d4db4e0095ffa471ca8389fd1424ec97b24ff2993fd60f506751b3f5212e187a08463a889652772853190953a70d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000020f077e78ac7d1c8cbc69fdccf1932bf3a28161e5e6584472ea5711f4ca7d1ef6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000220f077e78ac7d1c8cbc69fdccf1932bf3a28161e5e6584472ea5711f4ca7d1ef0600000000000000080000000000000037db87d30c23d5d9c726ad93a9ab94d368abab94020a1cef9ecb70bd4839807f000efad5feffffff03a831dbc3902d50ae575ddb280d4e07480fe43242efda8bb6bec9d66bd0070cd42d773a77909ba99edbbce92a14786a411c59ee77d5d3b3530ba6df1b8b535ce2059373f75a5b431fc92126c9a4277ea8dd592c00b4f72200595969e345eda45b647e1b1a6c5e1c0065aa3ccde4e5868cc4ec57edee9146c2a80557b11ecd1455ab6af0c6a8be18ac55931a6351a762fd63319be82c2a07f3bcbbcb2ddd51200e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000001fefdc263a4f975a5233006d39b2499acc3c4b4240a8899eba214dec0296f95f803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000031fefdc263a4f975a5233006d39b2499acc3c4b4240a8899eba214dec0296f95f08000000000000000a00000000000000d4d9c0db7d9acdefbed171ffa46d3520a5323edf7a9e61d825008371830e14d1000efad5feffffff01624052b551966a1393d90d6511ea903570889504c2338e64add03523bc48e68ddb893091ef1e23fea8b0826d5fa074fca42c6886a3581c20eb9c4efe3b887bde60a6ba1f5f4e4f206528c32e0ffdcf77dcce86bba977613025e5319fe8636c02" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000006df4dbf84ec330f083b1863efce81a562490b1af793d667474556ea370f5c0330100000000000000c0c1702a010000000004802a010000005500000000000000d78833f498e20ebba22c6c0ff5ea1987436cdc4537669a6ff7ed96b65548597302000000000000000004802a0100000040468f2a010000003a0000000000000037fc9827e0ccc5d7cb59dc99baaddb6a23728e8cc2b586a1fc896a05b69d1a12030000000000000040468f2a0100000080889e2a010000005f000000000000005b88fcab0d1ef09f76f19f87918826180b3d2178b5725cc75a571ba201a966ee040000000000000080889e2a01000000c0caad2a0100000044000000000000003744df824b3ab87c9e257e3386cb3193689d404c6bc374ae53e45786a9b94fcd0500000000000000c0caad2a01000000000dbd2a0100000069000000000000004326cf7e4c1300866f0c1dfee80e8c55ac4e851180341e1e0460df5a4b70b56a0600000000000000000dbd2a01000000404fcc2a010000004e00000000000000ffc6e2d4a51a7c916aa9dfc04a4abf20d322ee3773b09f8020bfbdae52cc66910700000000000000404fcc2a010000008091db2a01000000330000000000000071ff5fc1b8425996cd9742e5052cbd1d6891e5b9e530b46f3a4ef51f8341ac4c08000000000000008091db2a01000000c0d3ea2a0100000058000000000000000189934d58fa4af4b2255813e757ef1640cbfc48e9c91c9c7030c2710ba8c1670900000000000000c0d3ea2a010000000016fa2a010000003d000000000000006cbd932a61ec840323ff36a614690dded33d76407e56a89847ab28bfcb9cb695d4d9c0db7d9acdefbed171ffa46d3520a5323edf7a9e61d825008371830e14d106000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e62c292858890c888de8fb3591e44259da8b1d2c9442c56087c5f56a46fda7bf8fe99a7c901d25dcc06ccbb0a5aebcf540f1beded30a9b191e373840afc1cb891520f077e78ac7d1c8cbc69fdccf1932bf3a28161e5e6584472ea5711f4ca7d1ef1fefdc263a4f975a5233006d39b2499acc3c4b4240a8899eba214dec0296f95f47d8f19d56309f480cb9ed68cf180dbc51e68a7ea149836559e3c6478e4828bf0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369980a9522246c68eabb881a419191c89f4d9047ef311ca42a5f835384817216537ad614281e4f4c11bac6b555d4d03e7f6e5af526c7d83cbaed6ff2248337d0f52d4f23e91fb3ec5018fe995fcbdf44c843c6c01c8d335542a25a673a497ac850a", + "parts": [ + { + "index": 0, + "bytes": "eb8c82ee33d0822a65b8b35b59b265ce9f9c3646229314f75cbc3824bd73f3485f5e06bd3aab1b418cec7f2a85b84c19" + }, + { + "index": 1, + "bytes": "f364c060151a08f1302f845aea3c9ebbc0b81adf6deea9d02a8d6e84a8d69490c05a53e42d66d2e4eae9d2fd256be167d339ecfbbcf2877e298430b8962151d1af4d51718360e484392c01580e38eb9d11e9d8b640" + }, + { + "index": 2, + "bytes": "0184537c634f312aa3a7990ad5151cf2a35b665d18cfbeb949ba6a033e733753ea34e905902bc77de6b92512f72e277f2ac366068ae19172bb72" + }, + { + "index": 3, + "bytes": "e20c122f4b8ac9877366ffaa50a8eaaa249c42dba47620cb6ea2cc32b19b11506b089eb973abaa38614ae6f44b651087ac7200eddfd7967164c59d32482a7e99744c20e24b7aa9931b8853c6e6f97b1bce8f049b2618814ad1a5687972d8a9" + }, + { + "index": 4, + "bytes": "9391fcf2c6c82559054a3614e797f5d88e65279110cdee6229ce49907bf403eb018c996f7857dcff5445dd3bf26ce81d45a6956995fc4efae0c7b287084815b0fdf1ba0d" + }, + { + "index": 5, + "bytes": "fe892160fda37966d186a1d6b7b497956a59079bdf3e09c7c06be02aee038b84a7d6302041eab7deae0597bbfaa0f6029b95f8de28fc4d8b5f138fb8363479871b11d8a4c9190036734d66ac691780efd7a6899d9dc37fb48d724db7022bcb4749b1c2fc1d079b6792" + }, + { + "index": 6, + "bytes": "c6deb890cd9f30b4acc2fb415b066981502f6b0a8a064170232ddfb8848b282861ed60d0fcc85c1dcb20bd86506f20a1c8669d927c74ea7a16e570abbf5217eba3cd67f06ad6defda047eb0c6e7e" + }, + { + "index": 7, + "bytes": "dcd830a506d5f25f7df568d8947c546b268b8e1c7c7cad3ef945a1b247f53d3555fec621b2f54efba72afae271cd07043e94dc" + }, + { + "index": 8, + "bytes": "ac3c1ececaab9b5a0841a8c4da07a3fb9fa9f90d5ad4ba91d8689bf52d6f6f2b9f1e3d12b70c11ca32022a449333512819d523f4343e76d453247a77b0bfcda83c135393d3a9c3cbab919ecff463f8abd171272852dd951b" + }, + { + "index": 9, + "bytes": "67bcba911cb0655e9a21f9a6276b1fc59c33cd575ce069cccd5a6b543de5cbb7fbea6d45bdb5928f699483db088c71f501fe675419e35211224731160c" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000005553f45f515f2c2f2d2f18edda3d10bfffb217e3a797d5d3331d9e127dcb9f315424cff818d40bfe02b4cc3f74724ee1efe0225d51e7e586df8081fe2815900c1600", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000000000000306ee17ae1203ba131e881f233f34d16c91408cb6afe83f6b90767a019626259c033cbd9e95d0600020a00000000000000d4d9c0db7d9acdefbed171ffa46d3520a5323edf7a9e61d825008371830e14d155539d9837741e1207bb9ee19ca16353a01b52421200eb9b6e6c5bab17b222dad638cb4b3a31ebc1f8251cabc1128d7eb1b08244e0e218273e25cd4dd98bcdb74c08", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000834401bc72f577f0f6df96411263cffda2bdb4aeeadcbf349c54ee044810508180faf8d9e95d0600040a00000000000000d4d9c0db7d9acdefbed171ffa46d3520a5323edf7a9e61d825008371830e14d155534b7b181d43dfa55830c84b2cec80b3ed8b72cace4ef655f981832eaad75caf22fbf20cba10d74b5684cb7c7ee89bd31fabc00feac6e43b54ebc203f035ec8107" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000004a215436573083debc2f9b513f943a60d8ac2a87a4e00c04d2c6a612c04a71d52c654f76b9063820f4641c5309e3b38734a09ef6dbe4dfc541f09eac98aae5eee505a94a5565ebff85ac3254d7a83209" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "store_outside_region", + "at": [ + "receipt", + 0 + ] + }, + { + "name": "consent_invalid", + "about": "a consent record that consents to no purpose (§8.2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000006e46ea8e358f2a74e9e52e7f67ac2f209d017d1c177a69a8b72fa4a31090366f000efad5feffffff00988f6d0a7b860bdaffb20d4e1d4e0f54e4d53a87b57f0ac7f5cf9d9d1d87e44a06784583683878abb0d4dd3cc6d7656bc008802032350edaf4865bbcc1068d0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000ec7630e3b34c6f39268f0804d60bf9e804bb02b218abf0c686cf993af9aae775602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002ec7630e3b34c6f39268f0804d60bf9e804bb02b218abf0c686cf993af9aae7750200000000000000040000000000000057f1130abd244189d58316141de96ecf4dd4e6acb2748cfdac8f62d7450167af000efad5feffffff0163a187f376e65e149c0050756dd5332b05b7e433669a9c2f8d28dd87b80aa3264c637987b5d9c159ebe522aafd3a94946e285866b28d753e3bce25d6e1e32d2be75622249dfddd02cdda1ddcfc43d9bf371fc2e250f97093fbb7231d4c430607", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000d22431342a4d08de384336045ec4681e8f399ff464cf0bbe591f01b08ce14630e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002d22431342a4d08de384336045ec4681e8f399ff464cf0bbe591f01b08ce146300400000000000000060000000000000078b7ed3e6ff3a8b0cab0caeaae06fad4b1b17c177377c99369d16960d252ba67000efad5feffffff010e58bd00a668abd76386ab622d0b50e4882337fb5263351a7fd52821ee146b1d2afb2c0c2001465ead5d26a2132a5f01883288fc0ad6a81937118610d2fe608c98ff7330cb4b63059c73e97e6e1f5b99e826767a3692b3e5718712b79483280c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000d12ffdd0eb4a77e5c9644358e7ee07b6a339c26cdb40e7921bf8d54c42616b8a6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002d12ffdd0eb4a77e5c9644358e7ee07b6a339c26cdb40e7921bf8d54c42616b8a0600000000000000080000000000000047b7dfa57ced5c26557eaa84fcd5dd2cd06388ebe68d1627c3e03c1acf5f018d000efad5feffffff030e58bd00a668abd76386ab622d0b50e4882337fb5263351a7fd52821ee146b1df055d6ea4ee03d6b1781381ea50560dbf424d4700e4086025478bca7c18a44d357f1130abd244189d58316141de96ecf4dd4e6acb2748cfdac8f62d7450167affaf96ff383ecbe0df1b2db7a613b6039a6794a47423c9b13c7d7f1de32b1067dd0f39446d05d8c86ff81ee3bcf1a8735746d03e857f2c7eaa85116323691040d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000eb16f27b9a4559537f5003603ca76c45f9521b7ab633c1d16ce2660b7f554544803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003eb16f27b9a4559537f5003603ca76c45f9521b7ab633c1d16ce2660b7f55454408000000000000000a00000000000000e1606da31b2e1c7ae88149be6a0cb0a729d438ef84570088171c82a10d5636b0000efad5feffffff0133b7195245c0a1506c039c4f41c4d41b131749d40a38d1f1fcdd8d445ed98c7f1994dfae0f8061120dcb44971ee161e6db9d428e1fbd57a92612b24cc910f4c567bbc91a6ea92d64869ce0a4a52fcad8ca04c1a9219e44785b1c7b64b27f1203" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000005dafd8377710ff786ed3b3a741a8c962427883b55521c9b78e9f11a8abfb7e7d0100000000000000c0c1702a010000000004802a01000000550000000000000060ec6c31b5cbbae2be88dcf77d2c457f246680577f29ca5ff497e75e824ceb2002000000000000000004802a0100000040468f2a010000003a0000000000000084ec24b8faba2c1046e9368f0b5dc587475902d6b879b824fda194d31a766046030000000000000040468f2a0100000080889e2a010000005f000000000000001159cc52b3b9a293ebf508fe5bdc38e70e31aad5bcf22d8ff16ff0593afbdf93040000000000000080889e2a01000000c0caad2a01000000440000000000000076845104b255a5d3b82cd1c5b6c802e26394c49297896ffa19c3e1fb6a40b0220500000000000000c0caad2a01000000000dbd2a01000000690000000000000032f3dd4d49096f2abfedad3a3f10d880bc7a9c0e2dded76d86bc1a5bdd9ee5660600000000000000000dbd2a01000000404fcc2a010000004e000000000000000500b6892ecb8a05051ef09342a7a3cd2ada2d15e256d08ba43c6c52e9a7d1a10700000000000000404fcc2a010000008091db2a010000003300000000000000f4574bd5c62b61c8e1a33f6025fbec1f6c0ca5437b54699d0c5c2f020c1b0d6e08000000000000008091db2a01000000c0d3ea2a01000000580000000000000032093c5aa3c4b783d89eae2c6d9aa3d84c7512864621de62e4e79ff7c7563e120900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000886492e124759608ebd1ea8e499e6c49b5b947468afe264808f0b43b78a079aae1606da31b2e1c7ae88149be6a0cb0a729d438ef84570088171c82a10d5636b006000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6ec7630e3b34c6f39268f0804d60bf9e804bb02b218abf0c686cf993af9aae775d22431342a4d08de384336045ec4681e8f399ff464cf0bbe591f01b08ce14630d12ffdd0eb4a77e5c9644358e7ee07b6a339c26cdb40e7921bf8d54c42616b8aeb16f27b9a4559537f5003603ca76c45f9521b7ab633c1d16ce2660b7f554544d7cd7a957b4d4af36610d386097a057f639677b376612e64adc40566bd11dd220159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369917cdb11d02b030e60fb5b0aed50f6e85feffbdf2e3be86e0fbd54617812c0a66269b0fe21770a6da4e2792c901192da677690fe5d38b6872c612735eea43ab4efdc22fb9fff1fc21d8c59246cb936e828a4906e3f5c247aa5b58158d2b9eb709", + "parts": [ + { + "index": 0, + "bytes": "b1cc9c4d282121419624c70cbd1a87e9dc1e76433ef7c284f6db94ac2acc9113aaa228a63247265452474c23fd3de868" + }, + { + "index": 1, + "bytes": "9357cdbffba6d13c2cd945cc0634c12b245796b37e666268ebc7e72169516c4a899f831881b0c550188f056685a264ce5746705871ac7147bb78fab6b3769dac9bf3e6d8ce902a5bc2d1080e0d5db9f6d785a498de" + }, + { + "index": 2, + "bytes": "7d8ad065bb88e8a7ff6efab721e11171c28cda16674c1ffc9bc9350f0a60e8486f74ee0866061a6b922059482093dae6ba904879e90c94f5079e" + }, + { + "index": 3, + "bytes": "c799608462f30b8cbe50ca200cea531cc6c158ef58e0ac43c3be2e501d7f3a78d2fcf3b7c2cfeff022eae23cd0da3a48a1b28592cd5dfb70792d142ccbfef945d0eff91c6585b199bf05fdd025dd48ddc6053a7de5e45500f59b98dd41faef" + }, + { + "index": 4, + "bytes": "f3c8edad568cd81f16d31853ea20d93cca9b41108e2badc8dad9d72abd03a54bc43887984de50aadcf0316c372628153d84f43ba52119c61feca3957443e720f35a0cd2b" + }, + { + "index": 5, + "bytes": "fe0730c8f567dcecbcc719e41fcf7a376df5779e41ce7b57a27f93d2a7a94ee41d4cc40ba32ca302e751af6925c718d9df09e35efd6f96fea960e7786281cc9b2d21453ea3f24b5cb6ecd0cbc8f5b840b9d0297ba1f8502757dfcd9e5e84fc8ab2161b42a4851bd7d7" + }, + { + "index": 6, + "bytes": "bbee13f892f5849f902569c9324f7f29ad0f12a0a5585e5433a0c90f013c3a936158810a21a39076f4ba042308a19b59ed5363efc4c597f0953fd92562d31ace067dd169a87a6cca1d5773b6f9c0" + }, + { + "index": 7, + "bytes": "476580e523ac9f0878f96df2c57afa2e576c0da860adfd37b7ee7f498544a47edec5ddc5f7feee05734cdf8079c2192b89f1f8" + }, + { + "index": 8, + "bytes": "de1005de0e54c4e87da379ff505d649a0bb77e627dc8a78349b6a1799e5cb18a82cf370ef3048dd5fa70b2bb5bb1ff3f5d2cb50b06b0a8547607afe387e8783090fdb6b0533ff958327c7d70058914180cdc7313f6251848" + }, + { + "index": 9, + "bytes": "656e88732d8ad4f60c0a7b413ea07beab3b80c900b3ba2e6467f471b501906afacef3aa8acfac5506aa446e3412fa896025a10a73fde51c2425be6c441" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000e1606da31b2e1c7ae88149be6a0cb0a729d438ef84570088171c82a10d5636b04445fd6d0d0a4148dcd8716a493fd29d6f94c6b6028215ab27ca0e7311172a41d11041f1b917a183f514fae6e16a577a1bc305c2c2c37dc8c10eeda504037c584805", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000d58f7c8588364fbc916e3b0c421758b18738d0ad959b1c2a2068f4237468c62b80faf8d9e95d0600040a00000000000000e1606da31b2e1c7ae88149be6a0cb0a729d438ef84570088171c82a10d5636b0444553a72e5eb1b4ec360761b2c8c9b2895d1d0515c3602253408508c47cbe3dd18917754153002bb938957579661b0fcf5fe214e1fc6b29cdc769c0d51d3c557404" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000005f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000eb97f87e82826ddea2ecd1e66f81e2d33a390ba30dea012fea0120c430d4e5f699891e4014be1df4eed99fe1ff0db61dbf78661079bdfefb0a3e025832ee66d19f7443c4cc9010f1eeeeb9549ef61a0a" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "consent_invalid", + "at": [ + "consent", + 0 + ] + }, + { + "name": "consent_bad_signature", + "about": "a consent of the performer signed by another key (§8.1)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60000000000000000020000000000000012c533ab6581934d8f1729a3e70c5bbbbbc474e75382ab176110b2caee0fa689000efad5feffffff009ae15a8002d46c3a30c268cd9b0d22a8085b1eca0c6467052329e43b88d968c7f3b0f2404ba4ed6d8f6f02b9356c0ce971cbadfe57e518d05d6d8d7ca5cdce0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000007cd0ed5a338beb07ba6c65e1b07e9d659b0925415fc3ca90089f592c6d45ce7b602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000027cd0ed5a338beb07ba6c65e1b07e9d659b0925415fc3ca90089f592c6d45ce7b020000000000000004000000000000008bc2d2bee29045163dcda6578dd011a4c3bfb8c461bb346c6fbeedab70790ce2000efad5feffffff01192528102ea611096b1d88ad3d62c209a36cf15ec9f243f4074302e79a6cacb1726c924e42387e37193db9c9cc4ad32c13d74f857d85c32527853ebda397e22942aa018f894859a9df9e5e862607d0eb02c3cf87e85c1911254ea79c6abbfc05", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000232f1419ada493b5463a9af4368d2b0cac70cea108fa12da788e98e77eccde29e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002232f1419ada493b5463a9af4368d2b0cac70cea108fa12da788e98e77eccde290400000000000000060000000000000009d67753862028726acb6279a58f97d5e73ee64c998a1dca03cc37a4396e974e000efad5feffffff012aa7b71576adeacdaa7bf827b5a496f771f4c131727cfb118c221a4cedb2816c32a6ba13a46c493210aa871b113331ca930fdeffae4afea1d54537a09d9299773321e5cce353a183d007506fbb208f4524afc6722170ab2d908581fa30ba740e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000531350eb038fa94074e0140638c3eb78215a3ac9d2bcde1c8f58471b2f2624436033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002531350eb038fa94074e0140638c3eb78215a3ac9d2bcde1c8f58471b2f2624430600000000000000080000000000000048fd8690a0e020e77d097965290c77db1c50b85e9e79d788a6c8eecb84b754dc000efad5feffffff032aa7b71576adeacdaa7bf827b5a496f771f4c131727cfb118c221a4cedb2816c18936bb6016c0fdb4c9af580ed666c4f663f8bfe932434a6c410b6364715865c8bc2d2bee29045163dcda6578dd011a4c3bfb8c461bb346c6fbeedab70790ce26c46a058dbd2651530464b0fc8a2f8bea0b9d0ce0c93016a8ec351bdcf205207e118d7f0699c82a1e739db7bf10dcde65337ec5b8168617ed4e8fc7adfa71e0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000076dbed6d18085f31f280196213112bc25b5d0a2e0fb7f71a5754d714caefcad3803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000376dbed6d18085f31f280196213112bc25b5d0a2e0fb7f71a5754d714caefcad308000000000000000a0000000000000025bbb87d5e79d51559de11ba522123fad9edf522fbbefc679c41cf6f204c5a3b000efad5feffffff01a7041062d025bb1c6e5592b02d14eff127642b166f36430be972c41c0bcca5b364416cc4c13cc4b51a4159370558ad76e1011ef72f8cdac7bbfff5e398e016408442acf3719fe3f8da0e94f040a6db31800bc16d9ee13c2cac4b770c3f18850f" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000004fb55837be8f357c58247d1b29ecc8d4396273c7fc51b57d96ad48e1ed32f0dc0100000000000000c0c1702a010000000004802a0100000055000000000000000bea07cfe7a46597b414a8e00b8517f87a55d0b56d3bd59acbf476fcec923bbe02000000000000000004802a0100000040468f2a010000003a000000000000005d33317c06972ac3ce1a5fbca5cc782697758515ab714f0822412559ad91e26a030000000000000040468f2a0100000080889e2a010000005f000000000000000788095b7a17534f6bd23165e86c3c3f76e7d3b1c9f25ed0a64b07c37feccec8040000000000000080889e2a01000000c0caad2a0100000044000000000000002616eed028bdfb352c0bb6c6d91c1a358ea5881b0779c5610857c92365b4a46b0500000000000000c0caad2a01000000000dbd2a010000006900000000000000d684bce148bad4231eded7de563d9944e601dd4750f6c2f2219c961a9858cbe70600000000000000000dbd2a01000000404fcc2a010000004e00000000000000b92b959f24c83915691d0ff9e5a269394d3059582ce202b76ca7c46482129dd90700000000000000404fcc2a010000008091db2a0100000033000000000000009e13ecbdc4aac638ab1d88a55b61a23a1e76f4b8aa7293aa5897bdf8afe8101e08000000000000008091db2a01000000c0d3ea2a01000000580000000000000011efcc181e7585def8180e094cb1adad676cf058570bd7258ec023be2780f9a40900000000000000c0d3ea2a010000000016fa2a010000003d00000000000000c57e7d433a6d053abf4d0bc85c6ce1c61984764ef85b52202dd421b84050b52225bbb87d5e79d51559de11ba522123fad9edf522fbbefc679c41cf6f204c5a3b06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e67cd0ed5a338beb07ba6c65e1b07e9d659b0925415fc3ca90089f592c6d45ce7b232f1419ada493b5463a9af4368d2b0cac70cea108fa12da788e98e77eccde29531350eb038fa94074e0140638c3eb78215a3ac9d2bcde1c8f58471b2f26244376dbed6d18085f31f280196213112bc25b5d0a2e0fb7f71a5754d714caefcad3e92a2c39af3620b52c3eaf42b2ac6ae26dd7ad19f04d3e1b62ac4fa2816eb7810159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699ef4f86cd8d954ce7c071d28694eca1405aa351675ecfcf0f8cd1628e06fac6498cfef29ffd370e3c540892a3e75c30c8af2556c4a9e136b330750522ce8d6557768ae8ab395d5d8376d063af9ddd3c3c2bd1cff4284042daeda1d1054045d10f", + "parts": [ + { + "index": 0, + "bytes": "23c0f23260ba1392a9ce2e405692824a63ac1e27f2ab23cd54c52b8ec371ff36688d4834a6efabe9428ac06cda7c350c" + }, + { + "index": 1, + "bytes": "0ea8d35b64781adfeffa5fee0778da8c191cdb8bb89b80e8262ba85381b97d0b97640c914760006bf76bfad2fe42486c7e64997baa225a06ae342c78412233058c16eef355ac991fc47337500468fc456f9d72b044" + }, + { + "index": 2, + "bytes": "60820cb6cc11f507cf7dff0b0b16825f7b6f446097473285c622282e03c1131dfb88b7cb213dc4162c68898b76a6afae8a63da907e4d45e8f1a8" + }, + { + "index": 3, + "bytes": "d9b49848a4f3698b98ec03d3d39a9269cb107de1ac54e34c9e5ebb8cf5dd77d0d00e91077d5c9e9af106d5bd5a0b86ea7a47c3959fbb7fccc7b02926c504a5a1a06df818062f40400f9df2c53fe42535b90b9de3d977239a04f67da971616d" + }, + { + "index": 4, + "bytes": "c81cf471584c8f62cb004a3126db51a00bcd6e352b4300fd3ed7f3f90667f8d9353c6a8b03cd6bff221e3978d66393c2f17eee6870d35975db87ec43bfc40a3dfa51c4ef" + }, + { + "index": 5, + "bytes": "bbc2b92f54504691a16e9fbc2024d647afc8e11dc21c02386b555fd8904068d4b1244059103626c88706f14f38658f14b8229760137296b5f93a30913586520c7063071d6bc41d04f26fc2a04f4cda844846b82bc936455c372d6bb98563d35532cdf44dbd55cf79a3" + }, + { + "index": 6, + "bytes": "4092e1214476397a51be9f8c5c3eea84a271228451f2f01125f3e42559707a6a75ed889409cf4d922d63b942b6c0ad725759cf24ac20cca5cae8f3e2b673d112793e2bb9e34930fe11d198d84c5d" + }, + { + "index": 7, + "bytes": "7130dceccca892a0508d57171182fa3ecde9fbb49583a154daafbadb064c14a2eba820cb5b33d97d91c9a61ab2a9587a4210d4" + }, + { + "index": 8, + "bytes": "1a7a6859f3122d059c1b9098872cc411c9f3d440cbb27a7c2da5a7b92280ecf4c466ce162cc22644a2ae4725ee371ee175885f7c0a9ef820df3b4b2da43e15e80217e13948644263d6d3d8c454b2435d352662191aa1ccc6" + }, + { + "index": 9, + "bytes": "1d45206d8c52cfbd5a2c78aebb8ee88eeb920cacfa62ac839f07074fcc0397eb3d7853dd4d77fbbd41ccfd72817d0f2ed506e5d94a0fae910dbb0260b9" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a0000000000000025bbb87d5e79d51559de11ba522123fad9edf522fbbefc679c41cf6f204c5a3b4445946d687520827bdbb08a366eddb49ab409d0aca87cdde45f28b8fc7650c9cb56a13b8a66828da8548eec87eb368d0fbbe8ebbe5259b88ac849c4562243d19c04", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000fbd74eea7d1f917467e2dd862a701024d73461856d83f893d10cfc8a6781426e80faf8d9e95d0600040a0000000000000025bbb87d5e79d51559de11ba522123fad9edf522fbbefc679c41cf6f204c5a3b4445238f46aa61d00131317ce17e47cb0ccd4e5ca7900b3f1190874ae1030e194dbbc786f0359cf9962528ac88f832c5ddffc0f68f6fef0af67a7993aa09bd0eb505" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000dc7d86aac17f5121cb15a4aad93f0e9ba596af7ac170c29bcf97be22e71e11efc7ebfa0ca4f9a0a87b3963d7dcd74682d4ff8e1f6456b343684e4d3ecb3ca4f0272c585a5d2f088f1afec3bae51ffb05" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "consent", + 0 + ] + }, + { + "name": "commit_chain_broken", + "about": "commitment 3 whose prev is zero, not commitment 2's digest (§5.3, §9.4 single-take 2)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000ae3948ec0cc5289d60170553942484526e3ad12f8ff7b3178dd5e1d04bc3e254000efad5feffffff0022d8869ca8814f29649ea5924beea91627130173fc11fd75358ea7d2edb032859031dbf8868b62844707f8711bc557cd7834a5069b90b35d35156f9215763408", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000058eb37319b2fe3d4041ffca164f61ec1cebe7831da8d99ac32dfc2d36fbf6769602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000258eb37319b2fe3d4041ffca164f61ec1cebe7831da8d99ac32dfc2d36fbf676902000000000000000400000000000000cbef9a3dd7b7e5325ed21b11986dd7bab9f6649542a1bb29699bf5f284f30c68000efad5feffffff01715b7cceb530573ae8be0374c04247810362ae35d15399fa291903b84b8d74c630d1e4313b88eaa1173929a85b5a599d2b553a5a0803984779498c3d9cd5b9e6469f6cd076d608f7dd5d88bbd56e95abc0c12b0fee8c8b1e0332587c9d6b3e0a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5030000000000000028c50cdebda9c5da6025e0660e1feed1e3e83a1ade07f6c3ec44b6d77c4cc53ce0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000020000000000000000000000000000000000000000000000000000000000000000040000000000000006000000000000008ee9ada81410186d4aa5ccece8ea9e03edff4b09ad5202899291fe74da3649b8000efad5feffffff014f20fb3ecb6cd8285e371318bd55dbf0e921a9905a0989dabe2a2d08cb4a8d63e1d08bc6c6869acd8f744640041cd1095b926be441fa29bd90773218b67b21b99e389a2a82a04208630c2aa2c3590cf347e45c832fa698605aa5cb43679f6309", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000c80343aa3df8b25829b4430e96b4d89c1b165a33739ab832c147596241952ce16033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002c80343aa3df8b25829b4430e96b4d89c1b165a33739ab832c147596241952ce106000000000000000800000000000000daa8a3be384e16820c13d7b6269615dc09df80d3cd77a90b841ce60d20d347d8000efad5feffffff034f20fb3ecb6cd8285e371318bd55dbf0e921a9905a0989dabe2a2d08cb4a8d63471b57f13bb6404ae0eb69679b94cc99d840488ae2fb922080a32b18cc4a34e7cbef9a3dd7b7e5325ed21b11986dd7bab9f6649542a1bb29699bf5f284f30c68366cf94afef4f6316f78a40ab2fec564cd4fdf786efec37f9380102ac928d57697c8bcbc54a2c8fc9baeada888650bb99ff4c024388008ac6e1d89e2d8de6c0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000081eaddbf74061f469ceef4d45e687799ed1ca1fdf3f50520eab79ebc8aea023e803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000381eaddbf74061f469ceef4d45e687799ed1ca1fdf3f50520eab79ebc8aea023e08000000000000000a00000000000000ce4af30172ca527296081b40b388cd6c25cf9e9bcfdc3beca54582d56ef21d0a000efad5feffffff01dbfc2812b96e08ff5bd60fcba52a06ee2a96e59d592bad42fbf0b2a8828b8c071e0eda41f72da3a6fbbab1140c0c33a874dc461c660c42ecf749f926bc810c5bfa266eeda01141c37571ac4af49c63a18c8d107c23ab6e03ca4fcd3fbe5c3607" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000aab8e80d95ee79517cfaac65f00ac4072ec1fed0675c31e5464479729743dfca0100000000000000c0c1702a010000000004802a010000005500000000000000666c8a93bb2543655c05e9cf777b89b5fd2a55b5331551477194abc9758b225e02000000000000000004802a0100000040468f2a010000003a0000000000000007554419efbeda41ce4f7927a7adc8ec55a3928425ed2aded5851e5065b83ffe030000000000000040468f2a0100000080889e2a010000005f00000000000000392ece0698069dfbf9174f4891244492aad9df4793f243806034f0b07738ddc7040000000000000080889e2a01000000c0caad2a01000000440000000000000009446e973220fe830907cea1ca570cd78e3d35e9357504bab6cb8e6cd9af294c0500000000000000c0caad2a01000000000dbd2a0100000069000000000000003793aaab734daef19e2314f66af288568d4c0c5f73ea8fe4d68e9b7ecd7539510600000000000000000dbd2a01000000404fcc2a010000004e000000000000005d61f99228cf1e8c50e3670932ae7b00419f12edcc2d6e607e8a3e0689cd44560700000000000000404fcc2a010000008091db2a010000003300000000000000a6865ddae3481eaebec44bd2ca99c76df7f25a1fc4866c50189e9d642142a60908000000000000008091db2a01000000c0d3ea2a010000005800000000000000d9f09b78759b7c0e0dc01ada644e3e381d8762b825430243d2ca7e6488dd2bba0900000000000000c0d3ea2a010000000016fa2a010000003d000000000000007404843ba435e8b461b4fd05a9b19d4a00ffa99c2e0a974c6ce40a9965ffef14ce4af30172ca527296081b40b388cd6c25cf9e9bcfdc3beca54582d56ef21d0a06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e658eb37319b2fe3d4041ffca164f61ec1cebe7831da8d99ac32dfc2d36fbf676928c50cdebda9c5da6025e0660e1feed1e3e83a1ade07f6c3ec44b6d77c4cc53cc80343aa3df8b25829b4430e96b4d89c1b165a33739ab832c147596241952ce181eaddbf74061f469ceef4d45e687799ed1ca1fdf3f50520eab79ebc8aea023e3319b480485c012ad32f93873f76060a800800b70bcd5104ce6992d315b489a60159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936993e22a0e65b51af181dd8b979697920941701b1c196c4f434adf1ba24f5f68d01785eeb55ae0ecde70e2562d4d85623721e3e93d870073d03822d3b96df25551211590eae8a6da19bdab2648b34388e1b269bbe485232814edc9ed68045f37d08", + "parts": [ + { + "index": 0, + "bytes": "9a54a5ecbe053236d57e8ebf7a3e0b91c3fe7148887ef79d4f009bd991c2e79eb000c6b372a9be084148be54aa11b0da" + }, + { + "index": 1, + "bytes": "c75be352185e45ce0cbcbeba4fee2ff7728de4fef322071979be4eff67e5b82c8ac30e4cecad4f52b70efe12dd4c505b8baaf33285324a92b7c782784a81f1db53988942002b17b5ea586899fe503c7c3e81f34854" + }, + { + "index": 2, + "bytes": "5365719d26108bd512a3d7c4066c8a48978df42f6e27fb12493fbfc1e721dbe7514a721a99886d0576a4bd8ab23af7cfc88b81401a631cf385e6" + }, + { + "index": 3, + "bytes": "30974331167dc14a546e0ae535cfa3144f356f6c960b3dba3c3e3f8e6457fb5f980bffea69584dd3d2c2a7c12c6b60c3897c78f90058e48874cdc4078367a77ce64940f4919725e23cb39bb6824afb728fe2f2e22ef94bc6c25638ed6ec9eb" + }, + { + "index": 4, + "bytes": "062624a608f140d26693fe28391271f4a69cdd0d1d0f5d58ff0789af945749d863a9bafe4a33ace642e89ccafd31bcd7772c32e3393f7917bbcbc3e8dd597941347102cb" + }, + { + "index": 5, + "bytes": "cf961ae2cbffecb03da351f78df71fd1121d236b8a53260cbef539a5836b0a07e66618f9abff8c3603cab1ae174df7c2868ca3487120665e8743470d7960b8d8bcde2c856eb7f3be3301f53828d5c1b69760b88b9227be5d06a755dfa63122871c3e26cbfa812c14c1" + }, + { + "index": 6, + "bytes": "4d1f299c80d9e52b3daf993937a215def73cf572e94f37015b343a2f0b4441651ba3c438dbf28a22521ba074bd809d221b794d5c26ad5d9b4d743d1d68933c8dd09f2151d45db4e3aa38f5ec6ffb" + }, + { + "index": 7, + "bytes": "7a10afb4e4df933f677a58f7e6d276125f3d0b3cfef77d47fb957bb8ee4e6792b9c3fcdf68ed3dbeeca7758cfc6c3c98d1b2af" + }, + { + "index": 8, + "bytes": "5c81a0d177b461becf80f5701b01a8788f80463d9f013db437fcdc0e5a5803f27b2619d9a4654750ef4aa35e6881ae19b561b10a251ccfcbb24825e9e47b48abdee9dc305f39d991e6a877cd5ce9caa14bdfe0173e027b34" + }, + { + "index": 9, + "bytes": "8a1860c1e7d68a2b647a29c265cf490680b802b36777caf6f6213263e5c3f4b00567a6f47861751255234b091d1ef505a1e1a33213b9b3a9ac50291503" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000ce4af30172ca527296081b40b388cd6c25cf9e9bcfdc3beca54582d56ef21d0a44459f81d1bb6c695a8ea1231465a0d8754da1b03cde0f9ded401c561f9b279c4f613f0a09f3d2b18520be37c93cb6a3328d19be7e074b6695c6fdefaea55c50890d", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000008221685f4b926c9b18488ee0cfcdd633db7dec7d63f73ffb4e5ff4e53adcf74180faf8d9e95d0600040a00000000000000ce4af30172ca527296081b40b388cd6c25cf9e9bcfdc3beca54582d56ef21d0a44457c615b18bd1dfc238a432661e278171d1a2d13134e06a68f723284abe472dcc159dbb244666ca528a965e774829b26a2316b03de413eb9dd902ce718686c640b" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000158dcae072d2f2bfb89930641d0b81be3af5620f52a89eb05bd94e09c260b862a797d3b4b75c6ac0809801658e3c4bb384397dd1cd7c89146212777b8209992ea2ec4790d14c64f215fd5aa7875a4302" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "58eb37319b2fe3d4041ffca164f61ec1cebe7831da8d99ac32dfc2d36fbf6769", + "28c50cdebda9c5da6025e0660e1feed1e3e83a1ade07f6c3ec44b6d77c4cc53c", + "c80343aa3df8b25829b4430e96b4d89c1b165a33739ab832c147596241952ce1", + "81eaddbf74061f469ceef4d45e687799ed1ca1fdf3f50520eab79ebc8aea023e", + "3319b480485c012ad32f93873f76060a800800b70bcd5104ce6992d315b489a6" + ], + "size": 10, + "root": "ce4af30172ca527296081b40b388cd6c25cf9e9bcfdc3beca54582d56ef21d0a", + "verdicts": { + "single_take": "commit_chain_broken", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "take_not_closed", + "about": "a device that stopped committing before the stop and never closed the take; its upload holds the eight chunks it committed (§9.4 single-take 4); complete holds", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000594e29a3579d51792bbe68007bfe60949db6ff08e85fae9f68c1929d595b3c53000efad5feffffff00870fc1994938032f8124e7f08a5f82fa99e759788514d3d1b4526a51393f707ced4dd04769190d4b92e79f835dc6a7171cad502b94219b5fade2bc2c05f13604", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000004547852e8332af4b86ac591d712704b673a8016556d6158725b28376b499d596602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000024547852e8332af4b86ac591d712704b673a8016556d6158725b28376b499d5960200000000000000040000000000000086f48eef4e497e5ade17206099817982efbb85f111ae73624a4a0722e3566e8d000efad5feffffff01d09d471a1a7559205a00c9195fe0f1c4fd44e7fc0194ddaf29fd0423053429ecacfd98539249d93fc712c8b2cf2734b099f89a285b18ea58287491aeb95d9080abb299d821dd399990ee3590ce3942608d1b6a5dd0099230c7c6aa3f8a328d0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000d421dfee10eed88cb73087e5f60e9d4b183ba664bb1a1a30c3303413c5a5d58fe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002d421dfee10eed88cb73087e5f60e9d4b183ba664bb1a1a30c3303413c5a5d58f04000000000000000600000000000000cc384ab5da997b1a92d07b3464d9a8bdaba72cc639fcbc0c4f40e7d6cbcddc5e000efad5feffffff01ebeedaa76dfff47c6c12f4bc1f090f8f5ebe455b0bf100f99323091696603d08610635368a52d06e27e2ff786cfd193cdbc0b814c87b6153a47e595ade04887c6972c8f2882d8b326c98884726364d2b90b8e7f15ab30151d81b20c7364ae304", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000003545df263b352b147b7c2c1d82c7ed05eeaf4368d784fb394eb59c96f5c912646033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000023545df263b352b147b7c2c1d82c7ed05eeaf4368d784fb394eb59c96f5c9126406000000000000000800000000000000f62d060de63b8c15df5567cd3cafe61023965f5a1ae93f0aac7cb11e43c6fae3000efad5feffffff03ebeedaa76dfff47c6c12f4bc1f090f8f5ebe455b0bf100f99323091696603d0892047356a249b963d8fc86b710ddededc951e6b0a884028b3e5615281f060b6786f48eef4e497e5ade17206099817982efbb85f111ae73624a4a0722e3566e8d4fd17c3f76610dbfac2e6ca92398f5f732a10bb9adbbb95fb118e8621584d45dcfd00385b85e1b6faa620f74a34d170054c20a46bd49e42b586ec4a8adb67804" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba130706080000000000000000000000807f612a01000000c0c1702a010000003000000000000000978e03039f9ff8f6b2c29ad49a7fffa7097fcac97aa6962707e0bd45ea630def0100000000000000c0c1702a010000000004802a0100000055000000000000005b1cb1b27b7d8a9d319c5ace66f7e3ec4b2e8f58044b65e865cc20aef4f7b19002000000000000000004802a0100000040468f2a010000003a00000000000000cd021cec4d599df22342bb3eab0777961385ba8789170d7022bfb14df82eb374030000000000000040468f2a0100000080889e2a010000005f00000000000000d74dadf7ce7c03f9262f457cb95748b51e0b0311c8b167361479a2a29c104293040000000000000080889e2a01000000c0caad2a010000004400000000000000c9eaacec424024b3f8f9b88e6e535d3ffc26978bf19617dd7c9e3f5c82f0ee190500000000000000c0caad2a01000000000dbd2a010000006900000000000000ea0cc05c6e1419d9054bd2e51c4d89db7886056b9f92bf293ba1e072c45f64790600000000000000000dbd2a01000000404fcc2a010000004e00000000000000c76feeee9c2ebe4902bda41dab741dcebb860dc8f11998495bc6bc94da646e0c0700000000000000404fcc2a010000008091db2a010000003300000000000000d08daccfd3b3ac20b3ba34c87c62c4d84c158fe89afe01c30fd355753faf4b1ef62d060de63b8c15df5567cd3cafe61023965f5a1ae93f0aac7cb11e43c6fae305000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e64547852e8332af4b86ac591d712704b673a8016556d6158725b28376b499d596d421dfee10eed88cb73087e5f60e9d4b183ba664bb1a1a30c3303413c5a5d58f3545df263b352b147b7c2c1d82c7ed05eeaf4368d784fb394eb59c96f5c9126438a3d2fb1cfc073e67b609937705dddba89e9c5d566a5cea894a79853a9adae30159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699b7d26131dd0032827e8a3c0ace55664e7d705d32e8fa3d7d621053d306802edd5f1369ba9b926f19001d7a863212afe4bd8b231ba5c8d2cec1a4325090255401bd038d3ef73dae19011ef3f7dae19f45c940a0f104a0575dd7e26c5c8eb8f900", + "parts": [ + { + "index": 0, + "bytes": "540002be95bcb5183d7ba2b9dc81877f187423b9198f8f4b889e23068ac9e417d4d95678bc0573fee9517f0b60aba9b0" + }, + { + "index": 1, + "bytes": "f7cafa4e862595927f77165558298ff297a83056e74d1115568707a302356eff3ed13dd07cdbc76a0d9000c4dd8e88b368c3b578a01863aea72cd24e436ddf545189d4710b7aad82064648c8145c8f19ce1d8e59a9" + }, + { + "index": 2, + "bytes": "652cdc9dbc2db2a67ea0fbc2907efa16d65dba9460a9b38061f14daa11bcf3ba0f87e148e24c6bf80b25d1e58412db2ff709db6b139ec99c831b" + }, + { + "index": 3, + "bytes": "2af2539c0af10376248736b69083e7a3b53f36a0aa87766b7b7adc22a6bfa2194dd168c55a92e411ee0442a085e808dad12b1b4c962517a7058447aca45a1452663ed864362e2d67207fadb20fb8f51d063e1c23579e593210fe84f3aea3ba" + }, + { + "index": 4, + "bytes": "91f9273eebfd2aad952d5234a60e583ca4f8f7d16db79bd16a8ae7bd761594edf6aa31afe77082e246f12f14a67beebc89cc2d74bd8f6328a98cae8b4077792d9b1df992" + }, + { + "index": 5, + "bytes": "6158745348ec9cd1088850ba20ae87d72a6112d157f3e0e756d58785da2f7a94b18693f43b8614cf05aabb98dc4e5543becb0d31751fc6a06f75fbf94c48a08b20130e9b8300b85de8b23c2e38296433e76b16ec8163d486fdfe9aa43e460d45e574470f4b0f5bee2b" + }, + { + "index": 6, + "bytes": "18223ead282dc0f7d0dd381d5121dff9ce6669e51b7bc2b230c759677bafb762c21c0390434752e5e59d5537da0a48d2d1f81ca83cdea25730b5811200001ebb8e758250a9ce1607f620427488d9" + }, + { + "index": 7, + "bytes": "4db90f8ab97a03113ee9e3c238017f800c3f3cc308c351454b4e472822a02bdae81beec983c12d7bc3eb45036b822c40775dad" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020800000000000000f62d060de63b8c15df5567cd3cafe61023965f5a1ae93f0aac7cb11e43c6fae344450da7aa9d241edfd49de1f90ab26f7c479c297ab128665c52b543cb9fe603ec16d2fc461afc504532328ed4524bc80b25e1effbf76ef0d5664166d39ddca83305", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000f5e540825f63de2f56c96facb05977838841737adafaf7d5b212a2236c8b0c8180faf8d9e95d0600040800000000000000f62d060de63b8c15df5567cd3cafe61023965f5a1ae93f0aac7cb11e43c6fae344452515654737b83fe5d119266d492389f5db458fe2229edde566b0d454519b9586e978141f0fd9cb26a2a3cdadd2a81c694b4c0c348f01656e565e31254780e10e" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a0000000094373db5dc692dec4057f487dd62231560e58c2f91dbee6ed24bbb2a76f6715873ed115e87b5c6fdbf24cc487a82a534b602c9bb1107bbf0cfb1393cfd4dbaa1dc6948e31d674849c2ff8050743a6002" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "4547852e8332af4b86ac591d712704b673a8016556d6158725b28376b499d596", + "d421dfee10eed88cb73087e5f60e9d4b183ba664bb1a1a30c3303413c5a5d58f", + "3545df263b352b147b7c2c1d82c7ed05eeaf4368d784fb394eb59c96f5c91264", + "38a3d2fb1cfc073e67b609937705dddba89e9c5d566a5cea894a79853a9adae3" + ], + "size": 8, + "root": "f62d060de63b8c15df5567cd3cafe61023965f5a1ae93f0aac7cb11e43c6fae3", + "verdicts": { + "single_take": "take_not_closed", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "manifest_not_committed", + "about": "a manifest and an upload whose chunk 2 is edited, under commitments of the chunk as captured (§9.4 single-take 5); complete fails the same way", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000005f216573985e6a76a6b14cee49c3e2e119f883d5335f82e8f8b613c6d323c36c000efad5feffffff001b6d50db408b12b7de017375364ca46ced368ba2f3d4dc8f7a29a0f9b08d38c6fee78b026fe7e1017f02094299ba534e8fb71d3535463d867b1e7c3cb150680c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000023ee3aa436aa93f99f28cf6e41761985524da4777091205561ea15de861f2160602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000223ee3aa436aa93f99f28cf6e41761985524da4777091205561ea15de861f216002000000000000000400000000000000aab0d8b9f6c35b6f33819cbb77d7f70c8d48925918ea756c0ee8d668dd6f1833000efad5feffffff01269fcce9b002078bc3d2c6de3256729e5742efb64dce7f88f6c931472dcedbeb0a22bb81092d74d90cd06b01cbfd6147bf8b51f3425febfbfbe291860b208c88875ce129f2b97db45488b5b921d71c821612ef3762862e25f149c1b692835a0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000006387e72b2a412f2b4b64b8bcf5271bcf4803e10c94b91a843c64d36edc8c8812e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000026387e72b2a412f2b4b64b8bcf5271bcf4803e10c94b91a843c64d36edc8c8812040000000000000006000000000000003494ac4f9b4649ec16411177a0ed623eb8057cadce4ae5401c60a20b71643c21000efad5feffffff010eeee2a1273c81bb20e14bcdda4858165e7b2650ffaacbf4682e6078f82fbc7012b61020e5d0220edfcefc3787fb84bc29273e4ea4f478b88adde6678e4ef5f5f909c970eec7588292f20e2bf080f46103f97c6b2e1ec23f574e051cb4d45400", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f504000000000000005710bd2d3e80cbab9aaebda399850630faf7353d582c74f6658bfece40e27fc26033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e04000000025710bd2d3e80cbab9aaebda399850630faf7353d582c74f6658bfece40e27fc20600000000000000080000000000000032f38d24662064bde7446ab28b12ad3146d926b501ca9cfb321ff1b92d8ff12d000efad5feffffff030eeee2a1273c81bb20e14bcdda4858165e7b2650ffaacbf4682e6078f82fbc705f8d25ec1e5843291c1bf42d2354fdc8960fc4ea49a1ec8050cb111c56e2bd3daab0d8b9f6c35b6f33819cbb77d7f70c8d48925918ea756c0ee8d668dd6f18332f39219d1971ad0ff3cd74cf2a5ac3d42d0511b4578392da04ba647b3a7f4b9fd07e1d0536ca7ae735d1285152acdf68b087e48afa1760f4072aef02c2a6410c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000001314a0d883214aea05b86f9f4ffbcd27563ddeceb7f09f9f946d20046c93b1a7803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000031314a0d883214aea05b86f9f4ffbcd27563ddeceb7f09f9f946d20046c93b1a708000000000000000a00000000000000cb9353a831f42a06376609bb4190ea51fe713d9a8bf90d871d50c2360e010ede000efad5feffffff0104c2f1102ac905c68b494b27c3cef0adff81cea5bdd48e4404943aac3df9c728beb31aa6e8c0ee3280d619ad3598a9d95f56202658494e957dd6c5dd31be574d5573e53ce20d43402e85ae3ded3c3a0cab3c7e25f2a5ee7c99890103f1cda50b" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000805088fd2db256ae6c5ef008488959fb51ec00c2c28242490cadd035fd0f1b380100000000000000c0c1702a010000000004802a0100000055000000000000003041aa0c962108ac2a74bcfb24e85a658c98f82d8e9f3a8d406768f8b9c6117502000000000000000004802a0100000040468f2a010000003a0000000000000035318b80d282c118723f8132a80b9d10ba9c31263ab1e78eadea2336f2d9c289030000000000000040468f2a0100000080889e2a010000005f00000000000000fee843c5df145d78479f5dab983b4c0dc6920e7c7f4247f8661301fccbb14c9f040000000000000080889e2a01000000c0caad2a010000004400000000000000a776cab2ef47455443cbece9bea16864fa4c2e25fc5c3841bee08cde536196220500000000000000c0caad2a01000000000dbd2a01000000690000000000000074061a451c6e646c62f91dbb09e954f7f0a03c6755924365890ec88627f4c0c00600000000000000000dbd2a01000000404fcc2a010000004e000000000000008fe769a540795ea5c4c684cc43fe477ca7f06d71cd6f2f5b8a99bab7576dbccd0700000000000000404fcc2a010000008091db2a0100000033000000000000001f45d9f3e00929ff519c8e2724d78253a6bb396df5c94466ce3313ca799ee25408000000000000008091db2a01000000c0d3ea2a010000005800000000000000365edce7c8fc8b6f8dbf457744c63894b6e06b7199b5f50d8108157efe4526bf0900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000068d0255ce2bc124bc1ca19c35c11c1ea1d29d1ea175d650fcbae43fba49e0f878cc4460acd15bbeac7ce4fd9efd144c163e77b989b92cbf5e98628aecfed09c706000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e623ee3aa436aa93f99f28cf6e41761985524da4777091205561ea15de861f21606387e72b2a412f2b4b64b8bcf5271bcf4803e10c94b91a843c64d36edc8c88125710bd2d3e80cbab9aaebda399850630faf7353d582c74f6658bfece40e27fc21314a0d883214aea05b86f9f4ffbcd27563ddeceb7f09f9f946d20046c93b1a763a2f313f7badfa13d7de2a7934d131d43722295a44b49092d6f8854b1ecced50159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699b33cf791ff379497476213fde4f337b22b53d25694b60f19d37d8528add0f794e9d7aec3636204183d5e0d207a79408f601cc32e1c6f3700ebf3aba9608a68b496c53fa5b54f08fef7119a03346b11dab6fc0eadea3de95a62f34624c44a9e04", + "parts": [ + { + "index": 0, + "bytes": "5c6b4dae6bf8a04dfa5f1a52119a9338482e81f0fb3c37d038dc4013e8f6190b687799bb910d07147612456155b291b1" + }, + { + "index": 1, + "bytes": "a96c3f5292ea30192a2cf8edfc4aac5f8409bd188fa412c3837c703b796e0bca096acb8698d47dce695b6de81cf4798cea7f117e3a0ded6c463b8af77bdc8c913989961fe7e6234a7e301d4d382f4c174fd8bd0f90" + }, + { + "index": 2, + "bytes": "4c633871addbdfae10c9008928c4d70eb0963a83aad27775066765fc0d317b9ffae8e6089c2b937e4f0746168d8664aaab329032a50b79117283" + }, + { + "index": 3, + "bytes": "88581a1522877d1f39405ae4b5f27680280fb0f6cec9ae0c36033e7bc4b1b45d51788192dcb101746f57a042c0be87d2376f26dbf5e4536ac1f2da40aacb2b0a2f0660b40a610b9413a6429e2ddb8c6104d8247a8c9849207c1f1d4a7bb5b7" + }, + { + "index": 4, + "bytes": "cfeab6b5ff1844c31217daff5d6905b3a698d9513e63233b781343e6df73c972bc7413224a7f559ef1b159cd2f217a29915ad200728b828e8a7e8195a221dc2b64a1b67b" + }, + { + "index": 5, + "bytes": "4e35fe28a7bc03442b37e934d5fe58eb7eec198bda6bb40d2c56f103bba7469d637501e170475c0aab140b47a755e1a177ef49709308974053c84750c4cda52617a51d6eedc558a1334b741fd5a5a29d645bb34c685dae55d56f6b58af7b99aed14145f2f04559c601" + }, + { + "index": 6, + "bytes": "a38c5f69352b30cb62354bf82f670acd1f9e804a6d305777742a9fa9efa7f985b0c0606658a21ef32562e5a2ded7e7ec979bf75d183040de9075c5fda81f4457320218ea9cb978534ca48041d66a" + }, + { + "index": 7, + "bytes": "916be45096d289f63667a3537d79559ece4454041c19910e0e6293af48507618876bbb619833e7c11176c4fac31e0dd0537060" + }, + { + "index": 8, + "bytes": "6e03c84a2ea8c696687e16bcb9a17e50b3605a4b3670c60f90e608cf254d69e433c944ed29d4834302016ac38df3c937df75ed5638ae3e91020453905ccf7a9ccf8a426035d2bc3cb88dc58c98e7219bc22da76b90cea4ff" + }, + { + "index": 9, + "bytes": "edd19c3ba0114f2c62c8a40de1cdd7ca51028524590686a8ea4f84b343bd457a31ca1c3047102afabff0db75f0f2118b769689efcda6edd0077a67d3c8" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a000000000000008cc4460acd15bbeac7ce4fd9efd144c163e77b989b92cbf5e98628aecfed09c74445c7dd4f95e1936dede8a0246f27d91df06e8068d2d19eb40814b94cce5e0e1fba46761ae44d88eb4cd13773fce6e9d064c7385e8f123b08f1ae7bcc158837070f", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000000737eda8c617ee3123e09759f233fe7bcdcee59e4e4dac15180df63d34f8d7fa80faf8d9e95d0600040a000000000000008cc4460acd15bbeac7ce4fd9efd144c163e77b989b92cbf5e98628aecfed09c7444503e0933e2dcf5e741d34971c2d05b8620d645f3afc9abc4e99b42aec78d07e98f81db1e888ab84718e89486670a518bf7cbe47179c8641b99c439935056f3d02" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000000a27d3ce920a148fc93ac1d5fa7a6193f3ee169e269077ea72c507e689e156be1557b8d0ec443f68bd6381a77a6394eb0f52c1ab65556eee62a5bbb16f41ddca4e4100859a5f8c59afcf827c281a0302" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "23ee3aa436aa93f99f28cf6e41761985524da4777091205561ea15de861f2160", + "6387e72b2a412f2b4b64b8bcf5271bcf4803e10c94b91a843c64d36edc8c8812", + "5710bd2d3e80cbab9aaebda399850630faf7353d582c74f6658bfece40e27fc2", + "1314a0d883214aea05b86f9f4ffbcd27563ddeceb7f09f9f946d20046c93b1a7", + "63a2f313f7badfa13d7de2a7934d131d43722295a44b49092d6f8854b1ecced5" + ], + "size": 10, + "root": "cb9353a831f42a06376609bb4190ea51fe713d9a8bf90d871d50c2360e010ede", + "verdicts": { + "single_take": "manifest_not_committed", + "aligned": "holds", + "complete": "manifest_not_committed", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "clock_unstable", + "about": "commitment 3 states an offset 600 ms from the opening commitment's, beyond the jitter (§9.4 single-take 6)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000008383728a9c2e05a6e87b3c3ff345326f7dfa81cab064ddd99c9c527ec6620a16000efad5feffffff006aa82dd32beaf1915935dedb1f78fee5d7e0e1442eba806c8d82a08e8e7d4c2e0c67dbfddf50caa2b632a791fd70993bd222b97b837c6601ed92b60e5764b103", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000000064e866ff47aaf04fb4f7cde6e63fc3aaa7149ddec4d7efac94f39b82e1df43602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000020064e866ff47aaf04fb4f7cde6e63fc3aaa7149ddec4d7efac94f39b82e1df43020000000000000004000000000000002cc19adb3aa3dbed537b19ff4218bd8aece2793142d285632e93e72c903e2e5b000efad5feffffff01a85bcff771f8b81fcf137bb5cb5314675a5ea46429f97e6bd335a14e759e28419ad8a9677b44b0dbaaf6c16eb58659a0642bb69ae96558c8900695b67aa9b5a5334a5e73ebd9ae5a6dbaee3b32c173524b535a0bcc4f40ac3a74a4d7cae5040b", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000a5e072d1767b15aca877a1711afc303fd8358324ea78025a1d15cb2ab6f6ec32e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002a5e072d1767b15aca877a1711afc303fd8358324ea78025a1d15cb2ab6f6ec3204000000000000000600000000000000e7e2f1fd2238181a8f7c7eb337b87a161e0671085f41c725fc9eafc022203cf5c03503d6feffffff015da6aefb99910b9cf8f1a3ecf4d9208fd72a544d23f68dcb34314447dd7bcc1431faa819371e80c8d53a5c301aa356f5545a9f3340a303aef340c69cdd37e8d8d605d9c8dcb0f45f9f2676b00e79369f38d7fd02d81412a12d9b83edca541c00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000c0c5285c3b7b12718b370d09d4855b4947db994718f41756c8bf0711468412a76033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002c0c5285c3b7b12718b370d09d4855b4947db994718f41756c8bf0711468412a706000000000000000800000000000000575f7f4285f4c1f27c5363595b93e5d82d35e3fcf1ca13b104a6397c6cd7e086000efad5feffffff035da6aefb99910b9cf8f1a3ecf4d9208fd72a544d23f68dcb34314447dd7bcc1412ed06b196a4c123f8c03c5fd5e8b3d96b93b0ad31e952ffd919b56aaeb5c4752cc19adb3aa3dbed537b19ff4218bd8aece2793142d285632e93e72c903e2e5b72929de5fd17788a4b603069496449642b7c41c8a68f9afe869f47215187f23bdedd9246f3d9e57f85f15605fbd5a13e4e1585999c39cac28f61e7ad56e7520a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000ecc4ed63fe1451cf280eec3c938a3531d1d52d19f7fdca64bbeb8fafe1f9da6a803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003ecc4ed63fe1451cf280eec3c938a3531d1d52d19f7fdca64bbeb8fafe1f9da6a08000000000000000a00000000000000680ecb79167911eac4bac73daba8e9d77cf1a34d4dc5e47b28bfa28284ceb3d3000efad5feffffff0102f48c9bb7a4c23c39b177adf1c4b75901dac76921736ff4437840bbce6666e36208fef1a513f4bfca70be894168c7d8200f5503de603dbc4614ec87e7e5ddae97451b9aa5529df546af6e6da7e158626b79dd03f7b0c597df247bf229071c09" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000052f4140dbd903b8c5ba4b6ff7e9e883f220e9d21a93370daf708980168b8c2570100000000000000c0c1702a010000000004802a010000005500000000000000eea6c8b6c36925275c7a94549889bde03314362471e9e107a7297df12143ac0c02000000000000000004802a0100000040468f2a010000003a00000000000000fc45b3253d0cdeb016a2d62fb93f9bba1b9ba0530256a194bbc3a239f301aaf2030000000000000040468f2a0100000080889e2a010000005f000000000000003cb492cc51838e7a47a17175aa9ee2668d97da0b5c4e060ecd2850639f6094d4040000000000000080889e2a01000000c0caad2a01000000440000000000000030b2b5746b4daefd2d2b6d6bee11c06b1a1960b2d02cbba34d3c55aab34b63d10500000000000000c0caad2a01000000000dbd2a010000006900000000000000ec72e724cfcb2351d0fc8eb9208ef41e5f23b68662c9cf2f07404bc59bcd545f0600000000000000000dbd2a01000000404fcc2a010000004e0000000000000083015b3f7cdadc950e3a50ec6385def424e84b37601dd810c270c23bc7ead8fc0700000000000000404fcc2a010000008091db2a0100000033000000000000009223cf1ed9ec2d96c6446adf7227927437743551f1e3c2a0fe6f23c5df4116f708000000000000008091db2a01000000c0d3ea2a0100000058000000000000006fdfe91ff460439db4fc4ad649995b2eb66eafcee3f0aaa3f0c9b57eb5a4272f0900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000021e24bbe0c431966f699023f2375dca8c74f52053d3ec94cea8f647600920f3d680ecb79167911eac4bac73daba8e9d77cf1a34d4dc5e47b28bfa28284ceb3d306000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e60064e866ff47aaf04fb4f7cde6e63fc3aaa7149ddec4d7efac94f39b82e1df43a5e072d1767b15aca877a1711afc303fd8358324ea78025a1d15cb2ab6f6ec32c0c5285c3b7b12718b370d09d4855b4947db994718f41756c8bf0711468412a7ecc4ed63fe1451cf280eec3c938a3531d1d52d19f7fdca64bbeb8fafe1f9da6a540f0e056a865eb98c256d8c120c76b3cc8c60b935113976e5810863a678a9600159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699449c668f823fbde91a54404ee85bbfda0bffc3c470dddc863cd052e4b09ea816206c4e206c4dbae38e81283dadd72a4d228a355bdee0ddbf93cd1ed01d64752e625038d393221ce0e230a1b4f696f9f32dab8035412f555f7a9b7e734872a30c", + "parts": [ + { + "index": 0, + "bytes": "0f7284e48ed6b3d545094d5aad0fa77cc7dff427b1486812f35c8a42ce6c58a2dabe33db41748fa5466c37e39eb8f538" + }, + { + "index": 1, + "bytes": "cce804b130e7d7aa443f38d8e57cb254c1b8b0e71e3b6b23b1b0e778bb13aa0f01098e1855b3290a3b55b57d5fd383bc7200372d68604aee0e26cd16c2f0afc9265b335ff7ba20a83d4a0e9d1cca19c51beedc1b54" + }, + { + "index": 2, + "bytes": "7117dd6823b129840f608f4d57b8180732a18bb5a6a2898b92584c34472afe46941be4e0ea41c41987043f2ac354697b9f751525e81b29befb52" + }, + { + "index": 3, + "bytes": "252fa9296adc45736780f788fd3f39deb79f4501c4db1ba83816939108f1a90ba82eda06a5594398c4e8883f14a49e2e1dac2e2071624fea6344a907319a864e1dd818e2051386365a3ea777bafa9af18cf24e39ca0c189b253a9955830b0e" + }, + { + "index": 4, + "bytes": "b0945bfca74cf49ad1201d2115ca11e6fb21c70347770e5fbf8deef28d8854bb76f54012f377dcce8a998925a0cfaf1cc4128604ef0a7ea9171ce7b45764ebb4f0e54483" + }, + { + "index": 5, + "bytes": "cff9f3e7a9da33f16181de52707d9aa2dc91f14f6d0414d84dba5b34e7b8b1323cba9d60956bb78d01deeff626d8b28ed5655ce2eda9c15716464bbc530f557d5f3071bb63e830f86fc95785fd6a92e25aea63b0c5ad9686e1d46b5a3acbade750be491fc7e8fd09b7" + }, + { + "index": 6, + "bytes": "0ca7ee430e844e2f6b11b8e40be1e77b4c6781626797781fd833777f0320b1f3ca6416a94f9aeb919cf2d9f68d684438e7a4e07b2f98eb01ae219833c0490526b67f48d3b8d219bdefafe8fdb5ba" + }, + { + "index": 7, + "bytes": "64476e13aad365e7a123dc081ed7142c79fe259948d785f0a6336eba11fc1ecb8a3d1c33587bc6d9d1da66bd4bda342a0deb01" + }, + { + "index": 8, + "bytes": "26438f9f81558dd4cad82e91265aa09e81e732d71335076c458e6323fb602573839e5ca56d963c8fb568bcb796be05f68121d4e6aaa60796e6d8d5be32a31d170fabf839a3e54718bf29c3d8fe00f73df1564e1f991c0198" + }, + { + "index": 9, + "bytes": "4caf665fb94798a097f39925d4e99ae8228d22859be567d07192da45928ede885a335b4a7e0fb8217581c15a7f5a54988c7103f94802460965261ae7c1" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000680ecb79167911eac4bac73daba8e9d77cf1a34d4dc5e47b28bfa28284ceb3d344451c447d042bb3978c6413c100c838fb4964e34bf972df231e47ec23b1acc193675a0d3019443cbab87349d7314a551eae0eff2aff2869aa49abcf6dc33c5c3605", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000c31b98298480901722bf03e35efe3b64d71792888e12b0650c8f15f6e815503780faf8d9e95d0600040a00000000000000680ecb79167911eac4bac73daba8e9d77cf1a34d4dc5e47b28bfa28284ceb3d3444548779d39254af75096c6bd471e9254949b96c0ef1dac927da5c7da9b7aa754241b29027d77fb9463b2ddee5a6728cd908a890f3391c00279c125133c186bef08" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000002261997a2ee79ede9163e657681800a6695a07a28614558078b079c1a23e8b5571a612e7da7a5e9fc1317f365750c04866e4879fb71c13cc6e466840744b2d65126d8935610554cebacd429adb43fc04" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "0064e866ff47aaf04fb4f7cde6e63fc3aaa7149ddec4d7efac94f39b82e1df43", + "a5e072d1767b15aca877a1711afc303fd8358324ea78025a1d15cb2ab6f6ec32", + "c0c5285c3b7b12718b370d09d4855b4947db994718f41756c8bf0711468412a7", + "ecc4ed63fe1451cf280eec3c938a3531d1d52d19f7fdca64bbeb8fafe1f9da6a", + "540f0e056a865eb98c256d8c120c76b3cc8c60b935113976e5810863a678a960" + ], + "size": 10, + "root": "680ecb79167911eac4bac73daba8e9d77cf1a34d4dc5e47b28bfa28284ceb3d3", + "verdicts": { + "single_take": "clock_unstable", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "capture_discontinuous", + "about": "chunk 5 begins 200 ms after chunk 4 ends: a pause in the capture (§9.4 single-take 7)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000003c25b060ca975b2d8d383fbc1d7e568210250c4fed35522a25c143051bf5f6f4000efad5feffffff006f9ba2255780b90f0b96525e7082ab5a68b5517afadbfc87bd7e3b203077801bb185c1db56dca2d9b9856e177912abf77a196dc56776c904135d7102c93a470a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000067d86cce8583bd5b516ea9708d7cde33ed4265ac119904efe97da57a5d4a2d01602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000267d86cce8583bd5b516ea9708d7cde33ed4265ac119904efe97da57a5d4a2d01020000000000000004000000000000005667ad1e0c33254228105f1e657b385779c264fa6ba82f01b87f63ac8f235c22000efad5feffffff01a2f24d87e124004685912c569c2597e1d51cc6b13705a24ddb2c99e3b492d70e98a95596f091b1cac14e9ad2736155e708304e8ddf5f1f123cb8d174018eac3076622160dbf5ae19a25f911ed0d22455452a39a28b326d0222062845611bff0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000002810c8775c7556d28d01a11748ebd8b5636c1a576f44d6a04c099cc5721a009fe0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000022810c8775c7556d28d01a11748ebd8b5636c1a576f44d6a04c099cc5721a009f0400000000000000060000000000000042267f855938c1aa995c78fc6bf621a58d57bd2300f95a80615c2d9c2daaf886000efad5feffffff01da62dd637e4ec62f7df5918d5b87256a8e055c7ebe2149bcf3a42a20b08175378265fc1e500e776459c80bde430749d8dcea5c2a12571b1911183b698046ad04689f79c93b1fb3ea33d1c57bc0b52d04d4d8411382dc4ea1f88307926b023b03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000aedb1963fa438980de25f3c08dd25a025be1c17ffb9d80e15ffeb38f739c2c2f6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002aedb1963fa438980de25f3c08dd25a025be1c17ffb9d80e15ffeb38f739c2c2f0600000000000000080000000000000028992463ae5083ef631dfec8d69a172fc04e9c44174b71cc4f8f5af9b3a000c5000efad5feffffff03da62dd637e4ec62f7df5918d5b87256a8e055c7ebe2149bcf3a42a20b0817537847cad27998885c7298247ac06aba82f55226967840a44cad4c7e9c5bd06e44d5667ad1e0c33254228105f1e657b385779c264fa6ba82f01b87f63ac8f235c2240e5d2e8cb392dc4c74faa050480546db612caa5317a3c84f2e40bba1c7f809ae7ff3c06b4f681853ca475a39a8fd66dcc2872401391d01736d9a8c940be100e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000000d650426e39b8e5f0d4a8a03d1ea58a59e8ae3302ba8c3587af8138379d2315b803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000030d650426e39b8e5f0d4a8a03d1ea58a59e8ae3302ba8c3587af8138379d2315b08000000000000000a00000000000000c0014ed864f4034e46b8b1d509eac28ca0c064120b32f087e40b55bf805715eb000efad5feffffff010edc94ec749e071da13d89acba5e2d5954e6427c30878f5b715481bf2f1a36c671bb80b2d43b838bfd08bbb9f479217e6b33ae790115a23a61826a990030f58db34f9674f0b901f9b11aabb07b7c978b5fcaa9a3351aa0764a74424a0d6d900a" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a0100000030000000000000001fc9c3fe6eb15add14a694e7eb179d9a439c5c12e0e1288c8234a20a828417450100000000000000c0c1702a010000000004802a010000005500000000000000c248cb851dfc7ec6378d5f5d6abe4387b51df54c80d1c28bf872e36fa3b49a7f02000000000000000004802a0100000040468f2a010000003a000000000000000c5fd13d5c57ffea2613cf2fcd42272b822fd9a11bc7852c9aa6d00ffb13871a030000000000000040468f2a0100000080889e2a010000005f00000000000000c41d6c5fec49d24c259e857b18fa498895f4b290d24c35e8c00516c3da0d17c8040000000000000080889e2a01000000c0caad2a01000000440000000000000066389f896b5f29639ff3ebd0a99d21fa437ee86709d34b5e4958d071193d1d88050000000000000000d8b02a01000000000dbd2a010000006900000000000000e5424e4b68c7e94e65be59a435c8e1fac93c264fe34daaecd67f9a48716361550600000000000000000dbd2a01000000404fcc2a010000004e000000000000007df510a2d00aa8e2a20c4e84ab8e9d868f303c041c88a1da88b8cd9eb41f3d7b0700000000000000404fcc2a010000008091db2a010000003300000000000000776ffefac6aff20ced495187fb6ef8152b7e816cd2222b4b8be8f8ba9aa4e40508000000000000008091db2a01000000c0d3ea2a010000005800000000000000eaaf791033976336884120b1ac99c8b56be360d230ddf507f0c18228f03b0bce0900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000001a8e087f18a1b35dd09aa9e10f6d66fc310df45526733159818fa313118cf46c0014ed864f4034e46b8b1d509eac28ca0c064120b32f087e40b55bf805715eb06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e667d86cce8583bd5b516ea9708d7cde33ed4265ac119904efe97da57a5d4a2d012810c8775c7556d28d01a11748ebd8b5636c1a576f44d6a04c099cc5721a009faedb1963fa438980de25f3c08dd25a025be1c17ffb9d80e15ffeb38f739c2c2f0d650426e39b8e5f0d4a8a03d1ea58a59e8ae3302ba8c3587af8138379d2315b5c692b3d202f41a1e7eda539e71ec85d2cdadd0e4ad01edfb69eb89117f70a5e0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a39e6519678160193d9fd62bea896ebe9856f041e4201a9a54ba1c9a8c37fa32fcf876494f9e8762e051beb146fe249139fa4f1268e0e763f2d3b0ea058af0aa0e635f3ced8f8f65cf97bec3709e2b278eedba159fe9f3e5ef799661df94d707", + "parts": [ + { + "index": 0, + "bytes": "54e3df3f3a6f0b463161f0d5b602bef55e715bacb6899efffdc4be9b7b4d0a0e275d123acb5c5454371140eadfc1d013" + }, + { + "index": 1, + "bytes": "5d8f111c2d1472729fa9d8e33b8f74a1fab954bc5de072832e0cbd965338d5fd3bd614a3cf0a7569f78ed83c0a16652a1791900c8f903d95112bca379f0121ea29fb36668763af6bedcf9760401c53f0274bfb2db4" + }, + { + "index": 2, + "bytes": "3fa82308f7f44ec77871f94f7feb4d9fc7f08c640b06bdd86d9c30ccbdbcf1c314e1eb506865c892fa2661ebf535f730ac793a78d8d1f4e17af1" + }, + { + "index": 3, + "bytes": "ce8f88adef65ebb94328b25f29d81bdee170073e7d14c0d5d54384ff7f7ce8cf0fe0dc7a3fecaa8a57ad8f39f231b096eef97c9f694bc75c5f872b3b4ec2e48f1790665f1375b44e22d97c7fc5a815e0f0c1a4e01ce6bd0ca81b89ad123e3c" + }, + { + "index": 4, + "bytes": "86c0e3f5873fd38e5d6ff16aae9d5927d6e200fb0220228039650153256675d3c059de360f7ceb13e5415fc3c84c8dbcc2c8314b2d9e07d076399d392e7b171f6670173a" + }, + { + "index": 5, + "bytes": "db1477201f1670e0a4e4dd1e3c0357fc027fa4fb78c398a2618c2abf8125478e37b4a2f90b6362efb4d82037bc184ce78a9fb2cd7c348342763ea78fbe286813173826273cb0e3b1eb190a04521bb65864666d3d74ec7eaee1d1779afb9d2e0881d50319a7bb03b28e" + }, + { + "index": 6, + "bytes": "a59442170d02f6901185309ecc50e27d871ae54bf41aa221a93e64ca842ffccb82ec5c7e14018f2aeeb920c678a5990fb97b06c327dc4214cb25f2bc141517f97ce4a569d00a8446fba0e718469e" + }, + { + "index": 7, + "bytes": "2067f81d16269826ffcb42cf1aa0d5d0c159c2fd8cfa4042a39e4473883afad84cb3c567dd641aab55a45447d427abb04d0d00" + }, + { + "index": 8, + "bytes": "1ad70652a3b6b000b39b6e0ae45c415119c46fdf0a7d6823a5133fb152bbe198671ebda84f68d112674851b8ba5b2b863b8cc8ad08ac801109ecd32064077b98b0af4a0ea6be0583f80c7747198d3bb7910527ef8ad3d76a" + }, + { + "index": 9, + "bytes": "753f128a2cb24d5cd235ae0276f91f0b7f1b58a1c72578915398530f38042671a8a7fb801d0e60d4264de1c4846ea0877859f2f227de33e51310d683af" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000c0014ed864f4034e46b8b1d509eac28ca0c064120b32f087e40b55bf805715eb44453904ea93c94cc2516d29765e5dd93b6305573aa23af2d2bc215b4f2384d57f3a74a5caa7758541408e39c5db449d3966c7d344de8ed5d1852c54c5534618fd05", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000001fa6b8a9feb22cf987e1f2625eb8443e9bd908e178f32cd44bd6c44351489c7d80faf8d9e95d0600040a00000000000000c0014ed864f4034e46b8b1d509eac28ca0c064120b32f087e40b55bf805715eb4445c991702762d3412436a23f05b7c7c3503c487d6a248046565a172728672813c55b3f5d9f9ccc5bb00f5e3ab0be2db705a44361bf5fb5b662fd61baa82db1aa0e" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000c726de5406ac7ceafedbf2affbc1c618d5b92a47fb7c69dec9b68405108e0e40a68850e3429e29dc942bfbde7bee36bf3044f6d3f919ddb7eeee62623d240a928caf75397a99087dd5bfed38db8b1409" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "67d86cce8583bd5b516ea9708d7cde33ed4265ac119904efe97da57a5d4a2d01", + "2810c8775c7556d28d01a11748ebd8b5636c1a576f44d6a04c099cc5721a009f", + "aedb1963fa438980de25f3c08dd25a025be1c17ffb9d80e15ffeb38f739c2c2f", + "0d650426e39b8e5f0d4a8a03d1ea58a59e8ae3302ba8c3587af8138379d2315b", + "5c692b3d202f41a1e7eda539e71ec85d2cdadd0e4ad01edfb69eb89117f70a5e" + ], + "size": 10, + "root": "c0014ed864f4034e46b8b1d509eac28ca0c064120b32f087e40b55bf805715eb", + "verdicts": { + "single_take": "capture_discontinuous", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "chunk_too_long", + "about": "chunk 3 spans 2.5 s of capture, beyond the commit interval (§9.4 single-take 8)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000341c06bfcafb77745afbdf9a29464ecfe3847aa38b09067f062153c4b076845e000efad5feffffff00810f10ead7733885359c151d8cb78948dcad9b22e39301ba24e08d727e0c7642dbd682a3f04b2ab843284d45dfe7b742df0a0d2bfa94a846b7199b8b55099f09", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000f7ee4c1d75c34a02aa61477a6111769a37e0b35f660e3150bd79a60d935796ab602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002f7ee4c1d75c34a02aa61477a6111769a37e0b35f660e3150bd79a60d935796ab0200000000000000030000000000000028399a831159c997df83c1c9093216580ea54ae60d9f60e7be8f91329c6cda45000efad5feffffff01a124c18972a4771f11e85bab33f48631fe6b33e927e12570e127d6cb9be52f03ead9b2475b1f7bf3f775dcdc447b2168381e2328fde482ed4015cff99980429dfb7e76ffbcd2060651a3ea12c6a59e0762528e0f4c33e6c654423bdf16c44f0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000001e3c60395b8b63a363fb17c9b62649ae1f418f4eebd6805fc350bc7b2e185f55e0aebb0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000021e3c60395b8b63a363fb17c9b62649ae1f418f4eebd6805fc350bc7b2e185f5503000000000000000400000000000000388d74dad7f805b32e77aca18e5158c02b28e12194078420476d09d9d81c4beb000efad5feffffff03a124c18972a4771f11e85bab33f48631fe6b33e927e12570e127d6cb9be52f03da218be93d814e3a3ed7f5039ba16bb9425825fc965416ec40e1615deef771ed341c06bfcafb77745afbdf9a29464ecfe3847aa38b09067f062153c4b076845e2712fa477bf5d0cd7e14f03093a202cfb019615c9f02ed3eecdb1a176a63f664454460955770814ee6f516f9b0b993cc36cebd80b6d2dd42900c1c3787397101", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000d5b83198f7f7388a88e55e4efe72016b868f9fec41dc4e21cccf99f699692bfd6033da0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002d5b83198f7f7388a88e55e4efe72016b868f9fec41dc4e21cccf99f699692bfd0400000000000000060000000000000075ee7ae177ef83fd778487b9f5ec906b8e1b4ffc46d91cb32e080909c48f2cbd000efad5feffffff0195db638adeab9662c93842bd4cd8338ea17df7e3b98e8d686547ff5087726489c416a53498301de3b498e949152e17d2af59475c9c048b7371b661b81fc61d9cca99377a8dd9d3e6a4d907a513f001c6616438ddc404089e76935c469b8b160d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000d1a2b628512933b76ac973140d0bee12f2e715355bde1297e6d762fc47285535803efa0000000000000cfe0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003d1a2b628512933b76ac973140d0bee12f2e715355bde1297e6d762fc472855350600000000000000090000000000000021b08ff801f8a3269af66cd8f7ad1dfcb61dca047441e26d8217edb3043b9129000efad5feffffff0495db638adeab9662c93842bd4cd8338ea17df7e3b98e8d686547ff508772648980ea0bb3682958e71f804803c6bef9fdb020c42a9438df9ce2ddcdea0476415d388d74dad7f805b32e77aca18e5158c02b28e12194078420476d09d9d81c4bebfe7628db3460e380829ee765ef3d324948e6cc2f77e027d809f1f6e49a383f62c334710740626b59e30c5e63e1dcb9540e680e1271e10a8d6511b9bc260b2ab3b86f29ff61edbf800ca56bb4d400a9cabc0c349cb0a6398930203100b90e2a02" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba130706090000000000000000000000807f612a01000000c0c1702a0100000030000000000000006605a11fd6e270c88823cf1efc471f98d6bd6249b153a79d7bd51cdc106591200100000000000000c0c1702a010000000004802a010000005500000000000000d2ef128a82f04d1dbe2c3ef1ca13244b7341f2de317e803dcc0984f86c37144702000000000000000004802a0100000040468f2a010000003a000000000000005fe9a9ebd5bd880c73602c7411f1846e4f7ce26024a604a13c58a4d444198e93030000000000000040468f2a01000000e06bb52a010000005f00000000000000bf4acf64257ed99c49e6cd560e5e634f17ad0041e9a957fd937d7428e58bcefb0400000000000000e06bb52a0100000020aec42a010000004400000000000000d193d679df6e1f4b9d8de1385cb83b34798914600364576b6920d6be7111c773050000000000000020aec42a0100000060f0d32a0100000069000000000000004b4ccd466a74d95890afb8c39972b624bfee4a390b561e4e8a56c99803db26d7060000000000000060f0d32a01000000a032e32a010000004e0000000000000042010aee2c28dc1233184666cd0b5ec7733e0dac43b80d17f6c8525ac75755f30700000000000000a032e32a01000000e074f22a010000003300000000000000291870d503674c3c5ddcb3f73bfd3b7a96bc9420947606e9aae3eb7632087b390800000000000000e074f22a010000000016fa2a010000005800000000000000e86f663a14d8ef77b203677c72d26ad43e353034a993411e1135934c818f60d621b08ff801f8a3269af66cd8f7ad1dfcb61dca047441e26d8217edb3043b912906000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6f7ee4c1d75c34a02aa61477a6111769a37e0b35f660e3150bd79a60d935796ab1e3c60395b8b63a363fb17c9b62649ae1f418f4eebd6805fc350bc7b2e185f55d5b83198f7f7388a88e55e4efe72016b868f9fec41dc4e21cccf99f699692bfdd1a2b628512933b76ac973140d0bee12f2e715355bde1297e6d762fc47285535e8c0d527f28b421eb5e8b236ac1910f5b71c2883272a8090a5819227a3e3b70e0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369956480dc01e0e90f8811f9030851bd26df2e606070bb79003e1579b5759097e135e955ff6560dee9c30e6edd0a2f531a4aba20418b114bbed14eacbc200994619b2d1b3eabdc28baeb3b4bea763757920b33b2ed4985d1d7ccc3ebbd3680d0608", + "parts": [ + { + "index": 0, + "bytes": "02576560d5053551dd4f30d8342d069b97a34723628a460c7fab2e7263dfe163bda32b587e6ec834799a336203d97ac7" + }, + { + "index": 1, + "bytes": "c61213f1f9266f17d1b55ff722818283e30490889e03db89757a8f14b32d82c2b5756b87c5fe4c86fbf0c3e11c98ce08975503b7e42529aa1fb399105a4f48bd4572546cd24a424c86dc34b3ba861d2ba7f45ee80e" + }, + { + "index": 2, + "bytes": "02ec861eff5c9216495711105ce04a0f1435cd4a8d94a2aa5f86045191d7d854c2658d9091bb0b38df1f88bf94f142309d81cf60bce50bf1f8be" + }, + { + "index": 3, + "bytes": "7ff2198541ceb3cbdc34a1e69fa13ca6507907d4f5c0cd3fc1c6fda10f15c91895af384253c63f1ae45a5ceed341971ae744eb20e250f43de3da5b03c47ca71069e4a7b8fbd3663d4cacc1006c44b74d205ffa9005c4d913ce8072d78b7dfb" + }, + { + "index": 4, + "bytes": "6f2bb2327fff94182c7958bc7d4a439262bfc767b1bcff375e8723be4785139ebc891b7fd04560cde036cd1364f4ef26a6fd6f74d49263dcaa2f4e80153a2d43737df19c" + }, + { + "index": 5, + "bytes": "dac163a3d85e9a60789172fd8b6fe47bea63e0666aedd322e00acb09f02060a3a9e059b0c949325f464c956c51c567c74f64a241124386c10709e355d0afc6797f6f93f3b3229a6f7dccb1ac13ec4747365a7aad25691901fc7ac2fde3f839afbfd8128174c03c082a" + }, + { + "index": 6, + "bytes": "b07f490453304c518ed16decf4dbba6f05e59fe071e5847efcdd0a70e741ad5db67e1855a9ce591a87499466078e9f38aaea4148118e3763ffef99699e18d2396ae1c45850c8376b4edd342a5104" + }, + { + "index": 7, + "bytes": "9a1584c80bf06d00a859243995de26995275cc19b0393b4fc2eff7424c565fde1bf995dabe42f771abf306e6bce17c9acdca42" + }, + { + "index": 8, + "bytes": "ffcab1e07071ab77d8bbff3212c58bc5144adff9c4c3108a826858953ecc2ca1dafdeac8c96322a0cb2aa46bc0e1c6a3e844787a76910b03e0088aeb1738be6f9dbbdd5567aa51459eac66b605f6b7b4abe3a0cc30081424" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d060002090000000000000021b08ff801f8a3269af66cd8f7ad1dfcb61dca047441e26d8217edb3043b9129444595578177dd13259e931f99ea7d7bad92f1ced54353364a41ce2c20d8fe39efbcf35eb7d91d31b8f7eff7bdd2531e380d517bc22adcd3ec7d02f0a09daee27c0b", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000000000000a06b57f0c63404a14307056caad73a46c080d15f1a184cb1e39a80c03e324ae680faf8d9e95d060004090000000000000021b08ff801f8a3269af66cd8f7ad1dfcb61dca047441e26d8217edb3043b9129444598fd5a8bd5aab51d62f29c153218741dbf0e6255346edcfb8fb6347099cebe2896f0780d01f1248d92407b4312d6eefd48782e11729dc5b230b0a83cbcb9bb04" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000c7050d5ef3038000e56b0b0db3ea4bfa67d6f5403f62a930aefad54b2f1cb0990dbf43e2707eb0f84c46f4dcee95f5baa37130bbf9ad069d4081a55b96f2d34258fb9c842edb162e8d0ee48d43a6080b" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "f7ee4c1d75c34a02aa61477a6111769a37e0b35f660e3150bd79a60d935796ab", + "1e3c60395b8b63a363fb17c9b62649ae1f418f4eebd6805fc350bc7b2e185f55", + "d5b83198f7f7388a88e55e4efe72016b868f9fec41dc4e21cccf99f699692bfd", + "d1a2b628512933b76ac973140d0bee12f2e715355bde1297e6d762fc47285535", + "e8c0d527f28b421eb5e8b236ac1910f5b71c2883272a8090a5819227a3e3b70e" + ], + "size": 9, + "root": "21b08ff801f8a3269af66cd8f7ad1dfcb61dca047441e26d8217edb3043b9129", + "verdicts": { + "single_take": "chunk_too_long", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 5, + "into_chunk": 500000, + "into_master": 7000000 + } + ] + }, + { + "name": "commit_early", + "about": "commitment 2 commits chunk 4, whose capture ends 700 ms after it, beyond the jitter (§9.4 single-take 9)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000b9c48d0f25427effa0de240065cf0d00e8c625d5ab0c7c59f4d41747358b7299000efad5feffffff00a13cc25d2f3f254db08bf1f25cc68f0a6a63aff975ca4faca70fcd39dbcb05d42d714352056277d21d326caa0af24166b610900af04e5bee0138b7b328272305", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000ce20ac52283bdfb914d6e8da70daef048e87f0b3d0e4d9f77a84220479a5b677602a9d0000000000000cbe0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002ce20ac52283bdfb914d6e8da70daef048e87f0b3d0e4d9f77a84220479a5b67702000000000000000500000000000000603ca612693f2abad31e6bacb31139d6196d38f8a7195e32a53991446fb37f74000efad5feffffff0287bf537f1cc75f438bdf71a3d387ec2c9b1ffe0d781a8f358bfd4c0623692ea7a768f30431b0a851770f8fb8f1c180bef9d1a2699223d07c450fe03ff1d7051284be621eba9ccb3c1f6a76230513b19f8b578a97c29a69ceda54998478360d4521078067bc0227ee2356e5a58643d1aaeb07b86a1860f331ec8bc7ac5ea49403", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000005773fc8d7c223a9153cd2d98de786ed74654559b75907751523732a50758f43ce0aebb0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000025773fc8d7c223a9153cd2d98de786ed74654559b75907751523732a50758f43c05000000000000000600000000000000bce13223346f2ff8984e52d0a8224db336fb5808525f9be032c81dfbf2dfe0a2000efad5feffffff03a768f30431b0a851770f8fb8f1c180bef9d1a2699223d07c450fe03ff1d70512648c4aa99e1e841ef29f347cc9c280f6ebd265ba80585a33ba138cc96b30cc7799a6c39cfcffbe1df772054aa4940138a191960724d3b7dcf720f58c7a954e2143d0f6df10271d740e7c542455f81f24e8648679c63f4db6c7b01fa12ab9708cb20a03fd4ba0e154c4ae4732a4660e53da3adb67e4748788ab28f0abfaa8330f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000fc8b5f389ed60ddf9db7b8fc9a47cdcfb08a18b961d085c9926af9e080971c486033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002fc8b5f389ed60ddf9db7b8fc9a47cdcfb08a18b961d085c9926af9e080971c4806000000000000000800000000000000b38ee769af2a74494aba90110d44b85ee2fc6508feb0ae5bfe2b2f23c63e082d000efad5feffffff039f09ee837b41aeaafaff44be41e2bcec8e27744bdb8512ff40ccaf10bf4b655e60a6221e4e65872f1ab3234143da2db16bc766a5aacf23f6d4e632cb878a63fd99a6c39cfcffbe1df772054aa4940138a191960724d3b7dcf720f58c7a954e2193c6b9bc3e575fb7b0858a9c1420fd3603b340612df0e3146982b18561b5ccc77b0bd6a64668e69b29bcd2784dbf68c48feb38d3b6e872f26ea362209bafd107", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50500000000000000a9f55613b18252b260fcada171765727ad51fad3f7070de884fccf2bb9bada18803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0500000003a9f55613b18252b260fcada171765727ad51fad3f7070de884fccf2bb9bada1808000000000000000a00000000000000e819ce5ae27b95126df7bc7a694e141bcbb464944378ad2ff4a92e1bfde0b1ac000efad5feffffff01835934468c0352143e43232a03a62907df27686a4447abe533c36a2545660047751fcff5bd1d6cb92a05704a6923d341bdf3bf146abd8e185c42e6d027853bcc9d3bba057474f03b47f08f8ba9896238f70646246022fad723372d3d4362f808" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000018b90513cf52b806e1935b621040c4f7ec572f02ab7a14ce65d02e738b7534e70100000000000000c0c1702a010000000004802a0100000055000000000000005a07762983e5a496686325b7ddaaa9888809634777876f13771b285cde092b0602000000000000000004802a0100000040468f2a010000003a00000000000000c14b2b26d9925bc279f12d7282212f1b747e493e4a0f87ed313ae7ab2a0f364c030000000000000040468f2a0100000080889e2a010000005f000000000000009c69bfd487a4a6c87b54f75a260cce3452bcb2ea268331a22362266064a3085a040000000000000080889e2a01000000c0caad2a0100000044000000000000006988afc111642896af72a8a2d4334d2c394655631622c18ee0006c8be0519e840500000000000000c0caad2a01000000000dbd2a0100000069000000000000000ef66d4b63006ebade007090d9bab385e86aefad155535cfaf60e0e08023f6000600000000000000000dbd2a01000000404fcc2a010000004e000000000000001b75768ac6dc49b2859948b78ec404cd8d019abb51f5ff3a8926b0e78689350a0700000000000000404fcc2a010000008091db2a01000000330000000000000015e051030638f8e29fcf8b6289eabf80ecbb713ccff0769ad3333a2fe12662de08000000000000008091db2a01000000c0d3ea2a010000005800000000000000823508d5ed62cbcf3aa2f021fa767529c01aa45a3dbb28ee704e573cb704dda00900000000000000c0d3ea2a010000000016fa2a010000003d0000000000000016996feac16a737d279b251af8ed832a0586c6eee104c20d64e3755065831b53e819ce5ae27b95126df7bc7a694e141bcbb464944378ad2ff4a92e1bfde0b1ac06000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6ce20ac52283bdfb914d6e8da70daef048e87f0b3d0e4d9f77a84220479a5b6775773fc8d7c223a9153cd2d98de786ed74654559b75907751523732a50758f43cfc8b5f389ed60ddf9db7b8fc9a47cdcfb08a18b961d085c9926af9e080971c48a9f55613b18252b260fcada171765727ad51fad3f7070de884fccf2bb9bada18ff001cba7a20a02d8b990ab0a74b4215158da8632f82bb2741156aa9e54615b90159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699208089921128e5b60e0c2d0decca0b7f979b784822751476ddd87669e2b8e29ab9c6e0b08f51abea6e019330df224fe07fe7bada4d30dc8e4b5b9df36f564e0e83f02bcac70c76e2c335e7d03e59ba20fd4b7796e649ea7d645729bbf4c1b60a", + "parts": [ + { + "index": 0, + "bytes": "62dcda582f371c5c77859f5090d04917b390134f5eb695d7d761f49f2d57ce03f645f0ba497ff97c371fbf9430ca7b90" + }, + { + "index": 1, + "bytes": "2621d323677bde7d26fc0dcae276193a7cd42698f9682ed89eb730e57668c7072536d04cfd6a9f135c6626e789e1c30555ffb920a6f5305815b7d2148b410534bc163fd80885176df890cb7e46d52ba348383eae29" + }, + { + "index": 2, + "bytes": "39f067678685c4ec0209dfc4e592ab32d1b2f489a485c26bb27cf156220478b92dd5974ee1d12b9d7026923c362124125419399fbb85400febcc" + }, + { + "index": 3, + "bytes": "4fcd6cfd52e6d5e1150f21c3bc89a5d9d40388dc4efe7f02a2f8c0febd40a29135495370e079ffba1f335f9d6cb1dcc3fe1762bd07b97945d75921ccec04f99c7b76a8a46f18aa7fca778817d69ec7c81670edfdb659a2aecee64969d80d7c" + }, + { + "index": 4, + "bytes": "d412d83efaeb58ef41b29aafeaaf88b05a22f7ec9521172b2025e61fe08708d68baacb7a069694d2697c233c2e14b74d7f616ff301b2dc66be35919f4fcf092a559a00c8" + }, + { + "index": 5, + "bytes": "108f1bd1353308b41c9e58e4b808eceb4389bdc64dea39159031797d64bece381e98a653bca5cd16929170b4136a7fc33696a118cc170f0600edfd6f4255696cc20c419311778df96126adf0b1bc01765d0e21f7fd966ca3bbeb95e496bd046b0c7a66d601e9e30ce8" + }, + { + "index": 6, + "bytes": "6f18aef804812035f9509305e65891fca40f140088a6f39688cc6f097c63e2134c306be9d806cabce54b892399eb828e3b3d4077f215c92842ac3b40eba46a018313147cc60cd6dbc60270880197" + }, + { + "index": 7, + "bytes": "cb9abdfe05f7e221d6948b727305421b7ec40f13f666cabeb51e7fe5296444927eed8b7c845527c47ae4537d23251826fd164e" + }, + { + "index": 8, + "bytes": "2d927913658a98ea2b65653bc39c6779a34a26e0f409dba4134c631998da88b25b2209cadada905d9817ee28743b693aa38412f2acc2f80947ef4a7899dc75c698e50187f65cf04edcfa928d0379eb936306857c6bed9bfc" + }, + { + "index": 9, + "bytes": "2987c7b698ceea92e6e4fb0cce92d95b2e797b98651e39fa22497ca04f9a2fc52919cef2c8f838ec7566b99b135f862dcacbb209db87a669797d260dd7" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000e819ce5ae27b95126df7bc7a694e141bcbb464944378ad2ff4a92e1bfde0b1ac4445a9b4fb1cf18bda68a0272f8f90434e63da74c546308500aff179366acebb58f2c772a361d9eec442b6eb7f143c99e4c2101f8b2014288820a83c61e130a41906", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000005489b3f86680509ac9c66dbf0219f2a28856cce27148d283caea2f1f33502fc580faf8d9e95d0600040a00000000000000e819ce5ae27b95126df7bc7a694e141bcbb464944378ad2ff4a92e1bfde0b1ac4445775798b30ded2f8b0fdce047b74fad787491ff91f2281c19de76ec58a80d62fca3f9ba73060bae64b5422bbcbf616173037805ca01e78a34b9045f69c637bb08" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000005e42f95e7e18bdd192a36366199b00c2b0db304df41beb9bf3b70fda34bcd61977338cd3a490f0e20b9d7baa76b7bf289f8723e534eee060be8c022c5648d9b45986385248c2bcceee93970bc8609505" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "ce20ac52283bdfb914d6e8da70daef048e87f0b3d0e4d9f77a84220479a5b677", + "5773fc8d7c223a9153cd2d98de786ed74654559b75907751523732a50758f43c", + "fc8b5f389ed60ddf9db7b8fc9a47cdcfb08a18b961d085c9926af9e080971c48", + "a9f55613b18252b260fcada171765727ad51fad3f7070de884fccf2bb9bada18", + "ff001cba7a20a02d8b990ab0a74b4215158da8632f82bb2741156aa9e54615b9" + ], + "size": 10, + "root": "e819ce5ae27b95126df7bc7a694e141bcbb464944378ad2ff4a92e1bfde0b1ac", + "verdicts": { + "single_take": "commit_early", + "aligned": "holds", + "complete": "holds", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "upload_not_sealed", + "about": "every part uploaded and the store's last receipt a progress, never sealed (§9.4 complete 3)", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f524a8b201a23a6507b1296d34429670d9025dd45ec7601855e97ec2e2023028ddf567f30e40c1fb30c379fd1a84403a13949d2518c1a40cf2aae7c55827ec7b7b58549427e8b2ca42eea16eadcbb7e38397372325522c205f6ed33ce33b59a509", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7202000000000000008e69d6301ba69c645bf92e7fa065b1dc22ba820496ef3d8c904cda4ef284d29c20a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbecedc3852e80d10adadc9cc1adf0f8d0ad24b2274263293bf5416d1777c50175ba0b817f00fac87da5eab954534c4742b3ce8fb3e997433ffb094312e1ab89550d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294a40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101ec1fe5b5a101a4e3760188a760e9d501a1460617246d489a56e0f73faf9c3d3838f1eb6c31bd916e3ee80b6c4fa83a32399c646e20f3a67f468dd56bddd4af08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000163f19c5a78077cbdd75fbb012909dce6f0ae43876ba14cdeb98733c4c995d3040420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202037590580bad077a85c32c6791cc22e39be8ca0aa0717ae26a69bcc94a1112fb5092c044884b10333c596cd927e67260ed5a0fa23f7c88f7906995de0e4da99905", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000a1e8f6ca31e1d1d9eb2fd02c6de68948f9d995f3ab2e7cfe510596f1e7c4594e40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100017c49a900977cb002423604fe72b9757a32bea9f6b954399bf1a9f78f9fb9fe572492155780940bda5c2044cfcf1db9ec5c94c1fd8f5fdb3307d88fa45d974b0f" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000008d6e0504d0a47cb9548d5f36a05efd9cfd786bf27e96ef54769148922733b0f5000efad5feffffff004307ba8e1adfd8622ac34e1d86e36d2af46c205a25b57ac43b47b88b2f9591a10a086a599b679daf7d5f36746d0f43d51f8061a6f85b83806b165d455bd77109", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502000000000000006698b835dbdc62c3d07dfa8b4ca93f0f4f98761509306187199dae393d36cd14602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000026698b835dbdc62c3d07dfa8b4ca93f0f4f98761509306187199dae393d36cd14020000000000000004000000000000000f4a939cd9401ade1cd80aabdaeef393a2d168801db9ee3ac47ef242f381e239000efad5feffffff014c2c749eba7d922f6fba567412bc462e9d0316606c0f0fd25f1c030bdfedb0144ba24d9e566178fb346c5a25ee64c7699aad1c6c2b9b3c231adb1f3af9ecdf2bc3e50342c63a387e9de2fc9d61b0cbdb470dbf0254dccf3b146b99b2bea94a00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f503000000000000009fdc2f0f494597f33417cdb772cd491296f8a5ed977fe99eafe0acaf33bdfbc8e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e03000000029fdc2f0f494597f33417cdb772cd491296f8a5ed977fe99eafe0acaf33bdfbc804000000000000000600000000000000286e88dfdfba4cb9f69c6087ecd70a72478fb12e5c79234bbbdbd6115fc833de000efad5feffffff01be1d8e1418ddde684a00ddbd54360338ed7c09dab0cf037f0b9db213e3dc67461c1cd34b440bef3230bd8d5cc52bb983e127c4638a4b254832c80820ce679989a3e76232bca4cc5791a7125d34daed42a7eca00aabc69e714f64280e573d9f0d", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000091b594de1f56e3f7a53f2e27fa74cb351bf5bdcdd663b2ec5b646aeefb0c75996033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000291b594de1f56e3f7a53f2e27fa74cb351bf5bdcdd663b2ec5b646aeefb0c7599060000000000000008000000000000004bc369f894daf8c63c49819dd6e84113e01c007178cc3908b3dcccf342ae5f0b000efad5feffffff03be1d8e1418ddde684a00ddbd54360338ed7c09dab0cf037f0b9db213e3dc67464520486ae824e2379fde98ba2197788fb6306ac10a1c64345df585cf78c66aea0f4a939cd9401ade1cd80aabdaeef393a2d168801db9ee3ac47ef242f381e2398da6b3a7984eae04038a60d46cf5b6347dd2661acda4e3446021531c3fe0a34e433ccf19fbe896b4f6009824ef2988bcdc4831a490f9894b2c2b457aed1b7704", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5050000000000000023dad6eeac1a9676b72edbd7f0e9a535440f1479aaa8a39c3fa21ceccfa024af803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e050000000323dad6eeac1a9676b72edbd7f0e9a535440f1479aaa8a39c3fa21ceccfa024af08000000000000000a00000000000000d79b468f3af2785d4e9446705940937a4f50b7f2f0796e4d2ebc41e276b99069000efad5feffffff018296f1b17ea7ee611ac06e240f22d6916b67342c1a830e68fdce07fe17fd8a098e3cea2acc7f6f732108ca4f266fadf03190579bb40c0cd797c950b284e33d8ffb9143be5fb3fb8828752addc85a2a974a2190d01efdafb9a51722f88d030d00" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a01000000300000000000000069d0950c6c3a20deffd2d3ef44021ada5760b002b2e49ffe361949b11722085c0100000000000000c0c1702a010000000004802a010000005500000000000000f75460cbfb7bb2fb1a8be2b611d197d9782cc689eb933289706170cfdc456d7602000000000000000004802a0100000040468f2a010000003a00000000000000d0e073ebeeb2fc286c03a243e566e2aab5b5dab757c3cd6e59fc12a305acefa1030000000000000040468f2a0100000080889e2a010000005f000000000000008c8bfea6457000200041fbf10bee8caee6c6f9ac3faf22dbb259726578705a3d040000000000000080889e2a01000000c0caad2a01000000440000000000000043a5fb76caf86bbda5c8f95c8a7214766197464f9f2c35a3bb2101b8d556d3d30500000000000000c0caad2a01000000000dbd2a010000006900000000000000729a25bfaecdb8d1bb15c7c893260e40694bd577937360b104955908af7cf94b0600000000000000000dbd2a01000000404fcc2a010000004e00000000000000089b8ba24c6dcfbc341a01d892384bb605493884103f2aead1fd52c0a634b1920700000000000000404fcc2a010000008091db2a010000003300000000000000c3fe3190b7b12ec788ef27455a80e7f4965e4dfbb21e4c1abcd55660d4bf3ef408000000000000008091db2a01000000c0d3ea2a010000005800000000000000637395970e03e08826cd57efb99152f75e7ca17aaa322988ea780f4508b1d8b60900000000000000c0d3ea2a010000000016fa2a010000003d000000000000007b768662a529e1c1e49e097b012c2092e8cd4deb01184268bca22217cb3cbd78d79b468f3af2785d4e9446705940937a4f50b7f2f0796e4d2ebc41e276b9906906000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e66698b835dbdc62c3d07dfa8b4ca93f0f4f98761509306187199dae393d36cd149fdc2f0f494597f33417cdb772cd491296f8a5ed977fe99eafe0acaf33bdfbc891b594de1f56e3f7a53f2e27fa74cb351bf5bdcdd663b2ec5b646aeefb0c759923dad6eeac1a9676b72edbd7f0e9a535440f1479aaa8a39c3fa21ceccfa024af470ed9550ac167ce1b88076b924110a826ab44727335a083d4cb486f15026ae20159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e205259369969ae68415166b586fcac6f3efd39c521d69bba49ba56fc942e11438d3cbd4f34bed62924b893eaa744c9ea4520288d15ca0d58e14eefa16258fce7113a30f1ff1b0a1a2dc9a446750e936d80e29dbad28d000b106b6e570ffc7c19fddf29270d", + "parts": [ + { + "index": 0, + "bytes": "ea389b4ef0a8eee28a8d59100adc2f400e2a14b1a6cdd1ba133366dcef38beb54e7cdc7630ae3bb1760fff8edc052188" + }, + { + "index": 1, + "bytes": "bc8283c877066f013cffbf857e0c81339c4fd10adfd830f4910e239a45dad68771586230afeae66fe9cb3217f686c86c6f82a198f6e30a5949c77aeb3f7f68ebb1b3bc39d9fe24f5acb92924fe3cad9cfc56547a43" + }, + { + "index": 2, + "bytes": "5d1a2b8b24d889f0fae6d8938767aa2ebe7841950953f73d85f8ed99ae45fe058b58c93492ae29fe8fa9f3f02a1088bfb41c4fc47d6424dde2d5" + }, + { + "index": 3, + "bytes": "6e78884f5ef5cf995b4be2ab21289f4a376f838d2260fe9be2e1bd7095f1ff4463337cdae2bb48eaf40f0b3f495650fdbfa9b466688a78a772864027122a95a7fae97f54cc3bf89c20dd6e9c971bf1e919118ec8f0d57d8592f5422d3665c3" + }, + { + "index": 4, + "bytes": "4ce173e295c9e9a8afe0ad1e0429bcd87abe7e919a6cac5239e988cdafd00bed09bd2e5279f3cf70ed56ceba4396eba8dd9cc2f9545e5b4d235bd56654f610bff1e4f8eb" + }, + { + "index": 5, + "bytes": "7391d4735e2da41bf78810bd4547748fdff1b2c243a3a8efcd26e4abd24885722c73264accd74b3033c6be3debc2be8bfd36f4363824d411c92818ac6feb651aae0aa0a1e4a701a7bc84a0e2ebccf1cef6d42a8b55b4b04778bea23c92ed65477e8573df2536353984" + }, + { + "index": 6, + "bytes": "e82ec6055e75846ae0c7873ea593eefb00959e9422eed3aba8a17b2682c7ca5df9372b5e4a3271975b4e3cf522b3db25e56d516f154a1c63c6e2274d98343f2a664154f518622e0dd94a07f19b8f" + }, + { + "index": 7, + "bytes": "fd06e430e2ea2e240f11f08c5af49947a4fe64f34d906865b8dee83094d5b94e00674a2abfe34687b24a386f6964d744fa82fc" + }, + { + "index": 8, + "bytes": "8143b7e587f86e665ba9c6cd56baa0ce1e17883dd10bbf35a479786498778003f7559ce84325ae4186123fbdee9e8c34b9c09794020b567d9d30e9e2186ef0f6f29d3744ad12e36f109c93d6b8093eb5d85d5d2716190e76" + }, + { + "index": 9, + "bytes": "e666408a8d06c6f9eaf2610b8ef03384b27398d6f25040ffa607004a93202b6b539f2e7b18129f47b2b226dbf7e7ba2e44753d5e56bca5fd58d9a98662" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000d79b468f3af2785d4e9446705940937a4f50b7f2f0796e4d2ebc41e276b9906944455de92a8398c87ea73a36ab9e1221f08f6b903741882158a4a2306d82a8d2152e20697578c9aed3edf1974dbc7b4e6f46a17ac8d340477cba4dc80ebe4039110a" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a00000000b136b803f97671f83024498d89dae4b8006c9cebb55d9550f6fa0adf8ab59b1c312dd9368524c4cac9b9a5e0b71fdc499638b5389756e630d4a66ae00dcbd4ad8263ab56b0ba83de4e0de851d8fc9c00" + ], + "evaluated_at": 1792195200, + "outcome": "verdicts", + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "stream_id": "41f46867-56b9-883f-bac1-1b1d229c5fc2", + "commits": [ + "d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6", + "6698b835dbdc62c3d07dfa8b4ca93f0f4f98761509306187199dae393d36cd14", + "9fdc2f0f494597f33417cdb772cd491296f8a5ed977fe99eafe0acaf33bdfbc8", + "91b594de1f56e3f7a53f2e27fa74cb351bf5bdcdd663b2ec5b646aeefb0c7599", + "23dad6eeac1a9676b72edbd7f0e9a535440f1479aaa8a39c3fa21ceccfa024af", + "470ed9550ac167ce1b88076b924110a826ab44727335a083d4cb486f15026ae2" + ], + "size": 10, + "root": "d79b468f3af2785d4e9446705940937a4f50b7f2f0796e4d2ebc41e276b99069", + "verdicts": { + "single_take": "holds", + "aligned": "holds", + "complete": "upload_not_sealed", + "publishable": { + "live": "holds", + "record": "holds", + "distribute": "holds", + "train": "purpose_not_consented" + } + }, + "stands": false, + "markers": [ + { + "event": "1ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63", + "t": 9000000, + "chunk": 3, + "into_chunk": 0, + "into_master": 3000000 + }, + { + "event": "65c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c46", + "t": 13000000, + "chunk": 7, + "into_chunk": 0, + "into_master": 7000000 + } + ] + }, + { + "name": "room_refused", + "about": "a device whose grant does not permit take_commit: the room refuses its first commitment (live-rooms §9.2 step 4), and the take is refused there", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118010000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a6563744000353934323534363530303435303030333264363839336639383061376461643438336166373062346531313661313062376361613465323035323539333639394d83f618aab38f8b4dee81807d07c5c9d18ae0d4bd95a11382d077f1898d5dc6adefbfe35afa85ceee8584e811fb726a765805490ae0e715ad8cf70924637908", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06" + ], + "key_log_head": "{\"grant_max_s\":86400,\"issued_at\":\"2026-10-15T00:00:00Z\",\"keys\":[{\"compromised_since\":null,\"id\":\"room-authority\",\"key\":\"d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd\",\"may_sign\":[\"live/room\"],\"status\":\"active\",\"until\":null},{\"compromised_since\":null,\"id\":\"take-store\",\"key\":\"0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba13\",\"may_sign\":[\"capture/store\"],\"status\":\"active\",\"until\":null}],\"kind\":\"wai-key-set\",\"next_root\":\"fa2ec0c92dcc45c59d8ede47e5f6cbaa0f89e36186a25c7007ec718415288a8d\",\"origin\":\"https://lessons.example\",\"prev\":null,\"revoked_modules\":[],\"root\":\"93bd7020e78d0ced730d16b3df0385340bb6ad05773df662e19ec3d4735c5e5c\",\"seq\":0,\"sig\":\"5c85a664a073448a6b793b4bd97984ff5092b32347879412e538a217427aacca47f88df6251383a45fcc334648ffb6527e7bd0bbd91757ae3ba6c0d816edae06\",\"status_max_age_s\":3600}", + "chains": [ + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c529c7cd7b7701b548ac464140fb25265955ee382dd3b56e8e9fe143c8eb449d4537d6db291eb368c6b866995892e5c98b9853cbea4cae281520adc1d6670ef71368aeae1f3bae74b814bfef4637e58fcdab5363e3e11219fa11641f82dbf1eec07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7201000000000000004c61ec041af54b1721cb0884ea0a71d757a84dc5328ec05b85316a8cec9e08b4000000000000000000104000e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5d39efde56b98d681f5eaab74a1aa968f4012e9b2b002e316cd6025d27dd88804a589c67d40de466da0c311d497183471e9238ba8ad02f2fb23ba9888042a5d11372fd760a2dced71e7a62de5d23ec4a99de3664d110a2175a1c2461951d48f0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720200000000000000ac398fa18020437045d4f7d673009dcf30bbffa5827c409e162946b9fce94c3420a10700000000000010400078a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c68b117ea2a775c9da4b04e8180250edfa169fbea9b665304befac86629814fbec82fabf13ea1fcec7d95c91ce6aa105b8f5774e63e5336c2d99ed5d79f284a9f11741ca52ecb68b9900f9ce748691a1d81e582b58a921efacef1d654e31797801", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720300000000000000ae2462538d75322bbf540b39d409ef6e13541d8e8393b0f0646e49749ce1b0bc40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101e8f911bc12f98a8453e6bfb40a04f808b9f15009caaf4e174d01cc9b6d0f777c9475dbb4277b4066636d7d839cbdee82767b01d645c4a0a5205df32190faee0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720400000000000000411920f34ca5278bfe228046760e5eede33b88d2c5e83a0750e55876f535bd7240420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50002020335f68b5c76ff8daf8a4f19d4c92223fd55c1bcb7b5ad58dae740278a28207251baa06deff311d1933a82d30e650a7df948a53ca9d52b4a645a12c365da210908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7205000000000000001026c89ac16eb0c1e6781db9a7371236eeae9a70f6ef763bd77900af683a0c8b40420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52000100016fa87f3aec2e4ef25718c28336ea3c0d2476301e267d7d9f017fdc8b652bad5ebaa34e814942ffeb5357ddd4ad6a8877ff48c975310f537d3b3de26495494809" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd40548900000000000008160004000000020e00727573686564207468652072756e00809ba9c91815cd9f636ccff36640e190e494adc69a9e162fc3064de9b8b486df923f26427c923e695c24c8a3f2001af17ec446c9cb358df8b52df091a98b7003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5202000000000000001ba0b474d6e7290eec46ced4a76a5d5ba0b0c355356c46265eb9193404d03d63405dc600000000000008170004000000010f006c6f76656c79207068726173696e6700972a0268ca07e13e4c77f98f6918efc6065688ff1fe759c3d3cfe640a3bd88077d5f6dd2397d69d4dcd86c283bf63576d8b5b9796b374c3f16b9d19831619908", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52030000000000000065c8bdc618b2196fd73c8e4cca0384e68ad186e800e1b2d109d460f3a1896c460024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5026ff37f056942a036e4c9684ab673e494e3b02edd1948821cc13cefa761defec0b958efa7841c6ae5dde0c8bdde7b336f4937b5442b55e2f3d7970ecd00a52b00" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6000000000000000002000000000000002828a77b1079f8ef6304f494b4d563caa8ac24bef78ab71e12f7ecf6b1a0a879000efad5feffffff004cd235fcda61eeb981b9992683813b22a40e504e9dbc16bd87f8bea058e5331fd6499f7b7369d7db65a8b45bb381db1e011a4beb4f3f598d461089830e412c00", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5020000000000000023000dd65051fe948a1c2b67c93d1a92dea7619816554c7a529976fd8ece674a602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e020000000223000dd65051fe948a1c2b67c93d1a92dea7619816554c7a529976fd8ece674a0200000000000000040000000000000008fa8b2d101856ad831d4cbb7b33d3b9006a114832611307a65e905dbbe42907000efad5feffffff01b685e71b728b550ce13b27ba0057863bb4d2839dd9db9008bd8eda32270f93234fa42e82bc5660ca62b7ac93354e0ac9646224d177b376d67a50f1fa2ef0c196c1b187beeaa9f8df81e3d6852076a472b8356bd3dd285f9f5ae0b3ca9a958d0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000909a6e7905d7c6ad458a5ddff01bb7f22e119fe7c4240194ec50e1fe395e78d4e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002909a6e7905d7c6ad458a5ddff01bb7f22e119fe7c4240194ec50e1fe395e78d404000000000000000600000000000000f029deb404cbe9e54bd3f9ece815e8665fa40dc5ef382beb30b69a3a2e35e760000efad5feffffff0126963648d7fcdcaf9defb23ea1eb453a272d211ae86097e8aa1303c1bb7b0974c08e094984a7d553e5dbe0b99e3f5cbc93a0ce26079930c8e73a1d53ceb942012da479c4f12a60a29a4f7f2d49289ff42a321f858783316e02baddc154cafd0f", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50400000000000000fcacdd80185816812ae03983cb664de77821a571b388b0ef533063c522d06bdf6033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0400000002fcacdd80185816812ae03983cb664de77821a571b388b0ef533063c522d06bdf06000000000000000800000000000000d5ba3e89c32348af19c4f0a72427623c7c72d30dc158c8bcad3ecaef55179368000efad5feffffff0326963648d7fcdcaf9defb23ea1eb453a272d211ae86097e8aa1303c1bb7b097427a6560033d2e4f8ab2238ede473090fd00e0391bf87f87a11316830dd3a97c808fa8b2d101856ad831d4cbb7b33d3b9006a114832611307a65e905dbbe4290759c78021258166f1992c37530329fae225289c770293f9cf2ff56b4ed14a1cc2af9bcbcab576d721a46099eafc3fe012f51c02798f45b8810cd570e7975f1804", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000006c700bee392fb97a82b95c34e91b9bacec777d8fb55f041b7486971a57b02965803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000036c700bee392fb97a82b95c34e91b9bacec777d8fb55f041b7486971a57b0296508000000000000000a00000000000000bff7768ee08325d8b04f2353e9bceb01640fc3c618d82d29bf119463c47c9044000efad5feffffff01999d5fbbf5d7d0077686d2ea6b2209c0e507907a241c9d4952d8e732ccb3734429de2f83ef255ee1a12c67f59abd99b3499edcb0e6430814387eb796e0e03e7f2c8ba67b5f4394930d486cd6aaa94929217c564aece64aff890fc3dca5b32000" + ] + ], + "manifest": "57544d31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f559425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1307060a0000000000000000000000807f612a01000000c0c1702a010000003000000000000000b856de134643d6a058e801e3b3ef04e1b6dead3736777150cfb0e39311363e080100000000000000c0c1702a010000000004802a01000000550000000000000063448764eb5aefc0d64d11de2a8ab116c485da7afd8f3b17b7d716438c6eb91402000000000000000004802a0100000040468f2a010000003a00000000000000b094f3ce694ac7fbf67cb7f55c135799f2f697a89328d9fe00d188eec26aa212030000000000000040468f2a0100000080889e2a010000005f00000000000000a1fa771c2b07a43572badd28fba704d7f5e5da149a941b001689385282e1f7c1040000000000000080889e2a01000000c0caad2a0100000044000000000000007b6f02f9feb78efbd99f84145b3a514f9b9f9312de9da0845dee950f591484d40500000000000000c0caad2a01000000000dbd2a010000006900000000000000b53558158450b6e20a1ae865c9e5245498d9d3a96e21186374a3be1c567e65510600000000000000000dbd2a01000000404fcc2a010000004e000000000000009eecd9c9135398874a417dd9044bf91f2be2b22eb215f5af8680ecac2932bf7d0700000000000000404fcc2a010000008091db2a0100000033000000000000009d39f05a7fca7f5b398c8eef5e67134dd9fe47108951bb5c19e353f449af192e08000000000000008091db2a01000000c0d3ea2a010000005800000000000000208e77711c379d1f22d76a9ab70ad62d3f785fc69d209e96778ff86d58ef97dd0900000000000000c0d3ea2a010000000016fa2a010000003d000000000000000ebc684d1a59db72871a5522d8b650060d7e94ad91745a90700e0a56a3fe5e5fbff7768ee08325d8b04f2353e9bceb01640fc3c618d82d29bf119463c47c904406000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e623000dd65051fe948a1c2b67c93d1a92dea7619816554c7a529976fd8ece674a909a6e7905d7c6ad458a5ddff01bb7f22e119fe7c4240194ec50e1fe395e78d4fcacdd80185816812ae03983cb664de77821a571b388b0ef533063c522d06bdf6c700bee392fb97a82b95c34e91b9bacec777d8fb55f041b7486971a57b0296583abff7856b744f92f3c84fb521e81ec585c0346b2b00e35422fc1fbd32d7a2d0159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936998ae24424ea7e320d56376237f066a3a8077cc4752ff59d7b797f29f85f3dd0b7056b14a3f3880b16a44013c949b571e89d15e9731b0dc5c41ede45e3e965f5ed0aa434a0a4f34998de7eab72e3227011f9d312c13383a4410521de10e4214a07", + "parts": [ + { + "index": 0, + "bytes": "74c9eca2fe879bafb4433bf38a7e82cae486dfb9a59481ef7ee5deb6d9d0da6f836bea867721aa615aff79214081fecb" + }, + { + "index": 1, + "bytes": "aab385ed85f8d2edd88fb3a0763901b5bbaded83f5a562372b4b247b6ce28780fc38d2514aec9db5b4e47188e33805dd70b90ff59abf763af1ce43c74960f426d331c923bc560da50c8cdae9823136a5cfea6cb284" + }, + { + "index": 2, + "bytes": "89daea9b91883c58aa59701d51b4cf9fd9dd0b935ad0fd49b6748246b8e4711b8ea2f6cc598186e8cc1b4c9913b9b1871920e9f6862c2c7749b7" + }, + { + "index": 3, + "bytes": "ccffca9494a51ae257ff2e3aef0dabe8dad2d93a7f0b6fadb60a9187323fede12353310004aa68e914a563ffb329d901a45aa060269745d6fe768a5a87659f598851c0e1e5ffaaa8bfc47bb875156a1961c64c1e9d0e332081ae43787f361a" + }, + { + "index": 4, + "bytes": "43bf85d30d7b1854cb7d7b14dcd73253d9b2e7b316b023955af01effb09cace35976c72298a50c531fef0def1a28a8427e9200ba16e1bed3806acc29ccfa5662a982b68d" + }, + { + "index": 5, + "bytes": "39f06bedd8285e563ffff3a020fce3fd18cbc49bc32c9b5e87174ba65696f5bc37dd0397a709b3f54b1eb17708cacfbd59745aaefb5986846d7be8acecbba36f88e7571bf39ea4cc9a59d2251720d00f2a548b298dfb40bef4bf439faf528b1226fb7d7b5a52653bd1" + }, + { + "index": 6, + "bytes": "1ee8df8763ad69bb82659791607c33115219d7b52c23d4b5b7fc45dc8a1d1ce6ada49dd9998807718ee81689342bc2e54f10b4447d3702f3d8a8637501ef778184ff1c51e064afe25cfd86351cbc" + }, + { + "index": 7, + "bytes": "5ea395a9cba6e16c48313958d9fca7f034b920f65cf5a4d891a5ee098d5936c93431ce23e5a968db6e56d8bbc35d963146016a" + }, + { + "index": 8, + "bytes": "fa260e93ba395b699f7d854f2f5ba2afbd5251e8f05aee7eb53df072dbc9d7a0f5c72e6aa02898a4d3cc72c5b80b310c73b1d814cc7ad2fba91163272a082c4d0fafc8f6b1beefb24c506b4e5ad98f35905267afcbf28bda" + }, + { + "index": 9, + "bytes": "de398c2b8480910b3fe84aa6abfc13dc07dc8060bc505f8f9aa4ee94608132388d2e6b43f6e3be59183a40fbd3efeac185c649cda7f27a783a63a44bc7" + } + ], + "receipts": [ + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000000000000000000000000000000000000000000000000000000000000000000000000000006d9dd9e95d060001000000000000000000000000000000000000000000000000000000000000000000000000000000004445ade4928edc60ebd2d6214d3ee3e64d80470f9f9e7d4e17a43604a557bdc11a8f02a8314a78a769a4b77b0c97128d100990635f6e01f276f023dd2693271ab909", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e01000000000000003c3544438996ea3c33ca52d0c9588e1a06a629640c2b72bbba477f381f5389bfc033cbd9e95d0600020a00000000000000bff7768ee08325d8b04f2353e9bceb01640fc3c618d82d29bf119463c47c904444457cae2a086bc5d7f7de73b64f17ca274c887ca6b2dad432d7b38c4e59d099e84e60eafbd8aedd6f464f32998663f3848e00d66d3481a08a60b7c132bd6a1e8a06", + "57555231010f222415114ff3e773663df797c88d6e11b094c4ffc6694581d843dbfbe8ba1341f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e02000000000000000349821e0efde8ccde5482ea6447e4fc5d2ad5ef0835bd768e57766d3bcfbf9b80faf8d9e95d0600040a00000000000000bff7768ee08325d8b04f2353e9bceb01640fc3c618d82d29bf119463c47c90444445c405b6b02675b8582b85518bc46e6e7bfc02d71713b7dd01c66d3a79a869d17e47e1efda8cce6f75103e74cba2f626df0aeaf737a786f2ab9762e52e5138110f" + ], + "consents": [ + "57434e310159425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699000000000000000000000000000000000000000000000000000000000000000000075f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca8017d06a0000000000f6f86a000000005a86399c70581583168bbaf91ce6a46202193bc7aa4ef60fad87bfe153f4f634feffffc238342c32e8126c38933f01b5afbdb04364b9fd529ff6cb4bcec7958f20f76db5e11bb2cae6d5d8ef06a56008" + ], + "evaluated_at": 1792195200, + "outcome": "refuse", + "reason": "kind_not_permitted", + "at": [ + "room", + "record", + 3, + 0 + ] + } + ] +} diff --git a/wai/registry/capabilities.json b/wai/registry/capabilities.json index f49193baa..2de06862d 100644 --- a/wai/registry/capabilities.json +++ b/wai/registry/capabilities.json @@ -214,6 +214,20 @@ "edition": null, "registered": "2026-06-13" }, + { + "capability": "wai.capture.take", + "kind": "record", + "status": "registered", + "media": null, + "role": null, + "tier": null, + "licence": null, + "replicate": null, + "sets": [], + "spec_section": "§5 Interactive, temporal & computed content", + "edition": null, + "registered": "2026-10-17" + }, { "capability": "wai.derive.crop", "kind": "derivation", @@ -544,6 +558,34 @@ "edition": null, "registered": "2026-06-12" }, + { + "capability": "wai.live.events", + "kind": "record", + "status": "registered", + "media": null, + "role": null, + "tier": null, + "licence": null, + "replicate": null, + "sets": [], + "spec_section": "§5 Interactive, temporal & computed content", + "edition": null, + "registered": "2026-10-16" + }, + { + "capability": "wai.live.room", + "kind": "record", + "status": "registered", + "media": null, + "role": null, + "tier": null, + "licence": null, + "replicate": null, + "sets": [], + "spec_section": "§5 Interactive, temporal & computed content", + "edition": null, + "registered": "2026-10-16" + }, { "capability": "wai.mesh.draco", "kind": "payload", @@ -1643,6 +1685,27 @@ "section": "§5", "status": "defined" }, + { + "name": "WCN1", + "kind": "magic", + "document": "extensions/capture-binding.md", + "section": "§8.1", + "status": "defined" + }, + { + "name": "WEP1", + "kind": "magic", + "document": "extensions/live-events.md", + "section": "§5", + "status": "defined" + }, + { + "name": "WEV1", + "kind": "magic", + "document": "extensions/live-events.md", + "section": "§3.1", + "status": "defined" + }, { "name": "WHP1", "kind": "magic", @@ -1650,6 +1713,20 @@ "section": "§6.2", "status": "defined" }, + { + "name": "WRD1", + "kind": "magic", + "document": "extensions/live-rooms.md", + "section": "§3.1", + "status": "defined" + }, + { + "name": "WRG1", + "kind": "magic", + "document": "extensions/live-rooms.md", + "section": "§4.1", + "status": "defined" + }, { "name": "WSIX", "kind": "magic", @@ -1657,6 +1734,27 @@ "section": "§6", "status": "defined" }, + { + "name": "WTM1", + "kind": "magic", + "document": "extensions/capture-binding.md", + "section": "§7.1", + "status": "defined" + }, + { + "name": "WUR1", + "kind": "magic", + "document": "extensions/capture-binding.md", + "section": "§6.2", + "status": "defined" + }, + { + "name": "X-WAI-EVENT", + "kind": "playlist-attribute", + "document": "extensions/live-events.md", + "section": "§8.3", + "status": "defined" + }, { "name": "X-WAI-FLOOR", "kind": "playlist-attribute", @@ -1692,6 +1790,13 @@ "section": "§8", "status": "defined" }, + { + "name": "science.transaction.wai.event", + "kind": "playlist-attribute", + "document": "extensions/live-events.md", + "section": "§8.3", + "status": "defined" + }, { "name": "science.transaction.wai.multivariant", "kind": "data-id", @@ -1734,6 +1839,20 @@ "section": "§8", "status": "defined" }, + { + "name": "urn:wai:event:1", + "kind": "scheme", + "document": "extensions/live-events.md", + "section": "§8.4", + "status": "defined" + }, + { + "name": "urn:wai:event:1", + "kind": "catalog", + "document": "extensions/live-events.md", + "section": "§8.1", + "status": "defined" + }, { "name": "wai", "kind": "catalog", diff --git a/wai/vocab/v2.ttl b/wai/vocab/v2.ttl index 77495b0fc..07a326e90 100644 --- a/wai/vocab/v2.ttl +++ b/wai/vocab/v2.ttl @@ -267,6 +267,13 @@ wai:wai.avatar.pose a wai:Capability ; wai:specSection "§5 Interactive, temporal & computed content" ; wai:registeredOn "2026-06-13"^^xsd:date . +wai:wai.capture.take a wai:Capability ; + rdfs:label "wai.capture.take" ; + wai:kind wai:kind-record ; + wai:status wai:status-registered ; + wai:specSection "§5 Interactive, temporal & computed content" ; + wai:registeredOn "2026-10-17"^^xsd:date . + wai:wai.derive.crop a wai:Capability ; rdfs:label "wai.derive.crop" ; wai:kind wai:kind-derivation ; @@ -515,6 +522,20 @@ wai:wai.image.png a wai:Capability ; wai:specSection "§5 Mandatory floor" ; wai:registeredOn "2026-06-12"^^xsd:date . +wai:wai.live.events a wai:Capability ; + rdfs:label "wai.live.events" ; + wai:kind wai:kind-record ; + wai:status wai:status-registered ; + wai:specSection "§5 Interactive, temporal & computed content" ; + wai:registeredOn "2026-10-16"^^xsd:date . + +wai:wai.live.room a wai:Capability ; + rdfs:label "wai.live.room" ; + wai:kind wai:kind-record ; + wai:status wai:status-registered ; + wai:specSection "§5 Interactive, temporal & computed content" ; + wai:registeredOn "2026-10-16"^^xsd:date . + wai:wai.mesh.draco a wai:Capability ; rdfs:label "wai.mesh.draco" ; wai:kind wai:kind-payload ; diff --git a/wai/wai-rs/Cargo.toml b/wai/wai-rs/Cargo.toml index 3492ccbea..e258798f9 100644 --- a/wai/wai-rs/Cargo.toml +++ b/wai/wai-rs/Cargo.toml @@ -174,6 +174,24 @@ ed25519 = ["dep:ed25519-dalek"] # Interactive worlds (extensions/interactive-worlds): media that consumes # input. Pure-Rust, no ML dep chain — the sim is closed-form fixed-point. world = ["dep:blake3", "ed25519"] +# Live events (extensions/live-events): `wai.live.events`, a signed, hash-chained, +# timeline-bound event track — the WEV1 record, its policy, its verifier, poll tallies +# replayed through the feed sim (wai.world.sim.feed0), and the MSF event timeline, +# EXT-X-DATERANGE and emsg mappings. SHA-256 and Ed25519 only; no new dependency. +live_events = ["world"] +# Live rooms (extensions/live-rooms): `wai.live.room` — the signed room descriptor (WRD1) +# and room grant (WRG1), revocation through the authority's key log (jwp-receipts §7), +# track naming, precedence and redundancy over slots, publish profiles, and the room +# verifier that replays every principal's events under the grant in effect at each t. +# Ed25519, SHA-256 and the key log only; no new dependency. +live_room = ["live_events", "key_discovery"] +# Capture binding (extensions/capture-binding): `wai.capture.take` — a device's master +# recording bound to a live room by rolling take_commit events (the take tree is +# staged-measurement Appendix C's, with RFC 9162 consistency proofs), the store's upload +# receipts (WUR1), the take manifest (WTM1), consent records (WCN1), and the take verifier +# with its single-take, aligned, complete and publishable verdicts. Ed25519, SHA-256 and +# the key log only; no new dependency. +capture_take = ["live_room"] # Object-based spatial audio (extensions/spatial-audio): the deterministic # Fx mixdown engine. Reuses the world `Fx` floor + blake3; no codec/ML deps # (sources arrive as decoded mono PCM — decoding the wai.audio.* assets is @@ -601,6 +619,21 @@ name = "wai_world_vectors" path = "src/bin/wai_world_vectors.rs" required-features = ["world"] +[[bin]] +name = "wai_live_events_vectors" +path = "src/bin/wai_live_events_vectors.rs" +required-features = ["live_events"] + +[[bin]] +name = "wai_live_room_vectors" +path = "src/bin/wai_live_room_vectors.rs" +required-features = ["live_room"] + +[[bin]] +name = "wai_capture_take_vectors" +path = "src/bin/wai_capture_take_vectors.rs" +required-features = ["capture_take"] + [[bin]] name = "wai_world_meter" path = "src/bin/wai_world_meter.rs" @@ -1211,6 +1244,21 @@ name = "world_model" path = "tests/world_model.rs" required-features = ["world_model"] +[[test]] +name = "live_events" +path = "tests/live_events.rs" +required-features = ["live_events"] + +[[test]] +name = "live_room" +path = "tests/live_room.rs" +required-features = ["live_room"] + +[[test]] +name = "capture_take" +path = "tests/capture_take.rs" +required-features = ["capture_take"] + [[test]] name = "world_replay" path = "tests/world_replay.rs" diff --git a/wai/wai-rs/src/bin/wai_capture_take_vectors.rs b/wai/wai-rs/src/bin/wai_capture_take_vectors.rs new file mode 100644 index 000000000..84425536c --- /dev/null +++ b/wai/wai-rs/src/bin/wai_capture_take_vectors.rs @@ -0,0 +1,53 @@ +//! Conformance corpus for capture binding (`live-conformance/takes/`, extensions/capture-binding.md §13). +//! +//! wai_capture_take_vectors gen write vectors.json, from fixed seeds +//! wai_capture_take_vectors verify vectors.json regenerates byte for byte, and +//! every vector gets the outcome it states +//! +//! The generator and this verifier are one implementation. The corpus's second +//! implementation is `live-conformance/capture_take_verify.py`, written from the extension's +//! text and sharing no code with this binary. + +use std::path::Path; +use wai::capture_take::corpus; + +fn main() { + let a: Vec = std::env::args().collect(); + match (a.get(1).map(String::as_str), a.get(2)) { + (Some("gen"), Some(d)) => { + let p = Path::new(d).join("vectors.json"); + if let Err(e) = std::fs::create_dir_all(d).and_then(|_| std::fs::write(&p, corpus::generate())) { + eprintln!("write {}: {e}", p.display()); + std::process::exit(1); + } + println!("wrote {}", p.display()); + } + (Some("verify"), Some(d)) => std::process::exit(verify(Path::new(d))), + _ => { + eprintln!("usage: wai_capture_take_vectors gen|verify "); + std::process::exit(2); + } + } +} + +fn verify(dir: &Path) -> i32 { + let p = dir.join("vectors.json"); + let doc = match std::fs::read_to_string(&p) { + Ok(s) => s, + Err(e) => { + eprintln!("read {}: {e}", p.display()); + return 1; + } + }; + let mut fail = 0; + let same = doc == corpus::generate(); + println!("{} vectors.json regenerates byte for byte from its seeds", if same { "PASS" } else { "FAIL" }); + fail += (!same) as i32; + let fails = corpus::verify(&doc); + for f in &fails { + println!("FAIL {f}"); + } + println!("{} every vector gets the outcome the corpus states", if fails.is_empty() { "PASS" } else { "FAIL" }); + fail += (!fails.is_empty()) as i32; + (fail != 0) as i32 +} diff --git a/wai/wai-rs/src/bin/wai_live_events_vectors.rs b/wai/wai-rs/src/bin/wai_live_events_vectors.rs new file mode 100644 index 000000000..c26845982 --- /dev/null +++ b/wai/wai-rs/src/bin/wai_live_events_vectors.rs @@ -0,0 +1,54 @@ +//! Conformance corpus for live events (`live-conformance/events/`, extensions/live-events.md §10). +//! +//! wai_live_events_vectors gen write vectors.json, from fixed seeds +//! wai_live_events_vectors verify vectors.json regenerates byte for byte, and +//! every vector, policy case and binding case +//! gets the outcome it states +//! +//! The generator and this verifier are one implementation. The corpus's second +//! implementation is `live-conformance/live_events_verify.py`, written from the extension's +//! text and sharing no code with this binary. + +use std::path::Path; +use wai::live_events::corpus; + +fn main() { + let a: Vec = std::env::args().collect(); + match (a.get(1).map(String::as_str), a.get(2)) { + (Some("gen"), Some(d)) => { + let p = Path::new(d).join("vectors.json"); + if let Err(e) = std::fs::create_dir_all(d).and_then(|_| std::fs::write(&p, corpus::generate())) { + eprintln!("write {}: {e}", p.display()); + std::process::exit(1); + } + println!("wrote {}", p.display()); + } + (Some("verify"), Some(d)) => std::process::exit(verify(Path::new(d))), + _ => { + eprintln!("usage: wai_live_events_vectors gen|verify "); + std::process::exit(2); + } + } +} + +fn verify(dir: &Path) -> i32 { + let p = dir.join("vectors.json"); + let doc = match std::fs::read_to_string(&p) { + Ok(s) => s, + Err(e) => { + eprintln!("read {}: {e}", p.display()); + return 1; + } + }; + let mut fail = 0; + let same = doc == corpus::generate(); + println!("{} vectors.json regenerates byte for byte from its seeds", if same { "PASS" } else { "FAIL" }); + fail += (!same) as i32; + let fails = corpus::verify(&doc); + for f in &fails { + println!("FAIL {f}"); + } + println!("{} every case gets the outcome the corpus states", if fails.is_empty() { "PASS" } else { "FAIL" }); + fail += (!fails.is_empty()) as i32; + (fail != 0) as i32 +} diff --git a/wai/wai-rs/src/bin/wai_live_room_vectors.rs b/wai/wai-rs/src/bin/wai_live_room_vectors.rs new file mode 100644 index 000000000..0c6421ed5 --- /dev/null +++ b/wai/wai-rs/src/bin/wai_live_room_vectors.rs @@ -0,0 +1,53 @@ +//! Conformance corpus for live rooms (`live-conformance/rooms/`, extensions/live-rooms.md §12). +//! +//! wai_live_room_vectors gen write vectors.json, from fixed seeds +//! wai_live_room_vectors verify vectors.json regenerates byte for byte, and +//! every vector gets the outcome it states +//! +//! The generator and this verifier are one implementation. The corpus's second +//! implementation is `live-conformance/live_rooms_verify.py`, written from the extension's +//! text and sharing no code with this binary. + +use std::path::Path; +use wai::live_room::corpus; + +fn main() { + let a: Vec = std::env::args().collect(); + match (a.get(1).map(String::as_str), a.get(2)) { + (Some("gen"), Some(d)) => { + let p = Path::new(d).join("vectors.json"); + if let Err(e) = std::fs::create_dir_all(d).and_then(|_| std::fs::write(&p, corpus::generate())) { + eprintln!("write {}: {e}", p.display()); + std::process::exit(1); + } + println!("wrote {}", p.display()); + } + (Some("verify"), Some(d)) => std::process::exit(verify(Path::new(d))), + _ => { + eprintln!("usage: wai_live_room_vectors gen|verify "); + std::process::exit(2); + } + } +} + +fn verify(dir: &Path) -> i32 { + let p = dir.join("vectors.json"); + let doc = match std::fs::read_to_string(&p) { + Ok(s) => s, + Err(e) => { + eprintln!("read {}: {e}", p.display()); + return 1; + } + }; + let mut fail = 0; + let same = doc == corpus::generate(); + println!("{} vectors.json regenerates byte for byte from its seeds", if same { "PASS" } else { "FAIL" }); + fail += (!same) as i32; + let fails = corpus::verify(&doc); + for f in &fails { + println!("FAIL {f}"); + } + println!("{} every vector gets the outcome the corpus states", if fails.is_empty() { "PASS" } else { "FAIL" }); + fail += (!fails.is_empty()) as i32; + (fail != 0) as i32 +} diff --git a/wai/wai-rs/src/capture_take.rs b/wai/wai-rs/src/capture_take.rs new file mode 100644 index 000000000..a6f35c915 --- /dev/null +++ b/wai/wai-rs/src/capture_take.rs @@ -0,0 +1,1442 @@ +//! Capture binding — `wai.capture.take` ([extensions/capture-binding.md]). +//! +//! A device records its full-quality master while it takes part in a live room +//! ([`crate::live_room`]). Every commit interval of the room's recording policy it emits a +//! `take_commit` event ([`crate::live_events`] kind `0x0C`) carrying the take id, the chunk +//! range it adds, the root of the take tree over every chunk so far, its clock offset to +//! the room clock, and an RFC 9162 consistency proof that the new root extends the last. +//! The events ride the room's events track, so the room clock stamps them and every +//! participant holds them. After the session the device uploads the master by chunk hash, +//! the store signs receipts of the upload's state machine (`WUR1`), and the device signs a +//! take manifest (`WTM1`) listing the chunks, their root, every commitment's digest and the +//! consent record (`WCN1`) of every subject. +//! +//! What this module implements, by section of the extension: +//! +//! - §3: the binding of a device to the principal it captures for, through its grant's +//! `subject` attribute, and the take id; +//! - §4: chunk descriptors and the take tree, which is staged-measurement Appendix C's +//! tree ([`crate::output_tree`]: RFC 6962's Merkle tree hash and its node) over leaves of +//! the take's own domain, with RFC 9162 consistency proofs; +//! - §5: the `take_commit` payload and the chain of a take's commitments; +//! - §6: upload receipts, their chain and state machine, the store's listing in the key +//! log and the region pin; +//! - §7: the take manifest; §8: the consent record; +//! - §9: take verification over [`crate::live_room::verify_room`], and the verdicts of +//! `single-take`, `aligned`, `complete` and `publishable`; +//! - §10: a room-clock instant's position in the master; §11.1: the C2PA stream id. +//! +//! The C2PA live video mapping of §11 beyond the stream id is specified and not +//! implemented: this crate has no CBOR or COSE encoder. +//! +//! The corpus `live-conformance/takes/` is written by [`corpus::generate`] and checked by +//! [`corpus::verify`] here, and by `live-conformance/capture_take_verify.py`, which shares +//! no code with this module. +//! +//! [extensions/capture-binding.md]: ../../extensions/capture-binding.md + +use std::collections::BTreeSet; + +use ed25519_dalek::{Signer, SigningKey}; +use sha2::{Digest, Sha256}; + +use crate::key_log::{EntryStatus, Revision}; +use crate::live_events::{self as events, Command, Event, Payload}; +use crate::live_room::{self as room, verify_room, At, HeldGrant, RoomOutcome, RoomRun}; +use crate::output_tree::{tree_hash, verify_consistency}; + +pub mod corpus; + +/// The record this extension registers. +pub const CAPABILITY: &str = "wai.capture.take"; +/// The magic of a take manifest (§7.1). +pub const MANIFEST_MAGIC: [u8; 4] = *b"WTM1"; +/// The magic of an upload receipt (§6.2). +pub const RECEIPT_MAGIC: [u8; 4] = *b"WUR1"; +/// The magic of a consent record (§8.1). +pub const CONSENT_MAGIC: [u8; 4] = *b"WCN1"; +/// The version of the three records this revision defines. +pub const RECORD_VERSION: u8 = 1; +/// The domain of the take id (§3.2). +pub const TAKE_DOMAIN: &[u8] = b"wai:capture-take\x01"; +/// The take tree's leaf domain (§4.2); its node is the output tree's. +pub const LEAF_DOMAIN: &[u8] = b"wai:take-leaf\x01"; +/// The domain a manifest's signature is made over (§7.1). +pub const MANIFEST_DOMAIN: &[u8] = b"wai:capture-manifest\x01"; +/// The domain an upload receipt's signature is made over (§6.2). +pub const RECEIPT_DOMAIN: &[u8] = b"wai:take-upload\x01"; +/// The domain a consent record's signature is made over (§8.1). +pub const CONSENT_DOMAIN: &[u8] = b"wai:capture-consent\x01"; +/// The key-log authority a store's key needs (§6.4, jwp-receipts §7.5). +pub const STORE_AUTHORITY: &str = "capture/store"; +/// The grant attribute naming the principal a device captures for (§3.1). +pub const SUBJECT_ATTR: &str = "subject"; +/// The grant attribute marking that principal a minor (§3.1). +pub const MINOR_ATTR: &str = "minor"; +/// A chunk descriptor's length (§4.1). +pub const CHUNK_LEN: usize = 64; +/// The fixed part of a `take_commit` payload (§5.1). +pub const COMMIT_FIXED: usize = 126; +/// The most nodes a commitment's proof holds (§5.2). +pub const MAX_PROOF: usize = 64; +/// The most subjects a manifest lists (§7.2). +pub const MAX_DEPICTED: usize = 32; + +/// A commitment's `phase` (§5.1). +pub mod phase { + pub const OPEN: u8 = 1; + pub const RUNNING: u8 = 2; + pub const CLOSE: u8 = 3; +} + +/// An upload receipt's `state` (§6.2). +pub mod state { + pub const OPEN: u8 = 1; + pub const PROGRESS: u8 = 2; + pub const RESUME: u8 = 3; + pub const SEALED: u8 = 4; +} + +/// The purposes of §2, each a bit, with their names. +pub mod purpose { + pub const LIVE: u8 = 1; + pub const RECORD: u8 = 2; + pub const DISTRIBUTE: u8 = 4; + pub const TRAIN: u8 = 8; + /// Every purpose, in bit order, with its name. + pub const ALL: [(u8, &str); 4] = [(LIVE, "live"), (RECORD, "record"), (DISTRIBUTE, "distribute"), (TRAIN, "train")]; +} + +/// The claims a manifest makes (§7.1), each a bit. +pub mod claim { + pub const SINGLE_TAKE: u8 = 1; + pub const ALIGNED: u8 = 2; + pub const COMPLETE: u8 = 4; +} + +// --------------------------------------------------------------------------------------- +// §12 Reasons +// --------------------------------------------------------------------------------------- + +/// Why a take is refused, or why one of its claims fails (§12). +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Reason { + /// A code of live-rooms §11, or of live-events §9 through it. + Room(room::Reason), + RecordingNotPermitted, + TakeUnknown, + CommitMalformed, + DeviceNotBound, + ManifestInvalid, + ManifestMismatch, + StoreNotListed, + UploadReceiptInvalid, + UploadReceiptMismatch, + StoreOutsideRegion, + ConsentInvalid, + CommitChainBroken, + RootNotExtending, + TakeNotClosed, + ManifestNotCommitted, + ClockUnstable, + CaptureDiscontinuous, + ChunkTooLong, + CommitEarly, + CommitLate, + ChunkExtra, + ChunkReordered, + ChunkAltered, + Misaligned, + ChunkMissing, + UploadNotSealed, + ConsentMissing, + GuardianMissing, + ConsentRevoked, + ConsentExpired, + PurposeNotConsented, +} + +impl From for Reason { + fn from(r: room::Reason) -> Self { + Reason::Room(r) + } +} + +impl From for Reason { + fn from(r: events::Reason) -> Self { + Reason::Room(room::Reason::Events(r)) + } +} + +const TRUNCATED: Reason = Reason::Room(room::Reason::Events(events::Reason::Truncated)); +const MALFORMED: Reason = Reason::Room(room::Reason::Events(events::Reason::Malformed)); +const UNKNOWN_VERSION: Reason = Reason::Room(room::Reason::Events(events::Reason::UnknownVersion)); +/// `delivery_gap`, as a verdict. +pub const DELIVERY_GAP: Reason = Reason::Room(room::Reason::Events(events::Reason::DeliveryGap)); + +impl Reason { + /// The codes this extension adds, in §12's order. + pub const ALL: [Reason; 31] = [ + Reason::RecordingNotPermitted, + Reason::TakeUnknown, + Reason::CommitMalformed, + Reason::DeviceNotBound, + Reason::ManifestInvalid, + Reason::ManifestMismatch, + Reason::StoreNotListed, + Reason::UploadReceiptInvalid, + Reason::UploadReceiptMismatch, + Reason::StoreOutsideRegion, + Reason::ConsentInvalid, + Reason::CommitChainBroken, + Reason::RootNotExtending, + Reason::TakeNotClosed, + Reason::ManifestNotCommitted, + Reason::ClockUnstable, + Reason::CaptureDiscontinuous, + Reason::ChunkTooLong, + Reason::CommitEarly, + Reason::CommitLate, + Reason::ChunkExtra, + Reason::ChunkReordered, + Reason::ChunkAltered, + Reason::Misaligned, + Reason::ChunkMissing, + Reason::UploadNotSealed, + Reason::ConsentMissing, + Reason::GuardianMissing, + Reason::ConsentRevoked, + Reason::ConsentExpired, + Reason::PurposeNotConsented, + ]; + + /// The reason's code. + pub fn code(self) -> &'static str { + match self { + Reason::Room(r) => r.code(), + Reason::RecordingNotPermitted => "recording_not_permitted", + Reason::TakeUnknown => "take_unknown", + Reason::CommitMalformed => "commit_malformed", + Reason::DeviceNotBound => "device_not_bound", + Reason::ManifestInvalid => "manifest_invalid", + Reason::ManifestMismatch => "manifest_mismatch", + Reason::StoreNotListed => "store_not_listed", + Reason::UploadReceiptInvalid => "upload_receipt_invalid", + Reason::UploadReceiptMismatch => "upload_receipt_mismatch", + Reason::StoreOutsideRegion => "store_outside_region", + Reason::ConsentInvalid => "consent_invalid", + Reason::CommitChainBroken => "commit_chain_broken", + Reason::RootNotExtending => "root_not_extending", + Reason::TakeNotClosed => "take_not_closed", + Reason::ManifestNotCommitted => "manifest_not_committed", + Reason::ClockUnstable => "clock_unstable", + Reason::CaptureDiscontinuous => "capture_discontinuous", + Reason::ChunkTooLong => "chunk_too_long", + Reason::CommitEarly => "commit_early", + Reason::CommitLate => "commit_late", + Reason::ChunkExtra => "chunk_extra", + Reason::ChunkReordered => "chunk_reordered", + Reason::ChunkAltered => "chunk_altered", + Reason::Misaligned => "misaligned", + Reason::ChunkMissing => "chunk_missing", + Reason::UploadNotSealed => "upload_not_sealed", + Reason::ConsentMissing => "consent_missing", + Reason::GuardianMissing => "guardian_missing", + Reason::ConsentRevoked => "consent_revoked", + Reason::ConsentExpired => "consent_expired", + Reason::PurposeNotConsented => "purpose_not_consented", + } + } +} + +impl std::fmt::Display for Reason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.code()) + } +} + +impl std::error::Error for Reason {} + +// --------------------------------------------------------------------------------------- +// Reading +// --------------------------------------------------------------------------------------- + +fn sha256(parts: &[&[u8]]) -> [u8; 32] { + let mut h = Sha256::new(); + for p in parts { + h.update(p); + } + h.finalize().into() +} + +/// A cursor whose running out is `out`. +struct Rd<'a> { + b: &'a [u8], + p: usize, + out: Reason, +} + +impl<'a> Rd<'a> { + fn new(b: &'a [u8], p: usize, out: Reason) -> Self { + Rd { b, p, out } + } + fn take(&mut self, n: usize) -> Result<&'a [u8], Reason> { + let e = self.p.checked_add(n).filter(|&e| e <= self.b.len()).ok_or(self.out)?; + let s = &self.b[self.p..e]; + self.p = e; + Ok(s) + } + fn arr(&mut self) -> Result<[u8; N], Reason> { + Ok(self.take(N)?.try_into().expect("N bytes")) + } + fn u8(&mut self) -> Result { + Ok(self.take(1)?[0]) + } + fn u32(&mut self) -> Result { + Ok(u32::from_le_bytes(self.arr()?)) + } + fn u64(&mut self) -> Result { + Ok(u64::from_le_bytes(self.arr()?)) + } + fn i64(&mut self) -> Result { + Ok(i64::from_le_bytes(self.arr()?)) + } + fn done(&self) -> bool { + self.p == self.b.len() + } +} + +/// live-events §3.3's first two steps, with `magic` for `WEV1`. +fn read_head(b: &[u8], magic: &[u8; 4]) -> Result<(), Reason> { + if b.len() < 4 { + return Err(TRUNCATED); + } + if b[..4] != *magic { + return Err(MALFORMED); + } + if b.len() < 5 { + return Err(TRUNCATED); + } + if b[4] != RECORD_VERSION { + return Err(UNKNOWN_VERSION); + } + Ok(()) +} + +fn verify_sig(key: &[u8; 32], domain: &[u8], body: &[u8], sig: &[u8; 64]) -> Result<(), Reason> { + let mut m = domain.to_vec(); + m.extend_from_slice(body); + crate::sig::verify_strict(key, &m, sig).map_err(|e| match e { + crate::sig::SigError::BadKey => events::Reason::BadKey.into(), + crate::sig::SigError::BadSignature => events::Reason::BadSignature.into(), + }) +} + +fn sign(key: &SigningKey, domain: &[u8], body: &[u8]) -> [u8; 64] { + let mut m = domain.to_vec(); + m.extend_from_slice(body); + key.sign(&m).to_bytes() +} + +fn hex(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() +} + +// --------------------------------------------------------------------------------------- +// §3 The device, its principal and the take +// --------------------------------------------------------------------------------------- + +/// The take id (§3.2). +pub fn take_id(room: &[u8; 32], device: &[u8; 32], start: &[u8; 32]) -> [u8; 32] { + sha256(&[TAKE_DOMAIN, room, device, start]) +} + +fn attr<'a>(h: &'a HeldGrant, key: &str) -> Option<&'a str> { + h.grant.attrs.iter().find(|(k, _)| k == key).map(|(_, v)| v.as_str()) +} + +/// Whether the grant binds its device to `principal` (§3.1). +pub fn binds(h: &HeldGrant, principal: &[u8; 32]) -> bool { + match attr(h, SUBJECT_ATTR) { + Some(v) => v == hex(principal), + None => h.grant.principal == *principal, + } +} + +/// Whether the grant marks the principal it binds a minor (§3.1). +pub fn marks_minor(h: &HeldGrant) -> bool { + attr(h, MINOR_ATTR) == Some("true") +} + +// --------------------------------------------------------------------------------------- +// §4 Chunks and the take tree +// --------------------------------------------------------------------------------------- + +/// A chunk's descriptor (§4.1). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Chunk { + pub index: u64, + pub start: u64, + pub end: u64, + pub len: u64, + pub hash: [u8; 32], +} + +impl Chunk { + /// The descriptor of chunk `index`, captured from `start` to `end` on the device clock. + pub fn of(index: u64, start: u64, end: u64, bytes: &[u8]) -> Chunk { + Chunk { index, start, end, len: bytes.len() as u64, hash: sha256(&[bytes]) } + } + + /// Its 64 bytes. + pub fn to_bytes(&self) -> [u8; CHUNK_LEN] { + let mut o = [0u8; CHUNK_LEN]; + o[..8].copy_from_slice(&self.index.to_le_bytes()); + o[8..16].copy_from_slice(&self.start.to_le_bytes()); + o[16..24].copy_from_slice(&self.end.to_le_bytes()); + o[24..32].copy_from_slice(&self.len.to_le_bytes()); + o[32..].copy_from_slice(&self.hash); + o + } + + fn read(r: &mut Rd) -> Result { + Ok(Chunk { index: r.u64()?, start: r.u64()?, end: r.u64()?, len: r.u64()?, hash: r.arr()? }) + } + + /// Its leaf (§4.2). + pub fn leaf(&self) -> [u8; 32] { + sha256(&[LEAF_DOMAIN, &self.to_bytes()]) + } + + /// Whether `bytes` are this chunk: their digest and their length. + pub fn is(&self, bytes: &[u8]) -> bool { + bytes.len() as u64 == self.len && sha256(&[bytes]) == self.hash + } +} + +/// The leaves of `chunks`, in order. +pub fn leaves(chunks: &[Chunk]) -> Vec<[u8; 32]> { + chunks.iter().map(Chunk::leaf).collect() +} + +/// The root over `chunks` (§4.2): 32 zero bytes over none. +pub fn root(chunks: &[Chunk]) -> [u8; 32] { + if chunks.is_empty() { + [0; 32] + } else { + tree_hash(&leaves(chunks)) + } +} + +/// Whether (`size`, `new_root`) extends (`first`, `old_root`) by `proof` (§4.3), with the +/// two cases RFC 9162 leaves to the caller decided as the extension decides them. +pub fn extends(first: u64, old_root: &[u8; 32], size: u64, new_root: &[u8; 32], proof: &[[u8; 32]]) -> bool { + if first == 0 { + proof.is_empty() + } else if first == size { + proof.is_empty() && old_root == new_root + } else { + first < size && verify_consistency(first, size, old_root, new_root, proof) + } +} + +// --------------------------------------------------------------------------------------- +// §5 Commitments +// --------------------------------------------------------------------------------------- + +/// A `take_commit` payload (§5.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Commit { + pub take: [u8; 32], + pub n: u32, + pub phase: u8, + pub prev: [u8; 32], + pub first: u64, + pub size: u64, + pub root: [u8; 32], + pub offset: i64, + pub proof: Vec<[u8; 32]>, +} + +impl Commit { + /// Its bytes. + pub fn encode(&self) -> Vec { + let mut o = Vec::with_capacity(COMMIT_FIXED + 32 * self.proof.len()); + o.extend_from_slice(&self.take); + o.extend_from_slice(&self.n.to_le_bytes()); + o.push(self.phase); + o.extend_from_slice(&self.prev); + o.extend_from_slice(&self.first.to_le_bytes()); + o.extend_from_slice(&self.size.to_le_bytes()); + o.extend_from_slice(&self.root); + o.extend_from_slice(&self.offset.to_le_bytes()); + assert!(self.proof.len() <= MAX_PROOF, "a proof of at most 64 nodes"); + o.push(self.proof.len() as u8); + for p in &self.proof { + o.extend_from_slice(p); + } + o + } + + /// Read a payload (§5.2). + pub fn parse(b: &[u8]) -> Result { + let mut r = Rd::new(b, 0, Reason::CommitMalformed); + let take = r.arr()?; + let n = r.u32()?; + let phase = r.u8()?; + if !(phase::OPEN..=phase::CLOSE).contains(&phase) { + return Err(Reason::CommitMalformed); + } + let prev = r.arr()?; + let first = r.u64()?; + let size = r.u64()?; + if size < first { + return Err(Reason::CommitMalformed); + } + let root: [u8; 32] = r.arr()?; + if size == 0 && root != [0; 32] { + return Err(Reason::CommitMalformed); + } + let offset = r.i64()?; + let k = r.u8()? as usize; + if k > MAX_PROOF { + return Err(Reason::CommitMalformed); + } + let proof = (0..k).map(|_| r.arr()).collect::, _>>()?; + if !r.done() { + return Err(Reason::CommitMalformed); + } + Ok(Commit { take, n, phase, prev, first, size, root, offset, proof }) + } + + /// Whether it is an opening commitment (§5.3). + pub fn is_opening(&self) -> bool { + self.n == 0 && self.phase == phase::OPEN && self.prev == [0; 32] && self.first == 0 && self.size == 0 && self.proof.is_empty() + } +} + +// --------------------------------------------------------------------------------------- +// §6 Upload receipts +// --------------------------------------------------------------------------------------- + +/// An upload receipt (§6.2). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Receipt { + pub store: [u8; 32], + pub take: [u8; 32], + pub seq: u64, + pub prev: [u8; 32], + pub at: u64, + pub state: u8, + pub held: u64, + pub root: [u8; 32], + pub region: [u8; 2], + pub sig: [u8; 64], +} + +impl Receipt { + /// The bytes its digest and signature cover. + pub fn body(&self) -> Vec { + let mut o = Vec::with_capacity(160); + o.extend_from_slice(&RECEIPT_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.store); + o.extend_from_slice(&self.take); + o.extend_from_slice(&self.seq.to_le_bytes()); + o.extend_from_slice(&self.prev); + o.extend_from_slice(&self.at.to_le_bytes()); + o.push(self.state); + o.extend_from_slice(&self.held.to_le_bytes()); + o.extend_from_slice(&self.root); + o.extend_from_slice(&self.region); + o + } + + /// The whole record. + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// Its digest (§6.2). + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Signed by the store. + pub fn sign(mut self, store: &SigningKey) -> Receipt { + self.sig = sign(store, RECEIPT_DOMAIN, &self.body()); + self + } + + /// Read one record (§6.2). + pub fn read(b: &[u8]) -> Result { + read_head(b, &RECEIPT_MAGIC)?; + let mut r = Rd::new(b, 5, TRUNCATED); + let rc = Receipt { + store: r.arr()?, + take: r.arr()?, + seq: r.u64()?, + prev: r.arr()?, + at: r.u64()?, + state: r.u8()?, + held: r.u64()?, + root: r.arr()?, + region: r.arr()?, + sig: r.arr()?, + }; + if !r.done() { + return Err(MALFORMED); + } + Ok(rc) + } +} + +// --------------------------------------------------------------------------------------- +// §7 The take manifest +// --------------------------------------------------------------------------------------- + +/// A take manifest (§7.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Manifest { + pub room: [u8; 32], + pub device: [u8; 32], + pub principal: [u8; 32], + pub start: [u8; 32], + pub take: [u8; 32], + pub store: [u8; 32], + pub claims: u8, + pub purposes: u8, + pub chunks: Vec, + pub root: [u8; 32], + pub commits: Vec<[u8; 32]>, + /// Each subject's key and its consent's digest (zero for none). + pub depicted: Vec<([u8; 32], [u8; 32])>, + pub sig: [u8; 64], +} + +impl Manifest { + /// The bytes its digest and signature cover. + pub fn body(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&MANIFEST_MAGIC); + o.push(RECORD_VERSION); + for f in [&self.room, &self.device, &self.principal, &self.start, &self.take, &self.store] { + o.extend_from_slice(f); + } + o.push(self.claims); + o.push(self.purposes); + o.extend_from_slice(&(self.chunks.len() as u32).to_le_bytes()); + for c in &self.chunks { + o.extend_from_slice(&c.to_bytes()); + } + o.extend_from_slice(&self.root); + o.extend_from_slice(&(self.commits.len() as u32).to_le_bytes()); + for c in &self.commits { + o.extend_from_slice(c); + } + assert!(self.depicted.len() <= u8::MAX as usize); + o.push(self.depicted.len() as u8); + for (p, c) in &self.depicted { + o.extend_from_slice(p); + o.extend_from_slice(c); + } + o + } + + /// The whole record. + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// Its digest (§7.1). + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Signed by the device. + pub fn sign(mut self, device: &SigningKey) -> Manifest { + self.sig = sign(device, MANIFEST_DOMAIN, &self.body()); + self + } + + fn read(b: &[u8]) -> Result { + read_head(b, &MANIFEST_MAGIC)?; + let mut r = Rd::new(b, 5, TRUNCATED); + let (room, device, principal, start, take, store) = (r.arr()?, r.arr()?, r.arr()?, r.arr()?, r.arr()?, r.arr()?); + let (claims, purposes) = (r.u8()?, r.u8()?); + let n = r.u32()? as usize; + let mut chunks = Vec::with_capacity(n.min(b.len() / CHUNK_LEN)); + for _ in 0..n { + chunks.push(Chunk::read(&mut r)?); + } + let root = r.arr()?; + let m = r.u32()? as usize; + let mut commits = Vec::with_capacity(m.min(b.len() / 32)); + for _ in 0..m { + commits.push(r.arr()?); + } + let k = r.u8()? as usize; + let mut depicted = Vec::with_capacity(k); + for _ in 0..k { + depicted.push((r.arr()?, r.arr()?)); + } + let sig = r.arr()?; + if !r.done() { + return Err(MALFORMED); + } + Ok(Manifest { room, device, principal, start, take, store, claims, purposes, chunks, root, commits, depicted, sig }) + } + + /// §7.2's rules. + fn rules_hold(&self) -> bool { + let commits: BTreeSet<&[u8; 32]> = self.commits.iter().collect(); + self.claims & !0b111 == 0 + && self.purposes & !0b1111 == 0 + && !self.chunks.is_empty() + && self.chunks.iter().enumerate().all(|(i, c)| c.index == i as u64 && c.len >= 1) + && self.root == root(&self.chunks) + && !self.commits.is_empty() + && commits.len() == self.commits.len() + && (1..=MAX_DEPICTED).contains(&self.depicted.len()) + && self.depicted.windows(2).all(|w| w[0].0 < w[1].0) + && self.depicted.iter().any(|(p, _)| *p == self.principal) + && self.take == take_id(&self.room, &self.device, &self.start) + } + + /// Read a manifest, hold it to §7.2's rules, check its room and verify its signature: + /// §9.1 step 2. + pub fn parse(b: &[u8], room: &[u8; 32]) -> Result { + let m = Manifest::read(b)?; + if !m.rules_hold() { + return Err(Reason::ManifestInvalid); + } + if m.room != *room { + return Err(events::Reason::WrongRoom.into()); + } + verify_sig(&m.device, MANIFEST_DOMAIN, &b[..b.len() - 64], &m.sig)?; + Ok(m) + } +} + +// --------------------------------------------------------------------------------------- +// §8 Consent +// --------------------------------------------------------------------------------------- + +/// A consent record (§8.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Consent { + pub subject: [u8; 32], + pub minor: u8, + pub guardian: [u8; 32], + pub purposes: u8, + pub room: [u8; 32], + pub nbf: u64, + pub exp: u64, + pub nonce: [u8; 16], + pub sig: [u8; 64], +} + +impl Consent { + /// The bytes its digest and signature cover. + pub fn body(&self) -> Vec { + let mut o = Vec::with_capacity(135); + o.extend_from_slice(&CONSENT_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.subject); + o.push(self.minor); + o.extend_from_slice(&self.guardian); + o.push(self.purposes); + o.extend_from_slice(&self.room); + o.extend_from_slice(&self.nbf.to_le_bytes()); + o.extend_from_slice(&self.exp.to_le_bytes()); + o.extend_from_slice(&self.nonce); + o + } + + /// The whole record. + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// Its digest (§8.1). + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// The key that signs it: the guardian's when there is one, the subject's otherwise. + pub fn signer(&self) -> [u8; 32] { + if self.guardian == [0; 32] { self.subject } else { self.guardian } + } + + /// Signed by `key`, which should be [`Consent::signer`]'s. + pub fn sign(mut self, key: &SigningKey) -> Consent { + self.sig = sign(key, CONSENT_DOMAIN, &self.body()); + self + } + + /// Read a record, hold it to §8.2's rules and verify its signature. + pub fn parse(b: &[u8]) -> Result { + read_head(b, &CONSENT_MAGIC)?; + let mut r = Rd::new(b, 5, TRUNCATED); + let c = Consent { + subject: r.arr()?, + minor: r.u8()?, + guardian: r.arr()?, + purposes: r.u8()?, + room: r.arr()?, + nbf: r.u64()?, + exp: r.u64()?, + nonce: r.arr()?, + sig: r.arr()?, + }; + if !r.done() { + return Err(MALFORMED); + } + let ok = c.minor <= 1 + && (c.minor == 1 || c.guardian == [0; 32]) + && c.guardian != c.subject + && c.purposes != 0 + && c.purposes & !0b1111 == 0 + && c.nbf < c.exp; + if !ok { + return Err(Reason::ConsentInvalid); + } + verify_sig(&c.signer(), CONSENT_DOMAIN, &b[..b.len() - 64], &c.sig)?; + Ok(c) + } + + /// Whether it holds at second `s`. + pub fn holds_at(&self, s: u64) -> bool { + self.nbf <= s && s < self.exp + } +} + +// --------------------------------------------------------------------------------------- +// §9 Verification +// --------------------------------------------------------------------------------------- + +/// Where a take verification stopped (§9.1). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Place { + /// The room refused, at its own place. + Room(At), + Manifest, + /// A record of the room: its chain's index, and its index in that chain. + Record { chain: usize, record: usize }, + Store, + Receipt(usize), + Consent(usize), +} + +/// A claim's verdict (§9.4). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Verdict { + Holds, + Fails(Reason), +} + +impl Verdict { + fn of(r: Result<(), Reason>) -> Verdict { + r.map_or_else(Verdict::Fails, |_| Verdict::Holds) + } + + pub fn holds(self) -> bool { + self == Verdict::Holds + } +} + +/// The verdicts of §9.5. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Verdicts { + pub single_take: Verdict, + pub aligned: Verdict, + pub complete: Verdict, + /// By [`purpose::ALL`]'s order. + pub publishable: [Verdict; 4], + /// Every claim the manifest makes holds. + pub stands: bool, +} + +/// The outcome of a take verification (§9.5). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum TakeOutcome { + Refuse { at: Place, reason: Reason }, + Verdicts(Verdicts), +} + +/// Where a room-clock instant falls in the master (§10). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Position { + pub chunk: u64, + /// Microseconds into the chunk. + pub into_chunk: u64, + /// Microseconds into the master. + pub into_master: u64, +} + +/// A marker of the room mapped into the master (§10). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct MarkerAt { + pub event: [u8; 32], + pub t: u64, + pub at: Position, +} + +/// What a take verification holds at its end, for the corpus. +#[derive(Clone, Debug)] +pub struct TakeRun { + pub outcome: TakeOutcome, + pub take: Option<[u8; 32]>, + /// The digests of the held commitments, in order. + pub held: Vec<[u8; 32]>, + /// The last held commitment's size and root. + pub size: u64, + pub root: [u8; 32], + pub markers: Vec, + pub room: RoomRun, +} + +/// What a take verifier is given (§9.1). +#[derive(Clone, Copy, Debug)] +pub struct TakeInputs<'a> { + pub descriptor: &'a [u8], + pub grants: &'a [Vec], + pub head: Option<&'a str>, + pub chains: &'a [Vec>], + pub manifest: &'a [u8], + /// The parts, as (index, bytes), in the order received (§6.1). + pub parts: &'a [(u64, Vec)], + pub receipts: &'a [Vec], + pub consents: &'a [Vec], + /// The evaluation instant, in seconds since 1970. + pub at: u64, +} + +/// A record the room verifier accepted, once, in the merged order. +struct Seen { + chain: usize, + record: usize, + event: Event, + digest: [u8; 32], + grant: Option<[u8; 32]>, +} + +/// The accepted records of a room run, each once, in the merged order. +fn accepted(run: &RoomRun, chains: &[Vec>]) -> Vec { + let mut out = Vec::new(); + let mut digests = BTreeSet::new(); + for &(c, i, g) in &run.order { + let Ok(event) = Event::parse(&chains[c][i]) else { continue }; + let digest = event.digest(); + if digests.insert(digest) { + out.push(Seen { chain: c, record: i, event, digest, grant: g }); + } + } + out +} + +fn payload(e: &Event) -> Option { + events::parse_payload(e.kind, &e.payload, u16::MAX).ok() +} + +fn is_control(e: &Event, device: &[u8; 32], want_start: bool) -> Option { + match payload(e)? { + Payload::Control { target, command: Command::RecordStart { count_in_ms } } if target == *device && want_start => Some(count_in_ms), + Payload::Control { target, command: Command::RecordStop } if target == *device && !want_start => Some(0), + _ => None, + } +} + +/// One held commitment: its record, its payload and its grant. +struct Held<'a> { + seen: &'a Seen, + c: Commit, +} + +/// The take as §9.2 finds it in the room. +struct Found<'a> { + start: &'a Seen, + count_in_ms: u32, + stop: Option<&'a Seen>, + commits: Vec>, +} + +fn grant_of<'a>(run: &'a RoomRun, s: &Seen) -> Option<&'a HeldGrant> { + s.grant.and_then(|g| run.grants.iter().find(|h| h.digest == g)) +} + +/// §9.2. +fn find<'a>(run: &'a RoomRun, seen: &'a [Seen], m: &Manifest) -> Result, (Place, Reason)> { + let d = run.descriptor.as_ref().expect("a room that verified"); + let at_manifest = |r| (Place::Manifest, r); + if d.recording.mode == 0 { + return Err(at_manifest(Reason::RecordingNotPermitted)); + } + let pos = seen.iter().position(|s| s.digest == m.start).ok_or(at_manifest(Reason::TakeUnknown))?; + let start = &seen[pos]; + let count_in_ms = is_control(&start.event, &m.device, true).ok_or(at_manifest(Reason::TakeUnknown))?; + let stop = seen[pos + 1..].iter().find(|s| is_control(&s.event, &m.device, false).is_some()); + // Step 3: every take_commit of the device reads; the take's are the held ones. + let mut mine: Vec<&Seen> = seen.iter().filter(|s| s.event.principal == m.device && s.event.kind == events::kind::TAKE_COMMIT).collect(); + mine.sort_by_key(|s| s.event.seq); + let mut commits = Vec::new(); + for s in mine { + let c = Commit::parse(&s.event.payload).map_err(|r| (Place::Record { chain: s.chain, record: s.record }, r))?; + if c.take == m.take { + commits.push(Held { seen: s, c }); + } + } + // Step 4: the device is bound to the principal at each. + for h in &commits { + let bound = grant_of(run, h.seen).is_some_and(|g| binds(g, &m.principal)); + if !bound { + return Err((Place::Record { chain: h.seen.chain, record: h.seen.record }, Reason::DeviceNotBound)); + } + } + // Step 5: the held commitments are the listed ones, in order, with those not held left out. + let device_gap = matches!(&run.outcome, RoomOutcome::Gap(g) if g.iter().any(|g| g.principal == m.device)); + let held: Vec<[u8; 32]> = commits.iter().map(|h| h.seen.digest).collect(); + let held_set: BTreeSet<&[u8; 32]> = held.iter().collect(); + let all: BTreeSet<&[u8; 32]> = seen.iter().map(|s| &s.digest).collect(); + let listed_held: Vec<[u8; 32]> = m.commits.iter().filter(|c| held_set.contains(c)).copied().collect(); + let unheld_ok = m.commits.iter().filter(|c| !held_set.contains(c)).all(|c| !all.contains(c) && device_gap); + if listed_held != held || !unheld_ok { + return Err(at_manifest(Reason::ManifestMismatch)); + } + Ok(Found { start, count_in_ms, stop, commits }) +} + +/// §6.4 and §6.3. +fn check_upload(d: &room::Descriptor, head: Option<&str>, m: &Manifest, receipts: &[Vec]) -> Result, (Place, Reason)> { + if !d.origin.is_empty() { + // The room verifier held the head for the origin (live-rooms §5), so it reads. + let listed = head.and_then(|h| Revision::from_json(h).ok()).is_some_and(|rev| { + rev.keys.iter().any(|e| e.key == m.store && e.may_sign.iter().any(|a| a == STORE_AUTHORITY) && e.status != EntryStatus::Revoked) + }); + if !listed { + return Err((Place::Store, Reason::StoreNotListed)); + } + } + let mut prev: Option = None; + for (i, b) in receipts.iter().enumerate() { + let at = |r| (Place::Receipt(i), r); + let rc = Receipt::read(b).map_err(at)?; + let bad = Err(at(Reason::UploadReceiptInvalid)); + let fields = (state::OPEN..=state::SEALED).contains(&rc.state) + && rc.region.iter().all(u8::is_ascii_uppercase) + && (rc.held != 0 || rc.root == [0; 32]); + if !fields || rc.store != m.store || rc.take != m.take { + return bad; + } + verify_sig(&rc.store, RECEIPT_DOMAIN, &b[..b.len() - 64], &rc.sig).map_err(at)?; + let chained = match &prev { + None => rc.seq == 0 && rc.prev == [0; 32] && rc.state == state::OPEN && rc.held == 0, + Some(p) => { + let step = match rc.state { + state::PROGRESS => rc.held > p.held, + state::RESUME | state::SEALED => rc.held == p.held, + _ => false, + }; + rc.seq == i as u64 && rc.prev == p.digest() && rc.at >= p.at && rc.region == p.region && p.state != state::SEALED && step + } + }; + if !chained { + return bad; + } + if rc.held > m.chunks.len() as u64 || rc.root != root(&m.chunks[..rc.held as usize]) { + return Err(at(Reason::UploadReceiptMismatch)); + } + if !d.recording.regions.is_empty() && !d.recording.regions.contains(&rc.region) { + return Err(at(Reason::StoreOutsideRegion)); + } + prev = Some(rc); + } + Ok(prev) +} + +/// The timing of §9.3, from the room's policy and the take's mapping. +struct Clock { + interval: i128, + jitter: i128, + offset: i128, +} + +impl Clock { + fn map(&self, d: u64) -> i128 { + d as i128 + self.offset + } +} + +/// §9.4 `single-take`. +fn single_take(f: &Found, m: &Manifest, clock: &Clock, parts: &[(u64, Vec)]) -> Result<(), Reason> { + let held: BTreeSet<[u8; 32]> = f.commits.iter().map(|h| h.seen.digest).collect(); + // 1. Every listed commitment is held. + if m.commits.iter().any(|c| !held.contains(c)) { + return Err(DELIVERY_GAP); + } + // 2. The chain of §5.3. + let cs: Vec<&Commit> = f.commits.iter().map(|h| &h.c).collect(); + let chain_ok = cs.first().is_some_and(|c| c.is_opening()) + && f.commits.windows(2).all(|w| { + let (p, c) = (&w[0].c, &w[1].c); + p.phase != phase::CLOSE && c.phase != phase::OPEN && c.n == p.n.wrapping_add(1) && c.prev == w[0].seen.digest && c.first == p.size + }); + if !chain_ok { + return Err(Reason::CommitChainBroken); + } + // 3. Each extends its predecessor. + if !cs.windows(2).all(|w| extends(w[1].first, &w[0].root, w[1].size, &w[1].root, &w[1].proof)) { + return Err(Reason::RootNotExtending); + } + // 4. Closed, after a stop. + let last = cs.last().expect("an opening commitment"); + if last.phase != phase::CLOSE || f.stop.is_none() { + return Err(Reason::TakeNotClosed); + } + // 5. The manifest's chunks are the committed ones. + let n = m.chunks.len() as u64; + if n != last.size || cs.iter().any(|c| c.size > 0 && root(&m.chunks[..c.size as usize]) != c.root) { + return Err(Reason::ManifestNotCommitted); + } + // 6. The clock mapping held. + if cs.iter().any(|c| (c.offset as i128 - clock.offset).abs() > clock.jitter) { + return Err(Reason::ClockUnstable); + } + // 7, 8. The chunks tile the capture, none longer than the interval. + let ch = &m.chunks; + if ch.iter().any(|c| c.start >= c.end) || ch.windows(2).any(|w| w[1].start != w[0].end) { + return Err(Reason::CaptureDiscontinuous); + } + if ch.iter().any(|c| (c.end - c.start) as i128 > clock.interval) { + return Err(Reason::ChunkTooLong); + } + // 9, 10. Each commitment came after its chunks' capture, and within I + J. + let stop = f.stop.expect("checked at 4"); + let early = f.commits[0].seen.event.t < f.start.event.t + || f.commits.last().is_some_and(|h| h.seen.event.t < stop.event.t) + || f.commits.iter().any(|h| { + let t = h.seen.event.t as i128; + ch[h.c.first as usize..h.c.size as usize].iter().any(|c| t + clock.jitter < clock.map(c.end)) + }); + if early { + return Err(Reason::CommitEarly); + } + let late = f.commits.iter().any(|h| { + let t = h.seen.event.t as i128; + ch[h.c.first as usize..h.c.size as usize].iter().any(|c| t > clock.map(c.end) + clock.interval + clock.jitter) + }); + if late { + return Err(Reason::CommitLate); + } + // 11. Every part is the chunk committed at its index. + for (index, bytes) in parts { + if *index >= n { + return Err(Reason::ChunkExtra); + } + if !ch[*index as usize].is(bytes) { + let other = ch.iter().any(|c| c.index != *index && c.is(bytes)); + return Err(if other { Reason::ChunkReordered } else { Reason::ChunkAltered }); + } + } + Ok(()) +} + +/// §9.4 `aligned`. +fn aligned(f: &Found, m: &Manifest, clock: &Clock) -> Result<(), Reason> { + let first = m.commits[0]; + let Some(open) = f.commits.first() else { return Err(DELIVERY_GAP) }; + if open.seen.digest != first { + return Err(DELIVERY_GAP); + } + if !open.c.is_opening() { + return Err(Reason::CommitChainBroken); + } + let adds = f.commits.iter().find(|h| h.c.size > 0).ok_or(Reason::ManifestNotCommitted)?; + if adds.c.size > m.chunks.len() as u64 || root(&m.chunks[..adds.c.size as usize]) != adds.c.root { + return Err(Reason::ManifestNotCommitted); + } + let capture = f.start.event.t as i128 + f.count_in_ms as i128 * 1000; + if (clock.map(m.chunks[0].start) - capture).abs() > clock.jitter { + return Err(Reason::Misaligned); + } + Ok(()) +} + +/// §9.4 `complete`. +fn complete(f: &Found, m: &Manifest, parts: &[(u64, Vec)], last_receipt: Option<&Receipt>) -> Result<(), Reason> { + let (s, r) = f.commits.last().map_or((0, [0; 32]), |h| (h.c.size, h.c.root)); + if s == 0 || s > m.chunks.len() as u64 || root(&m.chunks[..s as usize]) != r { + return Err(Reason::ManifestNotCommitted); + } + for c in &m.chunks[..s as usize] { + if !parts.iter().any(|(i, b)| *i == c.index && c.is(b)) { + return Err(Reason::ChunkMissing); + } + } + if !last_receipt.is_some_and(|rc| rc.state == state::SEALED && rc.held == s) { + return Err(Reason::UploadNotSealed); + } + Ok(()) +} + +/// §9.4 `publishable` for purpose `p`. +#[allow(clippy::too_many_arguments)] +fn publishable( + p: u8, + m: &Manifest, + consents: &[Consent], + room_id: &[u8; 32], + revoked: &BTreeSet<[u8; 32]>, + principal_minor: bool, + start_s: u64, + at: u64, +) -> Result<(), Reason> { + for (subject, digest) in &m.depicted { + let c = consents + .iter() + .find(|c| *digest != [0; 32] && c.digest() == *digest && c.subject == *subject && (c.room == [0; 32] || c.room == *room_id)) + .ok_or(Reason::ConsentMissing)?; + let minor = c.minor == 1 || (*subject == m.principal && principal_minor); + if minor && c.guardian == [0; 32] { + return Err(Reason::GuardianMissing); + } + if revoked.contains(&c.digest()) { + return Err(Reason::ConsentRevoked); + } + if !c.holds_at(start_s) || !c.holds_at(at) { + return Err(Reason::ConsentExpired); + } + if c.purposes & purpose::RECORD == 0 || c.purposes & p == 0 { + return Err(Reason::PurposeNotConsented); + } + } + Ok(()) +} + +/// Where room-clock instant `t` falls in a master of `chunks` under offset `offset` (§10). +pub fn position(chunks: &[Chunk], offset: i64, t: u64) -> Option { + let d = t as i128 - offset as i128; + let first = chunks.first()?; + let c = chunks.iter().find(|c| (c.start as i128) <= d && d < c.end as i128)?; + Some(Position { chunk: c.index, into_chunk: (d - c.start as i128) as u64, into_master: (d - first.start as i128) as u64 }) +} + +/// The C2PA `streamId` of a take (§11.1): the take id's first 16 bytes as an RFC 9562 UUID +/// of version 8. +pub fn stream_id(take: &[u8; 32]) -> String { + let mut u: [u8; 16] = take[..16].try_into().expect("16 bytes"); + u[6] = (u[6] & 0x0F) | 0x80; + u[8] = (u[8] & 0x3F) | 0x80; + let h = hex(&u); + format!("{}-{}-{}-{}-{}", &h[..8], &h[8..12], &h[12..16], &h[16..20], &h[20..]) +} + +/// Verify a take (§9). +pub fn verify_take(i: &TakeInputs) -> TakeRun { + let room_run = verify_room(i.descriptor, i.grants, i.head, i.chains); + let mut run = TakeRun { outcome: TakeOutcome::Verdicts(fail_all()), take: None, held: vec![], size: 0, root: [0; 32], markers: vec![], room: room_run }; + let refuse = |run: &mut TakeRun, at: Place, reason: Reason| run.outcome = TakeOutcome::Refuse { at, reason }; + // Step 1: the room. + if let RoomOutcome::Refuse { at, reason } = &run.room.outcome { + let (at, reason) = (*at, *reason); + refuse(&mut run, Place::Room(at), reason.into()); + return run; + } + let room_id = run.room.room.expect("a room that verified"); + let d = run.room.descriptor.clone().expect("a room that verified"); + // Step 2: the manifest. + let m = match Manifest::parse(i.manifest, &room_id) { + Ok(m) => m, + Err(r) => { + refuse(&mut run, Place::Manifest, r); + return run; + } + }; + run.take = Some(m.take); + // Step 3: the take in the room. + let seen = accepted(&run.room, i.chains); + let f = match find(&run.room, &seen, &m) { + Ok(f) => f, + Err((at, r)) => { + refuse(&mut run, at, r); + return run; + } + }; + // Step 4: the store and the receipts. + let last_receipt = match check_upload(&d, i.head, &m, i.receipts) { + Ok(r) => r, + Err((at, r)) => { + refuse(&mut run, at, r); + return run; + } + }; + // Step 5: the consents. + let mut consents = Vec::with_capacity(i.consents.len()); + for (k, b) in i.consents.iter().enumerate() { + match Consent::parse(b) { + Ok(c) => consents.push(c), + Err(r) => { + refuse(&mut run, Place::Consent(k), r); + return run; + } + } + } + // Step 6: the verdicts. + let clock = Clock { + interval: d.recording.commit_interval_ms as i128 * 1000, + jitter: d.recording.jitter_ms as i128 * 1000, + offset: f.commits.first().map_or(0, |h| h.c.offset as i128), + }; + let revoked = if d.origin.is_empty() { + BTreeSet::new() + } else { + i.head.and_then(|h| Revision::from_json(h).ok()).map(|r| r.revoked_modules.into_iter().collect()).unwrap_or_default() + }; + let principal_minor = f.commits.first().and_then(|h| grant_of(&run.room, h.seen)).is_some_and(marks_minor); + let start_s = (d.t0_us + f.start.event.t) / 1_000_000; + let single = Verdict::of(single_take(&f, &m, &clock, i.parts)); + let align = Verdict::of(aligned(&f, &m, &clock)); + let whole = Verdict::of(complete(&f, &m, i.parts, last_receipt.as_ref())); + let publish = purpose::ALL.map(|(p, _)| Verdict::of(publishable(p, &m, &consents, &room_id, &revoked, principal_minor, start_s, i.at))); + let claimed = [(claim::SINGLE_TAKE, single), (claim::ALIGNED, align), (claim::COMPLETE, whole)]; + let stands = claimed.iter().all(|(b, v)| m.claims & b == 0 || v.holds()) + && purpose::ALL.iter().zip(&publish).all(|((b, _), v)| m.purposes & b == 0 || v.holds()); + run.outcome = TakeOutcome::Verdicts(Verdicts { single_take: single, aligned: align, complete: whole, publishable: publish, stands }); + run.held = f.commits.iter().map(|h| h.seen.digest).collect(); + if let Some(h) = f.commits.last() { + (run.size, run.root) = (h.c.size, h.c.root); + } + if align.holds() { + let offset = f.commits[0].c.offset; + run.markers = seen + .iter() + .filter(|s| s.event.kind == events::kind::MARKER) + .filter_map(|s| position(&m.chunks, offset, s.event.t).map(|at| MarkerAt { event: s.digest, t: s.event.t, at })) + .collect(); + } + run +} + +fn fail_all() -> Verdicts { + let v = Verdict::Fails(Reason::TakeUnknown); + Verdicts { single_take: v, aligned: v, complete: v, publishable: [v; 4], stands: false } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn chunks(n: u64) -> Vec { + (0..n).map(|i| Chunk::of(i, 1_000 * i, 1_000 * (i + 1), &[i as u8; 7])).collect() + } + + #[test] + fn the_root_of_a_prefix_is_extended_by_its_proof() { + let c = chunks(11); + let l = leaves(&c); + for m in 0..=11usize { + for n in m..=11usize { + let p = crate::output_tree::consistency_proof(m, &l[..n]); + assert!(extends(m as u64, &root(&c[..m]), n as u64, &root(&c[..n]), &p), "m = {m}, n = {n}"); + } + } + // A rewritten chunk 2 is a history that does not extend. + let mut r = c.clone(); + r[2] = Chunk::of(2, 2_000, 3_000, b"edited"); + let p = crate::output_tree::consistency_proof(4, &leaves(&r[..8])); + assert!(!extends(4, &root(&c[..4]), 8, &root(&r[..8]), &p)); + // Equal sizes extend only with equal roots, and never with a proof. + assert!(extends(5, &root(&c[..5]), 5, &root(&c[..5]), &[])); + assert!(!extends(5, &root(&c[..5]), 5, &root(&r[..5]), &[])); + assert!(!extends(0, &[0; 32], 3, &root(&c[..3]), &[[1; 32]])); + } + + #[test] + fn a_leaf_binds_every_field_of_its_descriptor() { + let c = Chunk::of(3, 10, 20, b"bytes"); + let base = c.leaf(); + for f in [Chunk { index: 4, ..c }, Chunk { start: 11, ..c }, Chunk { end: 21, ..c }, Chunk { len: 6, ..c }] { + assert_ne!(f.leaf(), base); + } + assert!(c.is(b"bytes") && !c.is(b"bytez") && !c.is(b"bytes!")); + // The take tree's leaf domain is not the output tree's. + assert_ne!(LEAF_DOMAIN, crate::output_tree::LEAF_DOMAIN); + } + + #[test] + fn a_commit_payload_round_trips_and_is_read_strictly() { + let c = Commit { take: [7; 32], n: 3, phase: phase::RUNNING, prev: [8; 32], first: 4, size: 6, root: [9; 32], offset: -5_000_000_000, proof: vec![[1; 32], [2; 32]] }; + let b = c.encode(); + assert_eq!(b.len(), COMMIT_FIXED + 64); + assert_eq!(Commit::parse(&b), Ok(c.clone())); + let mut t = b.clone(); + t.push(0); + assert_eq!(Commit::parse(&t), Err(Reason::CommitMalformed)); + assert_eq!(Commit::parse(&b[..b.len() - 1]), Err(Reason::CommitMalformed)); + let mut p = b.clone(); + p[36] = 4; + assert_eq!(Commit::parse(&p), Err(Reason::CommitMalformed)); + let z = Commit { first: 0, size: 0, proof: vec![], ..c.clone() }.encode(); + assert_eq!(Commit::parse(&z), Err(Reason::CommitMalformed), "a root over no chunk is zero"); + let back = Commit { first: 7, ..c }.encode(); + assert_eq!(Commit::parse(&back), Err(Reason::CommitMalformed), "size below first"); + } + + #[test] + fn the_stream_id_is_a_version_8_uuid() { + let s = stream_id(&[0xFF; 32]); + assert_eq!(s, "ffffffff-ffff-8fff-bfff-ffffffffffff"); + let s = stream_id(&[0; 32]); + assert_eq!(s, "00000000-0000-8000-8000-000000000000"); + } + + #[test] + fn an_instant_maps_into_the_master() { + let c = chunks(4); + // The room clock is the device clock + 500. + assert_eq!(position(&c, 500, 500), Some(Position { chunk: 0, into_chunk: 0, into_master: 0 })); + assert_eq!(position(&c, 500, 2_750), Some(Position { chunk: 2, into_chunk: 250, into_master: 2_250 })); + assert_eq!(position(&c, 500, 4_500), None, "the end is outside the master"); + assert_eq!(position(&c, 500, 499), None); + } + + #[test] + fn a_consent_is_signed_by_the_guardian_of_a_minor() { + let subject = SigningKey::from_bytes(&[1; 32]); + let guardian = SigningKey::from_bytes(&[2; 32]); + let base = Consent { + subject: subject.verifying_key().to_bytes(), + minor: 1, + guardian: guardian.verifying_key().to_bytes(), + purposes: purpose::RECORD | purpose::LIVE, + room: [0; 32], + nbf: 10, + exp: 20, + nonce: [3; 16], + sig: [0; 64], + }; + assert!(Consent::parse(&base.clone().sign(&guardian).to_bytes()).is_ok()); + assert_eq!(Consent::parse(&base.clone().sign(&subject).to_bytes()), Err(events::Reason::BadSignature.into())); + let adult_with_guardian = Consent { minor: 0, ..base.clone() }.sign(&guardian); + assert_eq!(Consent::parse(&adult_with_guardian.to_bytes()), Err(Reason::ConsentInvalid)); + let window = Consent { nbf: 20, ..base.clone() }.sign(&guardian); + assert_eq!(Consent::parse(&window.to_bytes()), Err(Reason::ConsentInvalid)); + let c = base.sign(&guardian); + assert!(c.holds_at(10) && c.holds_at(19) && !c.holds_at(20) && !c.holds_at(9)); + } + + #[test] + fn the_reasons_are_distinct() { + let codes: BTreeSet<&str> = Reason::ALL.iter().map(|r| r.code()).collect(); + assert_eq!(codes.len(), Reason::ALL.len()); + for r in Reason::ALL { + assert!(room::Reason::from_code(r.code()).is_none(), "{r} is also a room code"); + } + } +} diff --git a/wai/wai-rs/src/capture_take/corpus.rs b/wai/wai-rs/src/capture_take/corpus.rs new file mode 100644 index 000000000..93856dbea --- /dev/null +++ b/wai/wai-rs/src/capture_take/corpus.rs @@ -0,0 +1,964 @@ +//! The conformance corpus of extensions/capture-binding.md §13: `live-conformance/takes/vectors.json`. +//! +//! [`generate`] writes it from fixed seeds: every key is SHA-256 of a fixed label and an +//! index, every time is a constant, every chunk's bytes are SHA-256 output of a fixed label, +//! and Ed25519 signing is deterministic (RFC 8032), so the file is the same bytes on every +//! machine. Each vector states the outcome it was written to have, and the generator +//! asserts that this module reaches it before writing it, so a defect here cannot write +//! itself into the corpus as expected. +//! +//! [`verify`] checks a corpus file against this module. `live-conformance/capture_take_verify.py` +//! checks the same file from the extension's text, sharing no code with this module. + +use super::*; +use crate::key_log::{commitment, KeyEntry}; +use crate::live_events::{Marker, Policy}; +use crate::live_room::{media, power, registered_profile, Caps, Descriptor, Detail, Grant, Limits, Recording, Review, Role, NO_CEILING}; +use crate::output_tree::consistency_proof; +use serde_json::{json, Map, Value}; + +/// The rooms' `t0`: 2026-10-16T00:00:00Z, in microseconds and in seconds. +const T0_US: u64 = 1_792_108_800_000_000; +const T0_S: u64 = T0_US / 1_000_000; +const S: u64 = 1_000_000; +const MS: u64 = 1_000; +const ORIGIN: &str = "https://lessons.example"; +/// The evaluation instant of every vector: a day after `t0`. +const EVALUATED_AT: u64 = T0_S + 86_400; + +const AUTHORITY: u8 = 0; +const RELAY: u8 = 1; +const DIRECTOR: u8 = 2; +const DEVICE: u8 = 3; +const PERFORMER: u8 = 4; +const VIEWER: u8 = 5; +const STORE: u8 = 6; +const GUARDIAN: u8 = 7; +const MINOR: u8 = 8; +const IMPOSTOR: u8 = 9; +const LOG_ROOT: u8 = 10; +const LOG_NEXT: u8 = 11; + +const PRINCIPALS: [(&str, u8); 12] = [ + ("authority", AUTHORITY), + ("relay", RELAY), + ("director", DIRECTOR), + ("device", DEVICE), + ("performer", PERFORMER), + ("viewer", VIEWER), + ("store", STORE), + ("guardian", GUARDIAN), + ("minor", MINOR), + ("impostor", IMPOSTOR), + ("log_root", LOG_ROOT), + ("log_next", LOG_NEXT), +]; + +fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&sha256(&[b"wai:capture-take/corpus/key\x00", &[i]])) +} + +fn pk(i: u8) -> [u8; 32] { + key(i).verifying_key().to_bytes() +} + +fn unhex(s: &str) -> Option> { + if !s.len().is_multiple_of(2) { + return None; + } + (0..s.len()).step_by(2).map(|i| u8::from_str_radix(s.get(i..i + 2)?, 16).ok()).collect() +} + +fn bits(ks: &[u8]) -> [u8; 32] { + let mut b = [0u8; 32]; + for &k in ks { + b[(k / 8) as usize] |= 1 << (k % 8); + } + b +} + +/// The bytes of chunk `i`: 48 to 111 bytes of SHA-256 output under a fixed label. +fn chunk_bytes(label: &[u8], i: usize) -> Vec { + let len = 48 + (i * 37) % 64; + let mut out = Vec::with_capacity(len + 32); + let mut j = 0u8; + while out.len() < len { + out.extend_from_slice(&sha256(&[b"wai:capture-take/corpus/chunk\x00", label, &(i as u64).to_le_bytes(), &[j]])); + j += 1; + } + out.truncate(len); + out +} + +// ---- the room ---- + +fn role(name: &str, publish: u8, max_layer: u8, powers: u8, events: &[u8]) -> Role { + Role { name: name.into(), caps: Caps { publish, subscribe: true, max_layer, powers }, events: bits(events) } +} + +fn director() -> Role { + use events::kind::*; + role("director", 1, 2, power::MODERATE | power::DIRECT | power::RECORD, &[META, CHAT, REACTION, MARKER, CONTROL, CAPTION, DECISION]) +} + +fn performer() -> Role { + use events::kind::*; + role("performer", 1 | 2, 2, 0, &[CHAT, REACTION, MARKER, TAKE_COMMIT]) +} + +fn audience() -> Role { + use events::kind::*; + role("audience", 0, 1, 0, &[CHAT, REACTION]) +} + +fn kinds_of(b: &[u8; 32]) -> Vec { + (0..=255u8).filter(|k| b[(k / 8) as usize] & (1 << (k % 8)) != 0).collect() +} + +/// How the store's receipts run. +#[derive(Clone, Copy, PartialEq, Eq)] +enum Upload { + /// open, progress to every chunk, sealed. + Whole, + /// open, progress to 4, resume at 4, progress to every chunk, sealed. + Resumed, + /// open, progress to `n` and no further. + Stopped(usize), + /// open, progress to every chunk, and no seal. + Unsealed, +} + +/// How the parts arrive. +#[derive(Clone, Copy, PartialEq, Eq)] +enum Parts { + Whole, + /// Chunk 3 sent twice, once before the interruption and once after. + Resumed, + Missing(usize), + Altered(usize), + Swapped(usize, usize), + Extra, +} + +/// The consent a scene gives its principal. +#[derive(Clone, Copy)] +struct ConsentPlan { + subject: u8, + minor: u8, + guardian: Option, + /// The key that signs it; the signer of §8.1 unless a vector forges it. + signer: u8, + purposes: u8, + exp: u64, + given: bool, + revoked: bool, +} + +/// One take, with every knob a vector turns. +#[derive(Clone)] +struct Scene { + label: &'static str, + mode: u8, + regions: Vec<[u8; 2]>, + store_listed: bool, + /// The device grant's attributes. + attrs: Vec<(String, String)>, + /// Whether the device's grant may send `take_commit`. + device_commits: bool, + count_in_ms: u32, + start_t: u64, + /// Each chunk's capture range on the room clock. + chunks: Vec<(u64, u64)>, + stop_t: u64, + /// The offset (room clock − device clock). + offset: i64, + /// A commitment `n` whose stated offset differs by this much. + offset_jump: Option<(u32, i64)>, + /// A commitment `n` sent at this `t` instead. + late: Option<(u32, u64)>, + /// A commitment `n` that adds one chunk more than it has completed. + early_add: Option, + /// A commitment `n` whose `prev` is zero. + break_prev: Option, + /// From commitment `n` on, the device commits a history whose chunk `c` is edited. + rewrite: Option<(u32, usize)>, + /// The manifest and the parts carry chunk `c` edited, which no commitment committed. + manifest_edit: Option, + no_close: bool, + /// The commitment `n` the relay does not deliver. + drop: Option, + /// A `take_commit` of the device that does not read, after the close. + malformed: bool, + principal: u8, + consent: Option, + upload: Upload, + parts: Parts, + region: [u8; 2], + /// Receipt 1 states `seq` 2. + receipt_seq_skip: bool, + /// Receipt 1's root is not the manifest's. + receipt_root: bool, + /// The manifest names another start: the viewer's chat. + start_is_chat: bool, + /// The manifest leaves commitment `n` out. + omit: Option, + /// The manifest's claims byte. + claims: u8, + /// The manifest names another room. + other_room: bool, + /// The manifest's signature has a bit flipped. + flip_sig: bool, +} + +fn lesson(label: &'static str) -> Scene { + let capture = 6 * S; + Scene { + label, + mode: 1, + regions: vec![*b"DE", *b"FR"], + store_listed: true, + attrs: vec![("featured".into(), "true".into()), ("subject".into(), hex(&pk(PERFORMER)))], + device_commits: true, + count_in_ms: 4_000, + start_t: 2 * S, + chunks: (0..10).map(|i| (capture + i * S, capture + (i + 1) * S)).collect(), + stop_t: 16 * S, + offset: -5_000_000_000, + offset_jump: None, + late: None, + early_add: None, + break_prev: None, + rewrite: None, + manifest_edit: None, + no_close: false, + drop: None, + malformed: false, + principal: PERFORMER, + consent: Some(ConsentPlan { + subject: PERFORMER, + minor: 0, + guardian: None, + signer: PERFORMER, + purposes: purpose::LIVE | purpose::RECORD | purpose::DISTRIBUTE, + exp: T0_S + 30 * 86_400, + given: true, + revoked: false, + }), + upload: Upload::Whole, + parts: Parts::Whole, + region: *b"DE", + receipt_seq_skip: false, + receipt_root: false, + start_is_chat: false, + omit: None, + claims: claim::SINGLE_TAKE | claim::ALIGNED | claim::COMPLETE, + other_room: false, + flip_sig: false, + } +} + +/// A principal's chain being written. +struct Author { + who: u8, + seq: u64, + prev: [u8; 32], + records: Vec>, +} + +struct Room { + room: [u8; 32], + authors: Vec, +} + +impl Room { + fn emit(&mut self, who: u8, t: u64, p: &Payload) -> [u8; 32] { + self.raw(who, t, p.kind(), p.encode()) + } + + fn raw(&mut self, who: u8, t: u64, kind: u8, payload: Vec) -> [u8; 32] { + let room = self.room; + let a = match self.authors.iter().position(|a| a.who == who) { + Some(i) => &mut self.authors[i], + None => { + self.authors.push(Author { who, seq: 0, prev: [0; 32], records: vec![] }); + self.authors.last_mut().expect("just pushed") + } + }; + let ev = Event::sign(&key(who), room, a.seq, a.prev, t, None, kind, payload); + a.seq += 1; + a.prev = ev.digest(); + a.records.push(ev.to_bytes()); + a.prev + } + + fn life(&mut self, t: u64, subject: u8, d: Detail) { + self.emit(RELAY, t, &Payload::Lifecycle { kind: d.kind(), subject: pk(subject), detail: d.encode() }); + } +} + +/// A scene written out: everything a take verifier is given. +struct Written { + descriptor: Vec, + grants: Vec>, + head: Option, + chains: Vec>>, + manifest: Vec, + parts: Vec<(u64, Vec)>, + receipts: Vec>, + consents: Vec>, +} + +fn write(s: &Scene) -> Written { + // The descriptor. + let d = Descriptor { + authority: pk(AUTHORITY), + clock: pk(RELAY), + t0_us: T0_US, + tick_us: S, + origin: ORIGIN.into(), + limits: Limits { max_present: 8, max_publishers: 3, reval_s: 300, ceiling: Policy::default() }, + roles: vec![director(), performer(), audience()], + slots: vec![], + profiles: ["speech", "music", "camera-1080"].iter().map(|n| registered_profile(n).expect("registered")).collect(), + review: Review { kinds: [0; 32], deadline_ms: 0, fallback: 0 }, + recording: if s.mode == 0 { + Recording { mode: 0, retention_days: 30, commit_interval_ms: 0, jitter_ms: 0, regions: s.regions.clone() } + } else { + Recording { mode: s.mode, retention_days: 30, commit_interval_ms: 2_000, jitter_ms: 500, regions: s.regions.clone() } + }, + sig: [0; 64], + } + .sign(&key(AUTHORITY)); + let room_id = d.room_id(); + // The grants. + let grant = |who: u8, role: usize| { + let r = &d.roles[role]; + Grant { + room: room_id, + principal: pk(who), + prev: [0; 32], + effective: 0, + nbf: T0_S - 3_600, + exp: T0_S + 86_400, + role: role as u8, + caps: r.caps, + precedence: 0, + once: [0; 16], + viewer: [0; 16], + policy: Policy::with_kinds(&kinds_of(&r.events)), + joules_ceiling: NO_CEILING, + funds_ceiling: NO_CEILING, + currency: [0; 3], + profiles: vec![], + origins: vec!["https://relay.example".into()], + attrs: vec![], + sig: [0; 64], + } + }; + let gd = Grant { profiles: vec![0], ..grant(DIRECTOR, 0) }.sign(&key(AUTHORITY)); + let mut gp = Grant { profiles: vec![1, 2], attrs: s.attrs.clone(), ..grant(DEVICE, 1) }; + if !s.device_commits { + use events::kind::*; + gp.policy = Policy::with_kinds(&[CHAT, REACTION, MARKER]); + } + let gp = gp.sign(&key(AUTHORITY)); + let gv = grant(VIEWER, 2).sign(&key(AUTHORITY)); + let grants = vec![gd.to_bytes(), gp.to_bytes(), gv.to_bytes()]; + // The consent. + let consent = s.consent.map(|c| { + Consent { + subject: pk(c.subject), + minor: c.minor, + guardian: c.guardian.map_or([0; 32], pk), + purposes: c.purposes, + room: room_id, + nbf: T0_S - 86_400, + exp: c.exp, + nonce: sha256(&[b"wai:capture-take/corpus/nonce", s.label.as_bytes()])[..16].try_into().expect("16 bytes"), + sig: [0; 64], + } + .sign(&key(c.signer)) + }); + // The key log. + let mut keys = vec![KeyEntry::active("room-authority", pk(AUTHORITY), &[room::KEY_LOG_AUTHORITY])]; + if s.store_listed { + keys.push(KeyEntry::active("take-store", pk(STORE), &[STORE_AUTHORITY])); + } + let revoked = match (&consent, s.consent) { + (Some(c), Some(p)) if p.revoked => vec![c.digest()], + _ => vec![], + }; + let revision = Revision { + origin: ORIGIN.into(), + seq: 0, + prev: None, + issued_at: "2026-10-15T00:00:00Z".into(), + root: [0; 32], + next_root: commitment(&pk(LOG_NEXT)), + keys, + revoked_modules: revoked, + grant_max_s: 86_400, + status_max_age_s: 3_600, + sig: [0; 64], + }; + let head = Revision::seal(&key(LOG_ROOT), revision).expect("a well-formed revision").to_json(); + // The room's events: the clock's lifecycle, the director's, the viewer's. + let mut rm = Room { room: room_id, authors: vec![] }; + rm.life(0, DIRECTOR, Detail::Join { grant: gd.digest() }); + rm.life(0, DEVICE, Detail::Join { grant: gp.digest() }); + rm.life(500 * MS, VIEWER, Detail::Join { grant: gv.digest() }); + rm.life(S, DEVICE, Detail::Publish { slot: String::new(), media: media::AUDIO, profile: 1, layers: 1 }); + rm.life(S, DEVICE, Detail::Publish { slot: String::new(), media: media::VIDEO, profile: 2, layers: 3 }); + rm.life(S, DIRECTOR, Detail::Publish { slot: String::new(), media: media::AUDIO, profile: 0, layers: 1 }); + let start = rm.emit(DIRECTOR, s.start_t, &Payload::Control { target: pk(DEVICE), command: Command::RecordStart { count_in_ms: s.count_in_ms } }); + let capture = s.chunks[0].0; + for (k, note) in [(3, "rushed the run"), (7, "lovely phrasing")] { + let polarity = if k == 3 { 2 } else { 1 }; + rm.emit(DIRECTOR, capture + k * S, &Payload::Marker(Marker { taxonomy: 4, polarity, text: note.into(), attachment: None })); + } + rm.emit(DIRECTOR, s.stop_t, &Payload::Control { target: pk(DEVICE), command: Command::RecordStop }); + let chat = rm.emit(VIEWER, s.start_t + 500 * MS, &Payload::Chat { text: "good luck".into() }); + // The chunks, as captured, as the device commits them, and as the manifest lists them. + let device_time = |t: u64| (t as i128 - s.offset as i128) as u64; + let bytes: Vec> = (0..s.chunks.len()).map(|i| chunk_bytes(s.label.as_bytes(), i)).collect(); + let edited = |c: usize| { + let mut b = bytes.clone(); + b[c] = chunk_bytes(b"edited", c); + b + }; + let descriptors = |bs: &[Vec]| -> Vec { + s.chunks.iter().zip(bs).enumerate().map(|(i, (&(a, z), b))| Chunk::of(i as u64, device_time(a), device_time(z), b)).collect() + }; + let honest = descriptors(&bytes); + let rewritten = s.rewrite.map(|(_, c)| descriptors(&edited(c))); + // The device's commitments. + let take = take_id(&room_id, &pk(DEVICE), &start); + let mut times = vec![(s.start_t + 200 * MS, phase::OPEN)]; + let mut t = capture + 2_300 * MS; + while t < s.stop_t { + times.push((t, phase::RUNNING)); + t += 2 * S; + } + if !s.no_close { + times.push((s.stop_t + 400 * MS, phase::CLOSE)); + } + let mut commits: Vec<[u8; 32]> = Vec::new(); + let (mut prev, mut size) = ([0u8; 32], 0u64); + for (n, &(t, ph)) in times.iter().enumerate() { + let n = n as u32; + let t = s.late.filter(|l| l.0 == n).map_or(t, |l| l.1); + let history = match (&rewritten, s.rewrite) { + (Some(r), Some((from, _))) if n >= from => r, + _ => &honest, + }; + let done = if ph == phase::OPEN { + 0 + } else if ph == phase::CLOSE { + s.chunks.len() as u64 + } else { + s.chunks.iter().filter(|c| c.1 <= t).count() as u64 + u64::from(s.early_add == Some(n)) + }; + let first = size; + let new_size = done.max(size); + let l = leaves(&history[..new_size as usize]); + let c = Commit { + take, + n, + phase: ph, + prev: if s.break_prev == Some(n) { [0; 32] } else { prev }, + first, + size: new_size, + root: root(&history[..new_size as usize]), + offset: s.offset + s.offset_jump.filter(|j| j.0 == n).map_or(0, |j| j.1), + proof: consistency_proof(first as usize, &l), + }; + prev = rm.emit(DEVICE, t, &Payload::TakeCommit(c.encode())); + commits.push(prev); + size = new_size; + } + if s.malformed { + rm.raw(DEVICE, s.stop_t + S, events::kind::TAKE_COMMIT, vec![0; 10]); + } + if let Some(n) = s.drop { + let a = rm.authors.iter_mut().find(|a| a.who == DEVICE).expect("the device's chain"); + let i = a.records.iter().position(|r| Event::parse(r).expect("a corpus record").digest() == commits[n as usize]).expect("held"); + a.records.remove(i); + } + // What the device uploads: its master as committed, or as edited. + let final_bytes = match (s.rewrite, s.manifest_edit) { + (Some((_, c)), _) | (None, Some(c)) => edited(c), + _ => bytes.clone(), + }; + let mut listed = descriptors(&final_bytes); + listed.truncate(size as usize); + let n = listed.len(); + // The parts. + let mut parts: Vec<(u64, Vec)> = (0..n).map(|i| (i as u64, final_bytes[i].clone())).collect(); + match s.parts { + Parts::Whole => {} + Parts::Resumed => parts.insert(4, (3, final_bytes[3].clone())), + Parts::Missing(i) => { + parts.remove(i); + } + Parts::Altered(i) => parts[i].1[0] ^= 0x01, + Parts::Swapped(a, b) => { + let (x, y) = (parts[a].1.clone(), parts[b].1.clone()); + parts[a].1 = y; + parts[b].1 = x; + } + Parts::Extra => parts.push((n as u64, chunk_bytes(b"extra", n))), + } + // The receipts. + let steps: Vec<(u8, usize)> = match s.upload { + Upload::Whole => vec![(state::OPEN, 0), (state::PROGRESS, n), (state::SEALED, n)], + Upload::Resumed => vec![(state::OPEN, 0), (state::PROGRESS, 4), (state::RESUME, 4), (state::PROGRESS, n), (state::SEALED, n)], + Upload::Stopped(k) => vec![(state::OPEN, 0), (state::PROGRESS, k)], + Upload::Unsealed => vec![(state::OPEN, 0), (state::PROGRESS, n)], + }; + let mut receipts = Vec::new(); + let mut rprev = [0u8; 32]; + for (i, &(st, held)) in steps.iter().enumerate() { + let r = Receipt { + store: pk(STORE), + take, + seq: if s.receipt_seq_skip && i == 1 { 2 } else { i as u64 }, + prev: rprev, + at: T0_US + (20 + 3 * i as u64) * S, + state: st, + held: held as u64, + root: if s.receipt_root && i == 1 { [0x5A; 32] } else { root(&listed[..held]) }, + region: s.region, + sig: [0; 64], + } + .sign(&key(STORE)); + rprev = r.digest(); + receipts.push(r.to_bytes()); + } + // The manifest. + let m_room = if s.other_room { sha256(&[b"wai:capture-take/corpus/another room"]) } else { room_id }; + let m_start = if s.start_is_chat { chat } else { start }; + let manifest = Manifest { + room: m_room, + device: pk(DEVICE), + principal: pk(s.principal), + start: m_start, + take: take_id(&m_room, &pk(DEVICE), &m_start), + store: pk(STORE), + claims: s.claims, + purposes: purpose::RECORD | purpose::DISTRIBUTE, + root: root(&listed), + chunks: listed, + commits: commits.iter().enumerate().filter(|(i, _)| s.omit != Some(*i as u32)).map(|(_, c)| *c).collect(), + depicted: vec![(pk(s.principal), match &consent { + Some(c) if c.subject == pk(s.principal) => c.digest(), + _ => [0; 32], + })], + sig: [0; 64], + } + .sign(&key(DEVICE)); + let mut manifest = manifest.to_bytes(); + if s.flip_sig { + let l = manifest.len(); + manifest[l - 33] ^= 0x04; + } + let consents = match (consent, s.consent) { + (Some(c), Some(p)) if p.given => vec![c.to_bytes()], + _ => vec![], + }; + Written { + descriptor: d.to_bytes(), + grants, + head: Some(head), + chains: rm.authors.into_iter().map(|a| a.records).collect(), + manifest, + parts, + receipts, + consents, + } +} + +// ---- vectors ---- + +/// Which claim a vector is written to fail. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum Claim { + SingleTake, + Aligned, + Complete, + /// `publishable` for `record`. + Record, +} + +/// What a vector was written to do. +#[derive(Clone, Copy, Debug)] +enum Intent { + /// Every claim holds, and `publishable` for every purpose but `train`. + Good, + /// The claims hold but this one, which fails with this reason. + Fails(Claim, Reason), + /// Refused, at a place of this kind, with this reason. + Refuse(&'static str, Reason), +} + +struct Vector { + name: &'static str, + about: &'static str, + w: Written, + intent: Intent, +} + +fn inputs(w: &Written, at: u64) -> TakeInputs<'_> { + TakeInputs { + descriptor: &w.descriptor, + grants: &w.grants, + head: w.head.as_deref(), + chains: &w.chains, + manifest: &w.manifest, + parts: &w.parts, + receipts: &w.receipts, + consents: &w.consents, + at, + } +} + +fn place_kind(p: &Place) -> &'static str { + match p { + Place::Room(_) => "room", + Place::Manifest => "manifest", + Place::Record { .. } => "record", + Place::Store => "store", + Place::Receipt(_) => "receipt", + Place::Consent(_) => "consent", + } +} + +fn reached(intent: Intent, run: &TakeRun) -> bool { + let train = Verdict::Fails(Reason::PurposeNotConsented); + match (intent, &run.outcome) { + (Intent::Good, TakeOutcome::Verdicts(v)) => { + v.single_take.holds() && v.aligned.holds() && v.complete.holds() && v.publishable[..3].iter().all(|p| p.holds()) && v.publishable[3] == train && v.stands + } + (Intent::Fails(c, r), TakeOutcome::Verdicts(v)) => { + let got = match c { + Claim::SingleTake => v.single_take, + Claim::Aligned => v.aligned, + Claim::Complete => v.complete, + Claim::Record => v.publishable[1], + }; + got == Verdict::Fails(r) && !v.stands + } + (Intent::Refuse(k, r), TakeOutcome::Refuse { at, reason }) => place_kind(at) == k && *reason == r, + _ => false, + } +} + +fn vector(name: &'static str, about: &'static str, s: Scene, intent: Intent) -> Vector { + Vector { name, about, w: write(&s), intent } +} + +fn fails(c: Claim, r: Reason) -> Intent { + Intent::Fails(c, r) +} + +fn good_vectors() -> Vec { + let mut out = vec![vector( + "lesson", + "a lesson take: the director's remote record_start with a four-second count-in, the performer's device committing every two seconds while it captures ten one-second chunks, the director's markers, record_stop and the closing commitment, an upload sealed by the store in DE within the room's region pin, and the performer's consent to live, record and distribute (not train)", + lesson("lesson"), + Intent::Good, + )]; + let mut s = lesson("resumed_upload"); + s.upload = Upload::Resumed; + s.parts = Parts::Resumed; + out.push(vector( + "resumed_upload", + "the lesson take with an upload interrupted after four chunks and resumed: the store's receipts run open, progress, resume, progress, sealed, and chunk 3 is sent again after the interruption", + s, + Intent::Good, + )); + let mut s = lesson("minor_guardian"); + s.attrs = vec![("minor".into(), "true".into()), ("subject".into(), hex(&pk(MINOR)))]; + s.principal = MINOR; + s.consent = Some(ConsentPlan { subject: MINOR, minor: 1, guardian: Some(GUARDIAN), signer: GUARDIAN, ..s.consent.expect("a consent") }); + out.push(vector( + "minor_guardian", + "an audition take by a performer the room authority marks a minor in the device's grant, under a consent the guardian signs", + s, + Intent::Good, + )); + out +} + +fn negative_vectors() -> Vec { + let mut out = Vec::new(); + let mut s = lesson("gap"); + s.drop = Some(2); + out.push(vector("commit_gap", "commitment 2 not delivered by the relay: the device's chain has a gap where the manifest lists it (§9.4 single-take 1); aligned and complete hold", s, fails(Claim::SingleTake, DELIVERY_GAP))); + let mut s = lesson("spliced"); + s.parts = Parts::Altered(4); + out.push(vector("spliced_chunk", "the uploaded part 4 altered after its chunk was committed (§9.4 single-take 11); complete fails too, as chunk 4 was not uploaded", s, fails(Claim::SingleTake, Reason::ChunkAltered))); + let mut s = lesson("reordered"); + s.parts = Parts::Swapped(3, 5); + out.push(vector("reordered_chunk", "parts 3 and 5 uploaded each at the other's index (§9.4 single-take 11)", s, fails(Claim::SingleTake, Reason::ChunkReordered))); + let mut s = lesson("extra"); + s.parts = Parts::Extra; + out.push(vector("extra_chunk", "a part at index 10, beyond every committed chunk (§9.4 single-take 11); complete holds", s, fails(Claim::SingleTake, Reason::ChunkExtra))); + let mut s = lesson("missing"); + s.parts = Parts::Missing(6); + s.upload = Upload::Stopped(6); + out.push(vector("missing_chunk", "chunk 6 never uploaded, the store's receipts stopping at six held: every commitment verifies and single-take holds; complete fails (§9.4)", s, fails(Claim::Complete, Reason::ChunkMissing))); + let mut s = lesson("late"); + s.late = Some((3, 13_800 * MS)); + out.push(vector("late_commit", "commitment 3 sent 2.8 s after chunk 4's capture ended, beyond the interval plus the jitter (§9.4 single-take 10)", s, fails(Claim::SingleTake, Reason::CommitLate))); + let mut s = lesson("rewrite"); + s.rewrite = Some((4, 2)); + out.push(vector("root_not_extending", "from commitment 4 on the device commits a history whose chunk 2 is edited, and uploads it: commitment 4's root does not extend commitment 3's (§4.3, §9.4 single-take 3); aligned and complete hold of the edited upload", s, fails(Claim::SingleTake, Reason::RootNotExtending))); + let mut s = lesson("misaligned"); + let capture = s.start_t + 400 * MS; + s.chunks = (0..10).map(|i| (capture + i * S, capture + (i + 1) * S)).collect(); + s.stop_t = capture + 10 * S; + out.push(vector("misaligned", "the device began capturing at once, ignoring the four-second count-in: chunk 0 starts 3.6 s before the capture instant (§9.4 aligned 4); single-take holds", s, fails(Claim::Aligned, Reason::Misaligned))); + let mut s = lesson("consent_missing"); + s.consent = s.consent.map(|c| ConsentPlan { given: false, ..c }); + out.push(vector("consent_missing", "the manifest binds the performer's consent and no consent record is given (§9.4 publishable 1)", s, fails(Claim::Record, Reason::ConsentMissing))); + let mut s = lesson("consent_expired"); + s.consent = s.consent.map(|c| ConsentPlan { exp: T0_S + 3_600, ..c }); + out.push(vector("consent_expired", "a consent that ends an hour after t0, before the evaluation instant (§9.4 publishable 4)", s, fails(Claim::Record, Reason::ConsentExpired))); + let mut s = lesson("consent_revoked"); + s.consent = s.consent.map(|c| ConsentPlan { revoked: true, ..c }); + out.push(vector("consent_revoked", "a consent whose digest the key log's head lists in revoked_modules (§8.3, §9.4 publishable 3)", s, fails(Claim::Record, Reason::ConsentRevoked))); + let mut s = lesson("minor_alone"); + s.attrs = vec![("minor".into(), "true".into()), ("subject".into(), hex(&pk(PERFORMER)))]; + out.push(vector("minor_without_guardian", "a performer the device's grant marks a minor, under a consent the performer signed alone (§3.1, §9.4 publishable 2)", s, fails(Claim::Record, Reason::GuardianMissing))); + let mut s = lesson("impostor"); + s.principal = IMPOSTOR; + out.push(vector("device_not_bound", "a manifest that claims the take for another principal than the one the device's grant names in its subject attribute (§3.1, §9.2 step 4)", s, Intent::Refuse("record", Reason::DeviceNotBound))); + out +} + +fn reason_vectors() -> Vec { + let mut out = Vec::new(); + let mut s = lesson("not_recorded"); + s.mode = 0; + out.push(vector("recording_not_permitted", "a take in a room whose recording policy has mode 0 (§9.2 step 1)", s, Intent::Refuse("manifest", Reason::RecordingNotPermitted))); + let mut s = lesson("start_is_chat"); + s.start_is_chat = true; + out.push(vector("take_unknown", "a manifest whose start is the digest of a chat message, not of a record_start to the device (§9.2 step 2)", s, Intent::Refuse("manifest", Reason::TakeUnknown))); + let mut s = lesson("malformed"); + s.malformed = true; + out.push(vector("commit_malformed", "a take_commit of the device whose payload is ten bytes (§5.2, §9.2 step 3)", s, Intent::Refuse("record", Reason::CommitMalformed))); + let mut s = lesson("claims_bit"); + s.claims = 0b1000; + out.push(vector("manifest_invalid", "a manifest whose claims byte sets bit 3 (§7.2)", s, Intent::Refuse("manifest", Reason::ManifestInvalid))); + let mut s = lesson("omit"); + s.omit = Some(2); + out.push(vector("manifest_mismatch", "a manifest that leaves out commitment 2, which the room holds (§9.2 step 5)", s, Intent::Refuse("manifest", Reason::ManifestMismatch))); + let mut s = lesson("manifest_sig"); + s.flip_sig = true; + out.push(vector("manifest_bad_signature", "one bit of the manifest's signature flipped (§7.1)", s, Intent::Refuse("manifest", events::Reason::BadSignature.into()))); + let mut s = lesson("other_room"); + s.other_room = true; + out.push(vector("manifest_wrong_room", "a manifest of another room, its take id that room's (§7.2)", s, Intent::Refuse("manifest", events::Reason::WrongRoom.into()))); + let mut s = lesson("unlisted_store"); + s.store_listed = false; + out.push(vector("store_not_listed", "a store the key log's head does not list with capture/store (§6.4)", s, Intent::Refuse("store", Reason::StoreNotListed))); + let mut s = lesson("receipt_seq"); + s.receipt_seq_skip = true; + out.push(vector("upload_receipt_invalid", "receipt 1 states seq 2 (§6.3)", s, Intent::Refuse("receipt", Reason::UploadReceiptInvalid))); + let mut s = lesson("receipt_root"); + s.receipt_root = true; + out.push(vector("upload_receipt_mismatch", "receipt 1's root is not the root over the chunks it says it holds (§6.3)", s, Intent::Refuse("receipt", Reason::UploadReceiptMismatch))); + let mut s = lesson("region"); + s.region = *b"US"; + out.push(vector("store_outside_region", "a store that keeps the master in US, outside the room's region pin of DE and FR (§6.3)", s, Intent::Refuse("receipt", Reason::StoreOutsideRegion))); + let mut s = lesson("consent_purposes"); + s.consent = s.consent.map(|c| ConsentPlan { purposes: 0, ..c }); + out.push(vector("consent_invalid", "a consent record that consents to no purpose (§8.2)", s, Intent::Refuse("consent", Reason::ConsentInvalid))); + let mut s = lesson("consent_forged"); + s.consent = s.consent.map(|c| ConsentPlan { signer: VIEWER, ..c }); + out.push(vector("consent_bad_signature", "a consent of the performer signed by another key (§8.1)", s, Intent::Refuse("consent", events::Reason::BadSignature.into()))); + let mut s = lesson("prev_zero"); + s.break_prev = Some(3); + out.push(vector("commit_chain_broken", "commitment 3 whose prev is zero, not commitment 2's digest (§5.3, §9.4 single-take 2)", s, fails(Claim::SingleTake, Reason::CommitChainBroken))); + let mut s = lesson("no_close"); + s.no_close = true; + out.push(vector("take_not_closed", "a device that stopped committing before the stop and never closed the take; its upload holds the eight chunks it committed (§9.4 single-take 4); complete holds", s, fails(Claim::SingleTake, Reason::TakeNotClosed))); + let mut s = lesson("manifest_edit"); + s.manifest_edit = Some(2); + out.push(vector("manifest_not_committed", "a manifest and an upload whose chunk 2 is edited, under commitments of the chunk as captured (§9.4 single-take 5); complete fails the same way", s, fails(Claim::SingleTake, Reason::ManifestNotCommitted))); + let mut s = lesson("offset_jump"); + s.offset_jump = Some((3, 600_000)); + out.push(vector("clock_unstable", "commitment 3 states an offset 600 ms from the opening commitment's, beyond the jitter (§9.4 single-take 6)", s, fails(Claim::SingleTake, Reason::ClockUnstable))); + let mut s = lesson("pause"); + s.chunks[5].0 += 200 * MS; + out.push(vector("capture_discontinuous", "chunk 5 begins 200 ms after chunk 4 ends: a pause in the capture (§9.4 single-take 7)", s, fails(Claim::SingleTake, Reason::CaptureDiscontinuous))); + let mut s = lesson("long_chunk"); + let c = 6 * S; + let ends = [c, c + S, c + 2 * S, c + 3 * S, c + 5_500 * MS, c + 6_500 * MS, c + 7_500 * MS, c + 8_500 * MS, c + 9_500 * MS, c + 10 * S]; + s.chunks = ends.windows(2).map(|w| (w[0], w[1])).collect(); + out.push(vector("chunk_too_long", "chunk 3 spans 2.5 s of capture, beyond the commit interval (§9.4 single-take 8)", s, fails(Claim::SingleTake, Reason::ChunkTooLong))); + let mut s = lesson("early"); + s.early_add = Some(2); + out.push(vector("commit_early", "commitment 2 commits chunk 4, whose capture ends 700 ms after it, beyond the jitter (§9.4 single-take 9)", s, fails(Claim::SingleTake, Reason::CommitEarly))); + let mut s = lesson("unsealed"); + s.upload = Upload::Unsealed; + out.push(vector("upload_not_sealed", "every part uploaded and the store's last receipt a progress, never sealed (§9.4 complete 3)", s, fails(Claim::Complete, Reason::UploadNotSealed))); + let mut s = lesson("room_refused"); + s.device_commits = false; + out.push(vector("room_refused", "a device whose grant does not permit take_commit: the room refuses its first commitment (live-rooms §9.2 step 4), and the take is refused there", s, Intent::Refuse("room", events::Reason::KindNotPermitted.into()))); + out +} + +fn vectors() -> Vec { + let mut v = good_vectors(); + v.extend(negative_vectors()); + v.extend(reason_vectors()); + v +} + +// ---- the file ---- + +fn place_json(p: &Place) -> Value { + match p { + Place::Room(at) => { + let mut v = vec![json!("room")]; + match at { + At::Descriptor => v.push(json!("descriptor")), + At::KeyLog => v.push(json!("key_log")), + At::Grant(i) => v.extend([json!("grant"), json!(i)]), + At::Record { chain, record } => v.extend([json!("record"), json!(chain), json!(record)]), + } + Value::Array(v) + } + Place::Manifest => json!(["manifest"]), + Place::Record { chain, record } => json!(["record", chain, record]), + Place::Store => json!(["store"]), + Place::Receipt(i) => json!(["receipt", i]), + Place::Consent(i) => json!(["consent", i]), + } +} + +fn verdict_json(v: Verdict) -> Value { + match v { + Verdict::Holds => json!("holds"), + Verdict::Fails(r) => json!(r.code()), + } +} + +/// What a run states, as the corpus writes it: the outcome and what goes with it. +fn outcome_json(run: &TakeRun) -> Map { + let mut o = Map::new(); + match &run.outcome { + TakeOutcome::Refuse { at, reason } => { + o.insert("outcome".into(), json!("refuse")); + o.insert("reason".into(), json!(reason.code())); + o.insert("at".into(), place_json(at)); + } + TakeOutcome::Verdicts(v) => { + let take = run.take.expect("a take that read"); + o.insert("outcome".into(), json!("verdicts")); + o.insert("take".into(), json!(hex(&take))); + o.insert("stream_id".into(), json!(stream_id(&take))); + o.insert("commits".into(), json!(run.held.iter().map(|c| hex(c)).collect::>())); + o.insert("size".into(), json!(run.size)); + o.insert("root".into(), json!(hex(&run.root))); + let publishable: Map = purpose::ALL.iter().zip(v.publishable).map(|((_, n), v)| (n.to_string(), verdict_json(v))).collect(); + o.insert( + "verdicts".into(), + json!({ + "single_take": verdict_json(v.single_take), + "aligned": verdict_json(v.aligned), + "complete": verdict_json(v.complete), + "publishable": publishable, + }), + ); + o.insert("stands".into(), json!(v.stands)); + o.insert( + "markers".into(), + Value::Array( + run.markers + .iter() + .map(|m| json!({"event": hex(&m.event), "t": m.t, "chunk": m.at.chunk, "into_chunk": m.at.into_chunk, "into_master": m.at.into_master})) + .collect(), + ), + ); + } + } + o +} + +fn vector_json(v: &Vector) -> Value { + let run = verify_take(&inputs(&v.w, EVALUATED_AT)); + assert!(reached(v.intent, &run), "vector {} does not reach the outcome it was written to have ({:?}): {:?}", v.name, v.intent, run.outcome); + let w = &v.w; + let mut o = Map::new(); + o.insert("name".into(), json!(v.name)); + o.insert("about".into(), json!(v.about)); + o.insert("descriptor".into(), json!(hex(&w.descriptor))); + o.insert("grants".into(), json!(w.grants.iter().map(|g| hex(g)).collect::>())); + o.insert("key_log_head".into(), w.head.as_ref().map_or(Value::Null, |h| json!(h))); + o.insert("chains".into(), json!(w.chains.iter().map(|c| c.iter().map(|r| hex(r)).collect::>()).collect::>())); + o.insert("manifest".into(), json!(hex(&w.manifest))); + o.insert("parts".into(), Value::Array(w.parts.iter().map(|(i, b)| json!({"index": i, "bytes": hex(b)})).collect())); + o.insert("receipts".into(), json!(w.receipts.iter().map(|r| hex(r)).collect::>())); + o.insert("consents".into(), json!(w.consents.iter().map(|c| hex(c)).collect::>())); + o.insert("evaluated_at".into(), json!(EVALUATED_AT)); + o.extend(outcome_json(&run)); + Value::Object(o) +} + +/// The corpus file, `vectors.json`. +pub fn generate() -> String { + let doc = json!({ + "corpus": CAPABILITY, + "extension": "extensions/capture-binding.md", + "principals": PRINCIPALS.iter().map(|(n, i)| (n.to_string(), json!(hex(&pk(*i))))).collect::>(), + "vectors": vectors().iter().map(vector_json).collect::>(), + }); + serde_json::to_string_pretty(&doc).expect("the corpus serialises") + "\n" +} + +fn written_of(v: &Value) -> Option { + let hexes = |k: &str| -> Option>> { v[k].as_array()?.iter().map(|g| g.as_str().and_then(unhex)).collect() }; + Some(Written { + descriptor: unhex(v["descriptor"].as_str()?)?, + grants: hexes("grants")?, + head: v["key_log_head"].as_str().map(String::from), + chains: v["chains"] + .as_array()? + .iter() + .map(|c| c.as_array().and_then(|rs| rs.iter().map(|r| r.as_str().and_then(unhex)).collect::>>())) + .collect::>()?, + manifest: unhex(v["manifest"].as_str()?)?, + parts: v["parts"].as_array()?.iter().map(|p| Some((p["index"].as_u64()?, unhex(p["bytes"].as_str()?)?))).collect::>()?, + receipts: hexes("receipts")?, + consents: hexes("consents")?, + }) +} + +/// Check a corpus file against this module; the failures, one line each. +pub fn verify(doc: &str) -> Vec { + let mut fails = Vec::new(); + let root: Value = match serde_json::from_str(doc) { + Ok(v) => v, + Err(e) => return vec![format!("the corpus does not parse: {e}")], + }; + for v in root["vectors"].as_array().into_iter().flatten() { + let name = v["name"].as_str().unwrap_or("?"); + let Some(w) = written_of(v) else { + fails.push(format!("{name}: the vector does not read")); + continue; + }; + let Some(at) = v["evaluated_at"].as_u64() else { + fails.push(format!("{name}: no evaluated_at")); + continue; + }; + let run = verify_take(&inputs(&w, at)); + for (k, want) in outcome_json(&run) { + if v[&k] != want { + fails.push(format!("{name}: {k} is {want}, the corpus states {}", v[&k])); + } + } + } + fails +} diff --git a/wai/wai-rs/src/codecs/registry.rs b/wai/wai-rs/src/codecs/registry.rs index 094f403a3..e998ffe6e 100644 --- a/wai/wai-rs/src/codecs/registry.rs +++ b/wai/wai-rs/src/codecs/registry.rs @@ -209,6 +209,9 @@ pub const CAP_VIDEO_SSAI: &str = "wai.video.ssai"; pub const CAP_VIDEO_KEYS: &str = "wai.video.keys"; pub const CAP_VIDEO_PACKAGE: &str = "wai.video.package"; pub const CAP_VIDEO_CHANNEL: &str = "wai.video.channel"; +pub const CAP_LIVE_EVENTS: &str = "wai.live.events"; +pub const CAP_LIVE_ROOM: &str = "wai.live.room"; +pub const CAP_CAPTURE_TAKE: &str = "wai.capture.take"; /// One row per string SPEC §5 registers that is a payload, companion or record: /// `(string, SPEC section, edition, registered)`. @@ -286,6 +289,9 @@ const ROWS: &[(&str, &str, Option<&str>, &str)] = &[ (CAP_ASSET_PROVENANCE, S_INTERACTIVE, None, "2026-06-13"), (CAP_QUANTUM_CALIBRATION, S_INTERACTIVE, None, "2026-08-01"), (CAP_QUANTUM_JOB, S_INTERACTIVE, None, "2026-08-01"), + (CAP_LIVE_EVENTS, S_INTERACTIVE, None, "2026-10-16"), + (CAP_LIVE_ROOM, S_INTERACTIVE, None, "2026-10-16"), + (CAP_CAPTURE_TAKE, S_INTERACTIVE, None, "2026-10-17"), (CAP_AUDIO_IAMF, S_IMMERSIVE, None, "2026-06-17"), (CAP_AUDIO_AC4, S_IMMERSIVE, None, "2026-06-17"), (CAP_AUDIO_IVAS, S_IMMERSIVE, None, "2026-06-17"), @@ -332,6 +338,7 @@ const DERIVATIONS_REGISTERED: &str = "2026-09-28"; const RECORDS: &[&str] = &[ CAP_ASSET_PROVENANCE, CAP_QUANTUM_CALIBRATION, CAP_QUANTUM_JOB, CAP_VIDEO_MANIFEST, CAP_VIDEO_SSAI, CAP_VIDEO_KEYS, CAP_VIDEO_PACKAGE, CAP_VIDEO_CHANNEL, + CAP_LIVE_EVENTS, CAP_LIVE_ROOM, CAP_CAPTURE_TAKE, ]; /// A named identifier SPEC uses that has the shape of a capability string but is @@ -388,7 +395,8 @@ pub enum WireKind { WellKnown, /// A playlist tag. PlaylistTag, - /// A playlist attribute. + /// A playlist attribute, or a value a WAI binding gives one (an `EXT-X-DATERANGE` + /// `CLASS`). PlaylistAttribute, /// The `kind` member of a JSON document. DocumentKind, @@ -468,6 +476,9 @@ const HTTP_DELIVERY: &str = "extensions/http-delivery.md"; const MOQ_FORMAT: &str = "extensions/moq-streaming-format.md"; const JWP_RECEIPTS: &str = "extensions/jwp-receipts.md"; const PACKAGING: &str = "extensions/packaging.md"; +const LIVE_EVENTS: &str = "extensions/live-events.md"; +const LIVE_ROOMS: &str = "extensions/live-rooms.md"; +const CAPTURE_BINDING: &str = "extensions/capture-binding.md"; const fn wire(name: &'static str, kind: WireKind, document: &'static str, section: &'static str, status: WireStatus) -> WireIdentifier { @@ -476,8 +487,8 @@ const fn wire(name: &'static str, kind: WireKind, document: &'static str, sectio /// The wire identifiers of the container, of its two delivery bindings /// (http-delivery, moq-streaming-format), of the key discovery those bindings serve -/// (jwp-receipts §7) and of packaging, in document order. The export lists them sorted -/// by name and kind. +/// (jwp-receipts §7), of packaging, of live events, of live rooms and of capture binding, in document order. The +/// export lists them sorted by name and kind. pub const WIRE_IDENTIFIERS: &[WireIdentifier] = &[ wire("WAI1", WireKind::Magic, "SPEC.md", "§2", WireStatus::Defined), wire("WAI2", WireKind::Magic, "SPEC.md", "§7.1", WireStatus::Defined), @@ -520,6 +531,17 @@ pub const WIRE_IDENTIFIERS: &[WireIdentifier] = &[ wire("tag:transaction.science,2026:wai/class", WireKind::Scheme, PACKAGING, "§8", WireStatus::Defined), wire("tag:transaction.science,2026:wai/stages", WireKind::Scheme, PACKAGING, "§8", WireStatus::Defined), wire("wai_delivery_timeout_ms", WireKind::Catalog, PACKAGING, "§8", WireStatus::Defined), + wire("WEV1", WireKind::Magic, LIVE_EVENTS, "§3.1", WireStatus::Defined), + wire("WEP1", WireKind::Magic, LIVE_EVENTS, "§5", WireStatus::Defined), + wire("urn:wai:event:1", WireKind::Catalog, LIVE_EVENTS, "§8.1", WireStatus::Defined), + wire("science.transaction.wai.event", WireKind::PlaylistAttribute, LIVE_EVENTS, "§8.3", WireStatus::Defined), + wire("X-WAI-EVENT", WireKind::PlaylistAttribute, LIVE_EVENTS, "§8.3", WireStatus::Defined), + wire("urn:wai:event:1", WireKind::Scheme, LIVE_EVENTS, "§8.4", WireStatus::Defined), + wire("WRD1", WireKind::Magic, LIVE_ROOMS, "§3.1", WireStatus::Defined), + wire("WRG1", WireKind::Magic, LIVE_ROOMS, "§4.1", WireStatus::Defined), + wire("WUR1", WireKind::Magic, CAPTURE_BINDING, "§6.2", WireStatus::Defined), + wire("WTM1", WireKind::Magic, CAPTURE_BINDING, "§7.1", WireStatus::Defined), + wire("WCN1", WireKind::Magic, CAPTURE_BINDING, "§8.1", WireStatus::Defined), ]; /// A string with the shape of a capability that the reference implementation uses diff --git a/wai/wai-rs/src/lib.rs b/wai/wai-rs/src/lib.rs index 2cde4dd9f..80eabe796 100644 --- a/wai/wai-rs/src/lib.rs +++ b/wai/wai-rs/src/lib.rs @@ -376,6 +376,36 @@ pub mod delivery_terms; #[cfg(feature = "telemetry")] pub mod telemetry; +// Live events (extensions/live-events.md): `wai.live.events`, a signed, hash-chained, +// timeline-bound event track. Cues, chat, reactions, polls, markers, remote control, +// captions, moderation decisions and room lifecycle are one record, `WEV1`, with its +// policy (`WEP1`), its verifier, poll tallies replayed as feed state, and the field +// mappings onto an MSF event timeline, EXT-X-DATERANGE and a version 1 emsg. +// Its constants are Rust-only: names like VERSION, IN, OUT and BREAK must not +// become macros in include/wai.h. +/// cbindgen:ignore +#[cfg(feature = "live_events")] +pub mod live_events; + +// Live rooms (extensions/live-rooms.md): `wai.live.room` — the signed room descriptor and +// room grant, revocation through the room authority's key log, track naming, takeover and +// failover over slots, publish profiles, and the room verifier that replays every +// principal's events under the grant in effect at each room-clock instant. Rust-only, like +// live_events: its constants must not become macros in include/wai.h. +/// cbindgen:ignore +#[cfg(feature = "live_room")] +pub mod live_room; + +// Capture binding (extensions/capture-binding.md): `wai.capture.take` — a device's master +// recording bound to a live room by rolling take_commit events in the room's event track, +// the store's upload receipts, the take manifest, consent records with guardians for +// minors, and the take verifier's single-take, aligned, complete and publishable verdicts. +// Rust-only, like live_events and live_room: its constants must not become macros in +// include/wai.h. +/// cbindgen:ignore +#[cfg(feature = "capture_take")] +pub mod capture_take; + // Typed receipt classes (extensions/jwp-receipts.md §2.4.3–§2.4.12, §2.6, §3.1–§3.2): // energy, lawful-basis, log-inclusion, soft-binding, binding-recovery, measurement, // operating-point, stage, delivery-gap and reconstruct-session statements about diff --git a/wai/wai-rs/src/live_events.rs b/wai/wai-rs/src/live_events.rs new file mode 100644 index 000000000..1f7ac92a6 --- /dev/null +++ b/wai/wai-rs/src/live_events.rs @@ -0,0 +1,1987 @@ +//! Live events — `wai.live.events` ([extensions/live-events.md]). +//! +//! A signed, timeline-bound event track. An event is a `WEV1` record: one principal's +//! Ed25519-signed statement about one room, hash-chained to that principal's previous +//! event (`seq`, `prev`), stamped with the room clock (`t`, microseconds since the room's +//! `t0`) and optionally anchored to one MoQ object. Metadata, ad and chapter cues, chat, +//! reactions, polls, markers, remote-control commands, captions, moderation decisions, +//! take commitments and room lifecycle are all events, so one verifier covers them all. +//! +//! What this module implements, by section of the extension: +//! +//! - §3: the record, its digest (SHA-256 over the record without `sig`) and its signature +//! (Ed25519 over a domain and those bytes, verified strictly, SPEC §7 *Signatures*); +//! - §4: every kind's payload, encoded and read, with the text rules; +//! - §5: the event policy `WEP1` (permitted kinds, payload and text bounds, rates); +//! - §6: verification of one record and of each principal's chain in stream order, with +//! a delivery gap reported as a gap and never as corruption; +//! - §7: poll tallies replayed as `wai.feed.state` cells through `wai.world.sim.feed0` +//! (`ADD_INT`), so a tally is replay-equivalent and a stated tally is checkable; +//! - §8: the field mappings onto an MSF event timeline record, an `EXT-X-DATERANGE` tag +//! and a version 1 `emsg` box, in both directions. +//! +//! The corpus `live-conformance/events/` is written by [`corpus::generate`] and checked +//! by [`corpus::verify`] here, and by `live-conformance/live_events_verify.py`, which +//! shares no code with this module. +//! +//! [extensions/live-events.md]: ../../extensions/live-events.md + +use std::collections::{BTreeMap, BTreeSet}; + +use ed25519_dalek::{Signer, SigningKey}; +use sha2::{Digest, Sha256}; + +use crate::world::feed::{add_payload, feed_mutation, set_cell}; +use crate::world::{mint_node_id, CausalOp, Cell, FeedRecord, FeedState, Sim, WorldState}; + +pub mod corpus; + +/// The magic of an event record (§3.1). +pub const MAGIC: [u8; 4] = *b"WEV1"; +/// The version this revision defines (§3.1). +pub const VERSION: u8 = 1; +/// The magic of an event policy record (§5). +pub const POLICY_MAGIC: [u8; 4] = *b"WEP1"; +/// The policy version this revision defines (§5). +pub const POLICY_VERSION: u8 = 1; +/// The length of a policy record (§5). +pub const POLICY_LEN: usize = 65; +/// The domain an event signature is made over (§3.2). +pub const SIGN_DOMAIN: &[u8] = b"wai:live-event\x01"; +/// The MSF `eventType` and the `emsg` `scheme_id_uri` (§8.1, §8.4). +pub const EVENT_TYPE: &str = "urn:wai:event:1"; +/// The `CLASS` of an `EXT-X-DATERANGE` tag that carries an event (§8.3). +pub const HLS_CLASS: &str = "science.transaction.wai.event"; +/// The client attribute that carries the record (§8.3). +pub const HLS_ATTRIBUTE: &str = "X-WAI-EVENT"; +/// The tag an event rides in (§8.3). +pub const HLS_TAG: &str = "#EXT-X-DATERANGE:"; +/// One MoQ group of an events track spans this much of the room clock (§8.1). +pub const GROUP_US: u64 = 60_000_000; +/// The `emsg` timescale (§8.4): milliseconds. +pub const EMSG_TIMESCALE: u32 = 1000; +/// The largest integer a JSON number carries exactly (§8.1). +pub const MAX_SAFE_INTEGER: u64 = 9_007_199_254_740_991; +/// The largest payload the record's `payload_len` field can state (§3.1). +pub const PAYLOAD_FORMAT_MAX: usize = u16::MAX as usize; + +/// Why a record, a chain, a policy or a binding is refused (§9). `DeliveryGap` is the +/// one code that is not a refusal: it names what a receiver does not hold (§6.2). +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Reason { + Truncated, + Malformed, + UnknownVersion, + UnknownKind, + WrongRoom, + BadKey, + BadSignature, + KindNotPermitted, + PayloadTooLarge, + MalformedPayload, + BadUtf8, + TextTooLong, + SeqReplay, + SeqNotIncreasing, + ChainBroken, + TimeReversed, + DeliveryGap, + RateExceeded, + TallyMismatch, + PolicyMalformed, + BindingMalformed, + BindingMismatch, +} + +impl Reason { + /// Every code, in §9's order. + pub const ALL: [Reason; 22] = [ + Reason::Truncated, + Reason::Malformed, + Reason::UnknownVersion, + Reason::UnknownKind, + Reason::WrongRoom, + Reason::BadKey, + Reason::BadSignature, + Reason::KindNotPermitted, + Reason::PayloadTooLarge, + Reason::MalformedPayload, + Reason::BadUtf8, + Reason::TextTooLong, + Reason::SeqReplay, + Reason::SeqNotIncreasing, + Reason::ChainBroken, + Reason::TimeReversed, + Reason::DeliveryGap, + Reason::RateExceeded, + Reason::TallyMismatch, + Reason::PolicyMalformed, + Reason::BindingMalformed, + Reason::BindingMismatch, + ]; + + /// The code §9 gives it. + pub fn code(self) -> &'static str { + match self { + Reason::Truncated => "truncated", + Reason::Malformed => "malformed", + Reason::UnknownVersion => "unknown_version", + Reason::UnknownKind => "unknown_kind", + Reason::WrongRoom => "wrong_room", + Reason::BadKey => "bad_key", + Reason::BadSignature => "bad_signature", + Reason::KindNotPermitted => "kind_not_permitted", + Reason::PayloadTooLarge => "payload_too_large", + Reason::MalformedPayload => "malformed_payload", + Reason::BadUtf8 => "bad_utf8", + Reason::TextTooLong => "text_too_long", + Reason::SeqReplay => "seq_replay", + Reason::SeqNotIncreasing => "seq_not_increasing", + Reason::ChainBroken => "chain_broken", + Reason::TimeReversed => "time_reversed", + Reason::DeliveryGap => "delivery_gap", + Reason::RateExceeded => "rate_exceeded", + Reason::TallyMismatch => "tally_mismatch", + Reason::PolicyMalformed => "policy_malformed", + Reason::BindingMalformed => "binding_malformed", + Reason::BindingMismatch => "binding_mismatch", + } + } + + /// The reason a code names. + pub fn from_code(code: &str) -> Option { + Reason::ALL.iter().copied().find(|r| r.code() == code) + } +} + +impl std::fmt::Display for Reason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.code()) + } +} + +impl std::error::Error for Reason {} + +/// The kind codes of §4. +pub mod kind { + pub const META: u8 = 0x01; + pub const CUE: u8 = 0x02; + pub const CHAT: u8 = 0x03; + pub const REACTION: u8 = 0x04; + pub const POLL_OPEN: u8 = 0x05; + pub const VOTE: u8 = 0x06; + pub const POLL_CLOSE: u8 = 0x07; + pub const MARKER: u8 = 0x08; + pub const CONTROL: u8 = 0x09; + pub const CAPTION: u8 = 0x0A; + pub const DECISION: u8 = 0x0B; + pub const TAKE_COMMIT: u8 = 0x0C; + pub const JOIN: u8 = 0x10; + pub const LEAVE: u8 = 0x11; + pub const PUBLISH: u8 = 0x12; + pub const UNPUBLISH: u8 = 0x13; + pub const GRANT_EXCHANGE: u8 = 0x14; + pub const TAKEOVER: u8 = 0x15; + pub const FAILOVER: u8 = 0x16; +} + +/// Every kind this revision defines, with its name (§4), in code order. +pub const KINDS: [(u8, &str); 19] = [ + (kind::META, "meta"), + (kind::CUE, "cue"), + (kind::CHAT, "chat"), + (kind::REACTION, "reaction"), + (kind::POLL_OPEN, "poll_open"), + (kind::VOTE, "vote"), + (kind::POLL_CLOSE, "poll_close"), + (kind::MARKER, "marker"), + (kind::CONTROL, "control"), + (kind::CAPTION, "caption"), + (kind::DECISION, "decision"), + (kind::TAKE_COMMIT, "take_commit"), + (kind::JOIN, "join"), + (kind::LEAVE, "leave"), + (kind::PUBLISH, "publish"), + (kind::UNPUBLISH, "unpublish"), + (kind::GRANT_EXCHANGE, "grant_exchange"), + (kind::TAKEOVER, "takeover"), + (kind::FAILOVER, "failover"), +]; + +/// The name of a kind this revision defines. +pub fn kind_name(k: u8) -> Option<&'static str> { + KINDS.iter().find(|(c, _)| *c == k).map(|(_, n)| *n) +} + +/// Whether `k` is a lifecycle kind (§4.13). +pub fn is_lifecycle(k: u8) -> bool { + (kind::JOIN..=kind::FAILOVER).contains(&k) +} + +// --------------------------------------------------------------------------------------- +// §3 The record +// --------------------------------------------------------------------------------------- + +/// What an event is bound to, exactly (§3.1): one object of one MoQ track. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Anchor { + /// [`anchor_track`] of the track. + pub track: [u8; 32], + pub group: u64, + pub object: u64, +} + +/// The `track` of an anchor (§3.1): SHA-256 over the track's namespace as its MSF catalog +/// entry has it (its own or the one it inherits, MSF §5.2.2), one zero byte, and its name. +pub fn anchor_track(namespace: &str, name: &str) -> [u8; 32] { + let mut h = Sha256::new(); + h.update(namespace.as_bytes()); + h.update([0u8]); + h.update(name.as_bytes()); + h.finalize().into() +} + +/// One event record (§3.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Event { + pub room: [u8; 32], + pub principal: [u8; 32], + pub seq: u64, + pub prev: [u8; 32], + pub t: u64, + pub anchor: Option, + pub kind: u8, + pub payload: Vec, + pub sig: [u8; 64], +} + +/// A cursor that reports running out as `None`; each reader maps it to its own reason. +struct Rd<'a> { + b: &'a [u8], + p: usize, +} + +impl<'a> Rd<'a> { + fn new(b: &'a [u8]) -> Self { + Rd { b, p: 0 } + } + fn take(&mut self, n: usize) -> Option<&'a [u8]> { + let end = self.p.checked_add(n)?; + let s = self.b.get(self.p..end)?; + self.p = end; + Some(s) + } + fn u8(&mut self) -> Option { + Some(self.take(1)?[0]) + } + fn u16(&mut self) -> Option { + Some(u16::from_le_bytes(self.take(2)?.try_into().ok()?)) + } + fn u32(&mut self) -> Option { + Some(u32::from_le_bytes(self.take(4)?.try_into().ok()?)) + } + fn u64(&mut self) -> Option { + Some(u64::from_le_bytes(self.take(8)?.try_into().ok()?)) + } + fn d32(&mut self) -> Option<[u8; 32]> { + self.take(32)?.try_into().ok() + } + fn rest(&mut self) -> &'a [u8] { + let s = &self.b[self.p..]; + self.p = self.b.len(); + s + } + fn done(&self) -> bool { + self.p == self.b.len() + } +} + +impl Event { + /// The record without `sig` (§3.1): what the digest covers and the signature signs. + pub fn body(&self) -> Vec { + let mut out = Vec::with_capacity(166 + self.payload.len()); + out.extend_from_slice(&MAGIC); + out.push(VERSION); + out.extend_from_slice(&self.room); + out.extend_from_slice(&self.principal); + out.extend_from_slice(&self.seq.to_le_bytes()); + out.extend_from_slice(&self.prev); + out.extend_from_slice(&self.t.to_le_bytes()); + match &self.anchor { + None => out.push(0), + Some(a) => { + out.push(1); + out.extend_from_slice(&a.track); + out.extend_from_slice(&a.group.to_le_bytes()); + out.extend_from_slice(&a.object.to_le_bytes()); + } + } + out.push(self.kind); + assert!(self.payload.len() <= PAYLOAD_FORMAT_MAX, "a payload longer than u16 cannot be written"); + out.extend_from_slice(&(self.payload.len() as u16).to_le_bytes()); + out.extend_from_slice(&self.payload); + out + } + + /// The whole record: the body and `sig`. + pub fn to_bytes(&self) -> Vec { + let mut out = self.body(); + out.extend_from_slice(&self.sig); + out + } + + /// The event's digest (§3.2): SHA-256 over [`Event::body`]. + pub fn digest(&self) -> [u8; 32] { + Sha256::digest(self.body()).into() + } + + /// The bytes the signature is made over (§3.2): [`SIGN_DOMAIN`] and the body. + pub fn signing_bytes(&self) -> Vec { + let mut m = SIGN_DOMAIN.to_vec(); + m.extend_from_slice(&self.body()); + m + } + + /// An event signed by `key`, whose public key becomes `principal`. + #[allow(clippy::too_many_arguments)] + pub fn sign( + key: &SigningKey, + room: [u8; 32], + seq: u64, + prev: [u8; 32], + t: u64, + anchor: Option, + kind: u8, + payload: Vec, + ) -> Event { + let mut ev = Event { + room, + principal: key.verifying_key().to_bytes(), + seq, + prev, + t, + anchor, + kind, + payload, + sig: [0u8; 64], + }; + ev.sig = key.sign(&ev.signing_bytes()).to_bytes(); + ev + } + + /// The signature, verified as SPEC §7 *Signatures* requires (§3.2). + pub fn verify_signature(&self) -> Result<(), Reason> { + crate::sig::verify_strict(&self.principal, &self.signing_bytes(), &self.sig).map_err(|e| match e { + crate::sig::SigError::BadKey => Reason::BadKey, + crate::sig::SigError::BadSignature => Reason::BadSignature, + }) + } + + /// Read one record (§3.3): exactly the bytes given, in the order of §3.1. + pub fn parse(b: &[u8]) -> Result { + if b.len() < 4 { + return Err(Reason::Truncated); + } + if b[..4] != MAGIC { + return Err(Reason::Malformed); + } + if b.len() < 5 { + return Err(Reason::Truncated); + } + if b[4] != VERSION { + return Err(Reason::UnknownVersion); + } + let mut r = Rd::new(&b[5..]); + let t = Reason::Truncated; + let room = r.d32().ok_or(t)?; + let principal = r.d32().ok_or(t)?; + let seq = r.u64().ok_or(t)?; + let prev = r.d32().ok_or(t)?; + let time = r.u64().ok_or(t)?; + let anchor = match r.u8().ok_or(t)? { + 0 => None, + 1 => Some(Anchor { track: r.d32().ok_or(t)?, group: r.u64().ok_or(t)?, object: r.u64().ok_or(t)? }), + _ => return Err(Reason::Malformed), + }; + let kind = r.u8().ok_or(t)?; + let len = r.u16().ok_or(t)? as usize; + let payload = r.take(len).ok_or(t)?.to_vec(); + let sig: [u8; 64] = r.take(64).ok_or(t)?.try_into().map_err(|_| t)?; + if !r.done() { + return Err(Reason::Malformed); + } + Ok(Event { room, principal, seq, prev, t: time, anchor, kind, payload, sig }) + } +} + +// --------------------------------------------------------------------------------------- +// §4 Payloads +// --------------------------------------------------------------------------------------- + +/// A `cue` (§4.3). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Cue { + /// [`cue_type`]. + pub cue_type: u8, + pub cue_id: u32, + /// Planned (out, break), actual (in) or chapter length; 0 when not known. + pub duration_ms: u32, + /// `(form, bytes)`: [`scte_form`] and the SCTE-35 message carried verbatim. + pub scte: Option<(u8, Vec)>, +} + +/// The cue types (§4.3). +pub mod cue_type { + pub const OUT: u8 = 1; + pub const IN: u8 = 2; + pub const CHAPTER: u8 = 3; + pub const BREAK: u8 = 4; +} + +/// The forms an SCTE-35 message takes in a cue (§4.3). +pub mod scte_form { + /// A `splice_info_section()` (SCTE 35-1). + pub const SPLICE_INFO_SECTION: u8 = 1; + /// An event-based signaling message (SCTE 35-2), carried opaque. + pub const EVENT_BASED: u8 = 2; +} + +/// A `reaction` (§4.5). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Reaction { + pub rtype: u8, + pub value: u16, + pub target: Option<[u8; 32]>, + pub remove: bool, +} + +/// A `marker` (§4.8). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Marker { + pub taxonomy: u32, + /// 0 neutral, 1 positive, 2 negative. + pub polarity: u8, + pub text: String, + pub attachment: Option<[u8; 32]>, +} + +/// A `control` command (§4.9). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Command { + RecordStart { count_in_ms: u32 }, + RecordStop, + Zoom { q16: u32 }, + Mute { on: bool }, + LayerRequest { layer: u8 }, +} + +/// A `caption` (§4.10). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Caption { + pub duration_ms: u32, + /// 1 human, 2 machine, 3 machine-reviewed. + pub origin: u8, + /// The digest naming the model, present exactly when `origin` is 2 or 3. + pub model: Option<[u8; 32]>, + pub lang: String, + pub text: String, +} + +/// A payload, read (§4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Payload { + Meta(Vec), + Cue(Cue), + Chat { text: String }, + Reaction(Reaction), + PollOpen { question: String, options: Vec }, + Vote { poll: [u8; 32], option: u8 }, + PollClose { poll: [u8; 32], counts: Vec }, + Marker(Marker), + Control { target: [u8; 32], command: Command }, + Caption(Caption), + Decision { verdict: u8, target: [u8; 32], reason: u16 }, + TakeCommit(Vec), + Lifecycle { kind: u8, subject: [u8; 32], detail: Vec }, +} + +fn put_text(out: &mut Vec, s: &str) { + assert!(s.len() <= u16::MAX as usize, "a text field is at most 65535 bytes"); + out.extend_from_slice(&(s.len() as u16).to_le_bytes()); + out.extend_from_slice(s.as_bytes()); +} + +impl Payload { + /// The kind code the payload belongs to. + pub fn kind(&self) -> u8 { + match self { + Payload::Meta(_) => kind::META, + Payload::Cue(_) => kind::CUE, + Payload::Chat { .. } => kind::CHAT, + Payload::Reaction(_) => kind::REACTION, + Payload::PollOpen { .. } => kind::POLL_OPEN, + Payload::Vote { .. } => kind::VOTE, + Payload::PollClose { .. } => kind::POLL_CLOSE, + Payload::Marker(_) => kind::MARKER, + Payload::Control { .. } => kind::CONTROL, + Payload::Caption(_) => kind::CAPTION, + Payload::Decision { .. } => kind::DECISION, + Payload::TakeCommit(_) => kind::TAKE_COMMIT, + Payload::Lifecycle { kind, .. } => *kind, + } + } + + /// The payload bytes (§4). + pub fn encode(&self) -> Vec { + let mut o = Vec::new(); + match self { + Payload::Meta(b) | Payload::TakeCommit(b) => o.extend_from_slice(b), + Payload::Cue(c) => { + o.push(c.cue_type); + o.extend_from_slice(&c.cue_id.to_le_bytes()); + o.extend_from_slice(&c.duration_ms.to_le_bytes()); + match &c.scte { + None => o.push(0), + Some((form, bytes)) => { + o.push(*form); + o.extend_from_slice(&(bytes.len() as u16).to_le_bytes()); + o.extend_from_slice(bytes); + } + } + } + Payload::Chat { text } => put_text(&mut o, text), + Payload::Reaction(r) => { + o.push(r.rtype); + o.extend_from_slice(&r.value.to_le_bytes()); + o.push(r.target.is_some() as u8 | (r.remove as u8) << 1); + if let Some(t) = r.target { + o.extend_from_slice(&t); + } + } + Payload::PollOpen { question, options } => { + put_text(&mut o, question); + o.push(options.len() as u8); + for opt in options { + put_text(&mut o, opt); + } + } + Payload::Vote { poll, option } => { + o.extend_from_slice(poll); + o.push(*option); + } + Payload::PollClose { poll, counts } => { + o.extend_from_slice(poll); + o.push(counts.len() as u8); + for c in counts { + o.extend_from_slice(&c.to_le_bytes()); + } + } + Payload::Marker(m) => { + o.extend_from_slice(&m.taxonomy.to_le_bytes()); + o.push(m.polarity); + put_text(&mut o, &m.text); + o.push(m.attachment.is_some() as u8); + if let Some(a) = m.attachment { + o.extend_from_slice(&a); + } + } + Payload::Control { target, command } => { + o.extend_from_slice(target); + match command { + Command::RecordStart { count_in_ms } => { + o.push(1); + o.extend_from_slice(&count_in_ms.to_le_bytes()); + } + Command::RecordStop => o.push(2), + Command::Zoom { q16 } => { + o.push(3); + o.extend_from_slice(&q16.to_le_bytes()); + } + Command::Mute { on } => { + o.push(4); + o.push(*on as u8); + } + Command::LayerRequest { layer } => { + o.push(5); + o.push(*layer); + } + } + } + Payload::Caption(c) => { + o.extend_from_slice(&c.duration_ms.to_le_bytes()); + o.push(c.origin); + if let Some(m) = c.model { + o.extend_from_slice(&m); + } + o.push(c.lang.len() as u8); + o.extend_from_slice(c.lang.as_bytes()); + put_text(&mut o, &c.text); + } + Payload::Decision { verdict, target, reason } => { + o.push(*verdict); + o.extend_from_slice(target); + o.extend_from_slice(&reason.to_le_bytes()); + } + Payload::Lifecycle { subject, detail, .. } => { + o.extend_from_slice(subject); + o.extend_from_slice(detail); + } + } + o + } +} + +/// §4.1: a text field — `u16` length, then that many bytes of UTF-8 — read with its two +/// rules: the bytes are UTF-8 (`bad_utf8`), and hold at most `max_cp` code points +/// (`text_too_long`). +fn read_text(r: &mut Rd, max_cp: u16) -> Result { + let len = r.u16().ok_or(Reason::MalformedPayload)? as usize; + let bytes = r.take(len).ok_or(Reason::MalformedPayload)?; + let s = std::str::from_utf8(bytes).map_err(|_| Reason::BadUtf8)?; + if s.chars().count() > max_cp as usize { + return Err(Reason::TextTooLong); + } + Ok(s.to_string()) +} + +/// §4.10: a language tag as this revision reads it — 2 to 35 ASCII characters, a first +/// subtag of 2 to 8 letters, then subtags of 1 to 8 letters or digits, each after one +/// hyphen. +pub fn lang_tag_ok(s: &str) -> bool { + if s.len() < 2 || s.len() > 35 { + return false; + } + for (i, sub) in s.split('-').enumerate() { + let ok = if i == 0 { + (2..=8).contains(&sub.len()) && sub.bytes().all(|c| c.is_ascii_alphabetic()) + } else { + (1..=8).contains(&sub.len()) && sub.bytes().all(|c| c.is_ascii_alphanumeric()) + }; + if !ok { + return false; + } + } + true +} + +/// §4.3: a `splice_info_section()` as this revision checks it — `table_id` 0xFC, and +/// `section_length` (the low 12 bits of bytes 1 and 2) equal to the bytes after byte 2. +pub fn splice_info_section_ok(b: &[u8]) -> bool { + b.len() >= 3 && b[0] == 0xFC && 3 + ((((b[1] & 0x0F) as usize) << 8) | b[2] as usize) == b.len() +} + +/// Read a payload of kind `k` (§4), in the order its fields are written; each field's own +/// rule applies when it is read, and bytes after the last field are `malformed_payload`. +/// `k` is a kind this revision defines. +pub fn parse_payload(k: u8, b: &[u8], max_text_cp: u16) -> Result { + let m = Reason::MalformedPayload; + let mut r = Rd::new(b); + let p = match k { + kind::META => Payload::Meta(r.rest().to_vec()), + kind::TAKE_COMMIT => Payload::TakeCommit(r.rest().to_vec()), + kind::CUE => { + let ct = r.u8().ok_or(m)?; + if !(cue_type::OUT..=cue_type::BREAK).contains(&ct) { + return Err(m); + } + let cue_id = r.u32().ok_or(m)?; + let duration_ms = r.u32().ok_or(m)?; + let scte = match r.u8().ok_or(m)? { + 0 => None, + form @ (scte_form::SPLICE_INFO_SECTION | scte_form::EVENT_BASED) => { + let len = r.u16().ok_or(m)? as usize; + let bytes = r.take(len).ok_or(m)?.to_vec(); + let ok = if form == scte_form::SPLICE_INFO_SECTION { splice_info_section_ok(&bytes) } else { !bytes.is_empty() }; + if !ok { + return Err(m); + } + Some((form, bytes)) + } + _ => return Err(m), + }; + Payload::Cue(Cue { cue_type: ct, cue_id, duration_ms, scte }) + } + kind::CHAT => Payload::Chat { text: read_text(&mut r, max_text_cp)? }, + kind::REACTION => { + let rtype = r.u8().ok_or(m)?; + if !(1..=5).contains(&rtype) { + return Err(m); + } + let value = r.u16().ok_or(m)?; + if value == 0 { + return Err(m); + } + let flags = r.u8().ok_or(m)?; + if flags & !0x03 != 0 { + return Err(m); + } + let target = if flags & 1 != 0 { Some(r.d32().ok_or(m)?) } else { None }; + Payload::Reaction(Reaction { rtype, value, target, remove: flags & 2 != 0 }) + } + kind::POLL_OPEN => { + let question = read_text(&mut r, max_text_cp)?; + let n = r.u8().ok_or(m)?; + if n < 2 { + return Err(m); + } + let mut options = Vec::with_capacity(n as usize); + for _ in 0..n { + options.push(read_text(&mut r, max_text_cp)?); + } + Payload::PollOpen { question, options } + } + kind::VOTE => Payload::Vote { poll: r.d32().ok_or(m)?, option: r.u8().ok_or(m)? }, + kind::POLL_CLOSE => { + let poll = r.d32().ok_or(m)?; + let n = r.u8().ok_or(m)?; + if n < 2 { + return Err(m); + } + let mut counts = Vec::with_capacity(n as usize); + for _ in 0..n { + counts.push(r.u32().ok_or(m)?); + } + Payload::PollClose { poll, counts } + } + kind::MARKER => { + let taxonomy = r.u32().ok_or(m)?; + let polarity = r.u8().ok_or(m)?; + if polarity > 2 { + return Err(m); + } + let text = read_text(&mut r, max_text_cp)?; + let attachment = match r.u8().ok_or(m)? { + 0 => None, + 1 => Some(r.d32().ok_or(m)?), + _ => return Err(m), + }; + Payload::Marker(Marker { taxonomy, polarity, text, attachment }) + } + kind::CONTROL => { + let target = r.d32().ok_or(m)?; + let command = match r.u8().ok_or(m)? { + 1 => Command::RecordStart { count_in_ms: r.u32().ok_or(m)? }, + 2 => Command::RecordStop, + 3 => { + let q16 = r.u32().ok_or(m)?; + if q16 == 0 { + return Err(m); + } + Command::Zoom { q16 } + } + 4 => match r.u8().ok_or(m)? { + 0 => Command::Mute { on: false }, + 1 => Command::Mute { on: true }, + _ => return Err(m), + }, + 5 => Command::LayerRequest { layer: r.u8().ok_or(m)? }, + _ => return Err(m), + }; + Payload::Control { target, command } + } + kind::CAPTION => { + let duration_ms = r.u32().ok_or(m)?; + let origin = r.u8().ok_or(m)?; + let model = match origin { + 1 => None, + 2 | 3 => Some(r.d32().ok_or(m)?), + _ => return Err(m), + }; + let ll = r.u8().ok_or(m)? as usize; + let lb = r.take(ll).ok_or(m)?; + let lang = std::str::from_utf8(lb).map_err(|_| m)?; + if !lang_tag_ok(lang) { + return Err(m); + } + let lang = lang.to_string(); + let text = read_text(&mut r, max_text_cp)?; + Payload::Caption(Caption { duration_ms, origin, model, lang, text }) + } + kind::DECISION => { + let verdict = r.u8().ok_or(m)?; + if !(1..=3).contains(&verdict) { + return Err(m); + } + Payload::Decision { verdict, target: r.d32().ok_or(m)?, reason: r.u16().ok_or(m)? } + } + k if is_lifecycle(k) => Payload::Lifecycle { kind: k, subject: r.d32().ok_or(m)?, detail: r.rest().to_vec() }, + _ => return Err(Reason::UnknownKind), + }; + if !r.done() { + return Err(m); + } + Ok(p) +} + +// --------------------------------------------------------------------------------------- +// §5 The event policy +// --------------------------------------------------------------------------------------- + +/// An event policy (§5): what one principal may send. The room grant of a later extension +/// carries these same fields; until then a verifier is given policies by its caller. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Policy { + /// Bit `k mod 8` of byte `k div 8` is set when kind `k` is permitted. + pub kinds: [u8; 32], + pub max_payload: u16, + pub max_text_cp: u16, + pub max_events: u32, + pub window_us: u64, + pub max_reactions: u32, + pub reaction_window_us: u64, +} + +/// The defaults of §5. +pub mod defaults { + pub const MAX_PAYLOAD: u16 = 1024; + pub const MAX_TEXT_CP: u16 = 500; + pub const MAX_EVENTS: u32 = 50; + pub const WINDOW_US: u64 = 1_000_000; + pub const MAX_REACTIONS: u32 = 1; + pub const REACTION_WINDOW_US: u64 = 1_000_000; +} + +impl Default for Policy { + /// The default policy (§5): every kind but the lifecycle kinds, with the default bounds. + fn default() -> Self { + Policy::with_kinds(&KINDS.iter().map(|(k, _)| *k).filter(|k| !is_lifecycle(*k)).collect::>()) + } +} + +impl Policy { + /// The default bounds with exactly `kinds` permitted. + pub fn with_kinds(kinds: &[u8]) -> Policy { + let mut bits = [0u8; 32]; + for &k in kinds { + bits[(k / 8) as usize] |= 1 << (k % 8); + } + Policy { + kinds: bits, + max_payload: defaults::MAX_PAYLOAD, + max_text_cp: defaults::MAX_TEXT_CP, + max_events: defaults::MAX_EVENTS, + window_us: defaults::WINDOW_US, + max_reactions: defaults::MAX_REACTIONS, + reaction_window_us: defaults::REACTION_WINDOW_US, + } + } + + /// The default policy with the lifecycle kinds also permitted: a room authority's. + pub fn authority() -> Policy { + Policy::with_kinds(&KINDS.iter().map(|(k, _)| *k).collect::>()) + } + + pub fn permits(&self, k: u8) -> bool { + self.kinds[(k / 8) as usize] & (1 << (k % 8)) != 0 + } + + /// The policy record (§5). + pub fn to_bytes(&self) -> Vec { + let mut o = Vec::with_capacity(POLICY_LEN); + o.extend_from_slice(&POLICY_MAGIC); + o.push(POLICY_VERSION); + o.extend_from_slice(&self.kinds); + o.extend_from_slice(&self.max_payload.to_le_bytes()); + o.extend_from_slice(&self.max_text_cp.to_le_bytes()); + o.extend_from_slice(&self.max_events.to_le_bytes()); + o.extend_from_slice(&self.window_us.to_le_bytes()); + o.extend_from_slice(&self.max_reactions.to_le_bytes()); + o.extend_from_slice(&self.reaction_window_us.to_le_bytes()); + o + } + + /// Read a policy record (§5), refusing one a verifier cannot apply. + pub fn parse(b: &[u8]) -> Result { + if b.len() < 4 { + return Err(Reason::Truncated); + } + if b[..4] != POLICY_MAGIC { + return Err(Reason::PolicyMalformed); + } + if b.len() < 5 { + return Err(Reason::Truncated); + } + if b[4] != POLICY_VERSION { + return Err(Reason::UnknownVersion); + } + if b.len() < POLICY_LEN { + return Err(Reason::Truncated); + } + if b.len() > POLICY_LEN { + return Err(Reason::PolicyMalformed); + } + let mut r = Rd::new(&b[5..]); + let p = Policy { + kinds: r.d32().expect("length checked"), + max_payload: r.u16().expect("length checked"), + max_text_cp: r.u16().expect("length checked"), + max_events: r.u32().expect("length checked"), + window_us: r.u64().expect("length checked"), + max_reactions: r.u32().expect("length checked"), + reaction_window_us: r.u64().expect("length checked"), + }; + for k in 0..=255u8 { + if p.permits(k) && kind_name(k).is_none() { + return Err(Reason::PolicyMalformed); + } + } + if p.max_payload == 0 || p.max_text_cp == 0 || p.max_events == 0 || p.window_us == 0 || p.max_reactions == 0 || p.reaction_window_us == 0 { + return Err(Reason::PolicyMalformed); + } + Ok(p) + } +} + +// --------------------------------------------------------------------------------------- +// §6 Verification +// --------------------------------------------------------------------------------------- + +/// Seqs a receiver does not hold (§6.2), `first..=last`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Gap { + pub principal: [u8; 32], + pub first: u64, + pub last: u64, +} + +/// What a receiver holds of one principal's chain (§6.2, §6.3). +#[derive(Default, Clone, Debug)] +struct Chain { + held: BTreeMap, + /// The head: `(seq, digest, t)` of the last event accepted. + head: Option<(u64, [u8; 32], u64)>, + /// `t` of every event accepted, in stream order (non-decreasing). + times: Vec, + /// `t` of every standalone reaction accepted. + reactions: Vec, +} + +/// An event a verifier accepted. +#[derive(Clone, Debug)] +pub struct Accepted { + /// Its position among the records offered. + pub index: usize, + pub event: Event, + pub payload: Payload, + pub digest: [u8; 32], +} + +/// What [`RoomVerifier::offer`] did with a record it did not refuse. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Offered { + /// A new event, now held. + Accepted, + /// An event already held (§6.2): repeated, as at a group start, and not counted again. + Duplicate, +} + +/// Number of events in `times` (non-decreasing) whose `t` is within `window` of `t`, +/// plus one for the event at `t` itself (§6.3). +fn in_window(times: &[u64], t: u64, window: u64) -> usize { + 1 + times.iter().rev().take_while(|&&f| t - f < window).count() +} + +/// The verifier of one room's events (§6): each record offered in stream order, checked +/// in the order §6.1 gives, then against its principal's chain (§6.2) and rates (§6.3). +#[derive(Clone, Debug)] +pub struct RoomVerifier { + room: [u8; 32], + default_policy: Policy, + policies: BTreeMap<[u8; 32], Policy>, + chains: BTreeMap<[u8; 32], Chain>, + accepted: Vec, + gaps: Vec, + offered: usize, +} + +impl RoomVerifier { + /// A verifier of room `room`, under `default_policy` for every principal not given a + /// policy of its own. + pub fn new(room: [u8; 32], default_policy: Policy) -> Self { + RoomVerifier { + room, + default_policy, + policies: BTreeMap::new(), + chains: BTreeMap::new(), + accepted: Vec::new(), + gaps: Vec::new(), + offered: 0, + } + } + + /// Give `principal` a policy of its own. + pub fn set_policy(&mut self, principal: [u8; 32], policy: Policy) { + self.policies.insert(principal, policy); + } + + /// The policy `principal`'s events are held to. + pub fn policy_of(&self, principal: &[u8; 32]) -> &Policy { + self.policies.get(principal).unwrap_or(&self.default_policy) + } + + /// Offer the next record in stream order (§6). A refused record changes nothing a + /// verifier holds. + pub fn offer(&mut self, bytes: &[u8]) -> Result { + let index = self.offered; + self.offered += 1; + // §6.1, steps 1 to 7. + let ev = Event::parse(bytes)?; + if kind_name(ev.kind).is_none() { + return Err(Reason::UnknownKind); + } + if ev.room != self.room { + return Err(Reason::WrongRoom); + } + ev.verify_signature()?; + let policy = *self.policy_of(&ev.principal); + if !policy.permits(ev.kind) { + return Err(Reason::KindNotPermitted); + } + if ev.payload.len() > policy.max_payload as usize { + return Err(Reason::PayloadTooLarge); + } + let payload = parse_payload(ev.kind, &ev.payload, policy.max_text_cp)?; + let digest = ev.digest(); + // §6.2: the chain. + let chain = self.chains.entry(ev.principal).or_default(); + if chain.held.get(&ev.seq) == Some(&digest) { + return Ok(Offered::Duplicate); + } + let mut gap = None; + match chain.head { + Some((head_seq, head_digest, head_t)) => { + if ev.seq <= head_seq { + return Err(if chain.held.contains_key(&ev.seq) { Reason::SeqReplay } else { Reason::SeqNotIncreasing }); + } + if ev.seq == head_seq + 1 { + if ev.prev != head_digest { + return Err(Reason::ChainBroken); + } + } else { + gap = Some((head_seq + 1, ev.seq - 1)); + } + if ev.t < head_t { + return Err(Reason::TimeReversed); + } + } + None => { + if ev.seq == 0 { + if ev.prev != [0u8; 32] { + return Err(Reason::ChainBroken); + } + } else { + gap = Some((0, ev.seq - 1)); + } + } + } + // §6.3: the rates. + if in_window(&chain.times, ev.t, policy.window_us) > policy.max_events as usize { + return Err(Reason::RateExceeded); + } + let standalone = matches!(&payload, Payload::Reaction(r) if r.target.is_none()); + if standalone && in_window(&chain.reactions, ev.t, policy.reaction_window_us) > policy.max_reactions as usize { + return Err(Reason::RateExceeded); + } + // Accepted. + chain.held.insert(ev.seq, digest); + chain.head = Some((ev.seq, digest, ev.t)); + chain.times.push(ev.t); + if standalone { + chain.reactions.push(ev.t); + } + if let Some((first, last)) = gap { + self.gaps.push(Gap { principal: ev.principal, first, last }); + } + self.accepted.push(Accepted { index, event: ev, payload, digest }); + Ok(Offered::Accepted) + } + + /// The gaps found so far, in the order found. + pub fn gaps(&self) -> &[Gap] { + &self.gaps + } + + /// The events accepted so far, in the order offered. + pub fn accepted(&self) -> &[Accepted] { + &self.accepted + } + + /// The polls of the events accepted so far, replayed as feed state (§7). + pub fn tally(&self) -> Tally { + tally(&self.accepted) + } +} + +/// The outcome of verifying a stream of records (§6.4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Outcome { + /// Every record accepted or a duplicate, no gap, and every stated tally equal to the + /// replay. + Accept, + /// Every record accepted or a duplicate, and the receiver does not hold these seqs. + Gap(Vec), + /// The first refusal, at the index of the record (or of the `poll_close`) refused. + Refuse { index: usize, reason: Reason }, +} + +/// Verify records offered in stream order (§6.4): stop at the first refusal; with no +/// refusal and no gap, check every stated tally (§7). +pub fn verify_stream(verifier: &mut RoomVerifier, records: &[Vec]) -> Outcome { + for (i, r) in records.iter().enumerate() { + if let Err(reason) = verifier.offer(r) { + return Outcome::Refuse { index: i, reason }; + } + } + if !verifier.gaps().is_empty() { + return Outcome::Gap(verifier.gaps().to_vec()); + } + match check_tallies(verifier.accepted()) { + Some(index) => Outcome::Refuse { index, reason: Reason::TallyMismatch }, + None => Outcome::Accept, + } +} + +/// Verify one principal's whole chain, a recording of it for instance, in its order. +pub fn verify_chain(room: [u8; 32], policy: Policy, records: &[Vec]) -> Outcome { + verify_stream(&mut RoomVerifier::new(room, policy), records) +} + +// --------------------------------------------------------------------------------------- +// §7 Polls as feed state +// --------------------------------------------------------------------------------------- + +/// One poll's tally. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PollTally { + /// The digest of its `poll_open`. + pub poll: [u8; 32], + pub open: bool, + pub counts: Vec, +} + +/// Every poll's tally, and the state hash of the feed they replay to (§7). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Tally { + pub state_hash: [u8; 32], + /// By poll digest. + pub polls: Vec, +} + +struct PollInfo { + author: [u8; 32], + seq: u64, + n: usize, + open_t: u64, +} + +/// The effective close of each poll (§7): its author's `poll_close` of the lowest seq. +fn closes(accepted: &[Accepted], polls: &BTreeMap<[u8; 32], PollInfo>) -> BTreeMap<[u8; 32], (u64, u64, usize, Vec)> { + let mut out: BTreeMap<[u8; 32], (u64, u64, usize, Vec)> = BTreeMap::new(); + for a in accepted { + if let Payload::PollClose { poll, counts } = &a.payload + && let Some(p) = polls.get(poll) + && p.author == a.event.principal + && out.get(poll).is_none_or(|c| a.event.seq < c.0) + { + out.insert(*poll, (a.event.seq, a.event.t, a.index, counts.clone())); + } + } + out +} + +/// The polls held, the counted votes and the closes (§7). +#[allow(clippy::type_complexity)] +fn poll_state(accepted: &[Accepted]) -> (BTreeMap<[u8; 32], PollInfo>, BTreeMap<([u8; 32], [u8; 32]), u8>, BTreeMap<[u8; 32], (u64, u64, usize, Vec)>) { + let mut polls = BTreeMap::new(); + for a in accepted { + if let Payload::PollOpen { options, .. } = &a.payload { + polls.insert(a.digest, PollInfo { author: a.event.principal, seq: a.event.seq, n: options.len(), open_t: a.event.t }); + } + } + let closes = closes(accepted, &polls); + // Each principal's votes in its seq order; the last counted one per poll counts. + let mut by_principal: Vec<&Accepted> = accepted.iter().filter(|a| matches!(a.payload, Payload::Vote { .. })).collect(); + by_principal.sort_by_key(|a| (a.event.principal, a.event.seq)); + let mut counted: BTreeMap<([u8; 32], [u8; 32]), u8> = BTreeMap::new(); + for a in by_principal { + if let Payload::Vote { poll, option } = &a.payload + && let Some(p) = polls.get(poll) + && (*option as usize) < p.n + && a.event.t >= p.open_t + && closes.get(poll).is_none_or(|c| a.event.t < c.1) + { + counted.insert((*poll, a.event.principal), *option); + } + } + (polls, counted, closes) +} + +/// The feed0 ops a set of accepted events replays to (§7): a `CREATE` per poll, an +/// `ADD_INT` per counted vote, a `SET_CELL` per closed poll. Unsigned: they are derived +/// by every verifier from signed events, never sent. +pub fn tally_ops(accepted: &[Accepted]) -> Vec { + let (polls, counted, closes) = poll_state(accepted); + let op = |actor: [u8; 32], lamport: u64, target: [u8; 16], kind: u16, mutation: Vec| CausalOp { + actor, + lamport, + effect_tick: 1, + deps: vec![], + target, + mutation_kind: kind, + mutation, + signature: [0u8; 64], + }; + let node = |p: &PollInfo| mint_node_id(&p.author, p.seq); + let mut ops = Vec::new(); + for p in polls.values() { + let mut cells = vec![Cell::Int(1)]; + cells.extend(std::iter::repeat_n(Cell::Int(0), p.n)); + ops.push(op(p.author, p.seq, node(p), feed_mutation::CREATE, FeedRecord { cells }.to_body())); + } + for ((poll, voter), option) in &counted { + let p = &polls[poll]; + ops.push(op(*voter, 0, node(p), feed_mutation::ADD_INT, add_payload(1 + *option as u16, 1))); + } + for poll in closes.keys() { + let p = &polls[poll]; + ops.push(op(p.author, p.seq, node(p), feed_mutation::SET_CELL, set_cell(0, &Cell::Int(0)))); + } + ops +} + +/// Replay the polls of `accepted` through `wai.world.sim.feed0` (§7). +pub fn tally(accepted: &[Accepted]) -> Tally { + let (polls, _, _) = poll_state(accepted); + let mut ws: WorldState = WorldState::new(); + for op in tally_ops(accepted) { + FeedState.apply(&mut ws, &op).expect("a derived op is well formed"); + } + let state_hash = ws.state_hash(&FeedState); + let mut out = Vec::new(); + for (digest, p) in &polls { + let rec = &ws.nodes[&mint_node_id(&p.author, p.seq)]; + let int = |c: &Cell| match c { + Cell::Int(v) => *v, + _ => unreachable!("a poll record holds Int cells"), + }; + out.push(PollTally { poll: *digest, open: int(&rec.cells[0]) == 1, counts: rec.cells[1..].iter().map(int).collect() }); + } + Tally { state_hash, polls: out } +} + +/// §7: the index of the first `poll_close` whose stated counts differ from the replay, if +/// any. A stated count is checked only where the verifier holds every chain whole. +pub fn check_tallies(accepted: &[Accepted]) -> Option { + let (polls, counted, closes) = poll_state(accepted); + let mut bad = None; + for (poll, (_, _, index, stated)) in &closes { + let n = polls[poll].n; + let mut counts = vec![0u32; n]; + for ((p, _), option) in &counted { + if p == poll { + counts[*option as usize] += 1; + } + } + if *stated != counts { + bad = Some(bad.map_or(*index, |b: usize| b.min(*index))); + } + } + bad +} + +// --------------------------------------------------------------------------------------- +// §8 Bindings +// --------------------------------------------------------------------------------------- + +const B64URL: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +/// base64url without padding (RFC 4648 §5). +pub fn b64url_encode(b: &[u8]) -> String { + let mut s = String::with_capacity(b.len().div_ceil(3) * 4); + for chunk in b.chunks(3) { + let n = chunk.len(); + let v = (chunk[0] as u32) << 16 | (*chunk.get(1).unwrap_or(&0) as u32) << 8 | *chunk.get(2).unwrap_or(&0) as u32; + for i in 0..=n { + s.push(B64URL[(v >> (18 - 6 * i) & 63) as usize] as char); + } + } + s +} + +/// base64url without padding, accepted only in its one canonical spelling: the alphabet +/// of RFC 4648 §5, no `=`, and the encoding of what it decodes to. +pub fn b64url_decode(s: &str) -> Option> { + if s.len() % 4 == 1 { + return None; + } + let mut bits = 0u32; + let mut nbits = 0u32; + let mut out = Vec::with_capacity(s.len() * 3 / 4); + for c in s.bytes() { + let v = B64URL.iter().position(|&a| a == c)? as u32; + bits = bits << 6 | v; + nbits += 6; + if nbits >= 8 { + nbits -= 8; + out.push((bits >> nbits) as u8); + bits &= (1 << nbits) - 1; + } + } + (b64url_encode(&out) == s).then_some(out) +} + +fn hex_upper(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02X}")).collect() +} + +fn hex_lower(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() +} + +/// `YYYY-MM-DDTHH:MM:SS.mmmZ` for a count of milliseconds since 1970-01-01T00:00:00Z +/// (§8.3); `None` past year 9999. +pub fn iso8601_ms(ms: u64) -> Option { + let days = (ms / 86_400_000) as i64; + let rem = ms % 86_400_000; + // Civil date from a day count (proleptic Gregorian). + let z = days + 719_468; + let era = z.div_euclid(146_097); + let doe = z - era * 146_097; + let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let d = doy - (153 * mp + 2) / 5 + 1; + let m = if mp < 10 { mp + 3 } else { mp - 9 }; + let y = yoe + era * 400 + (m <= 2) as i64; + if y > 9999 { + return None; + } + Some(format!( + "{y:04}-{m:02}-{d:02}T{:02}:{:02}:{:02}.{:03}Z", + rem / 3_600_000, + rem / 60_000 % 60, + rem / 1000 % 60, + rem % 1000 + )) +} + +/// `S.mmm` seconds for a count of milliseconds (§8.3). +fn seconds(ms: u32) -> String { + format!("{}.{:03}", ms / 1000, ms % 1000) +} + +/// The record, read for a binding: any record §3.3 reads and whose kind this revision +/// defines, with the payload of a `cue` or `caption` read (§4) for the fields a binding +/// derives from it. +fn binding_record(record: &[u8]) -> Result<(Event, Option), Reason> { + let ev = Event::parse(record).map_err(|_| Reason::BindingMalformed)?; + if kind_name(ev.kind).is_none() { + return Err(Reason::BindingMalformed); + } + let p = match ev.kind { + kind::CUE | kind::CAPTION => Some(parse_payload(ev.kind, &ev.payload, u16::MAX).map_err(|_| Reason::BindingMalformed)?), + _ => None, + }; + Ok((ev, p)) +} + +/// The wallclock milliseconds of an event (§8.1, §8.3): `floor((t0 + t) / 1000)`. +fn wallclock_ms(ev: &Event, t0_unix_us: u64) -> Result { + Ok(t0_unix_us.checked_add(ev.t).ok_or(Reason::BindingMalformed)? / 1000) +} + +/// The attributes of an event's `EXT-X-DATERANGE` tag (§8.3), in the order written. +fn daterange_attributes(record: &[u8], t0_unix_us: u64) -> Result, Reason> { + let (ev, payload) = binding_record(record)?; + let start = iso8601_ms(wallclock_ms(&ev, t0_unix_us)?).ok_or(Reason::BindingMalformed)?; + let mut a: Vec<(&'static str, String)> = vec![ + ("ID", format!("\"{}\"", hex_lower(&ev.digest()))), + ("CLASS", format!("\"{HLS_CLASS}\"")), + ("START-DATE", format!("\"{start}\"")), + ]; + match &payload { + Some(Payload::Cue(c)) => { + if c.duration_ms > 0 { + let name = if matches!(c.cue_type, cue_type::OUT | cue_type::BREAK) { "PLANNED-DURATION" } else { "DURATION" }; + a.push((name, seconds(c.duration_ms))); + } + if let Some((scte_form::SPLICE_INFO_SECTION, bytes)) = &c.scte { + let name = match c.cue_type { + cue_type::OUT | cue_type::BREAK => "SCTE35-OUT", + cue_type::IN => "SCTE35-IN", + _ => "SCTE35-CMD", + }; + a.push((name, format!("0x{}", hex_upper(bytes)))); + } + } + Some(Payload::Caption(c)) if c.duration_ms > 0 => a.push(("DURATION", seconds(c.duration_ms))), + _ => {} + } + a.push((HLS_ATTRIBUTE, format!("\"{}\"", b64url_encode(record)))); + Ok(a) +} + +/// The attribute names this binding defines (§8.3); a reader compares exactly these. +pub const DATERANGE_NAMES: [&str; 9] = + ["ID", "CLASS", "START-DATE", "DURATION", "PLANNED-DURATION", "SCTE35-CMD", "SCTE35-OUT", "SCTE35-IN", HLS_ATTRIBUTE]; + +/// The `EXT-X-DATERANGE` tag that carries `record` (§8.3), the room's `t0` given as +/// microseconds since the Unix epoch. +pub fn to_daterange(record: &[u8], t0_unix_us: u64) -> Result { + let a = daterange_attributes(record, t0_unix_us)?; + Ok(format!("{HLS_TAG}{}", a.iter().map(|(n, v)| format!("{n}={v}")).collect::>().join(","))) +} + +/// An attribute list (RFC 8216 §4.2), as `name → value as written`. +fn attribute_list(s: &str) -> Option> { + let b = s.as_bytes(); + let mut i = 0; + let mut out = BTreeMap::new(); + while i < b.len() { + let start = i; + while i < b.len() && (b[i].is_ascii_uppercase() || b[i].is_ascii_digit() || b[i] == b'-') { + i += 1; + } + if i == start || i >= b.len() || b[i] != b'=' { + return None; + } + let name = &s[start..i]; + i += 1; + let vstart = i; + if i < b.len() && b[i] == b'"' { + i += 1; + while i < b.len() && b[i] != b'"' { + i += 1; + } + if i >= b.len() { + return None; + } + i += 1; + } else { + while i < b.len() && b[i] != b',' { + i += 1; + } + } + if i == vstart { + return None; + } + if out.insert(name.to_string(), s[vstart..i].to_string()).is_some() { + return None; + } + if i < b.len() { + if b[i] != b',' { + return None; + } + i += 1; + if i == b.len() { + return None; + } + } + } + Some(out) +} + +/// Read an event back from its tag (§8.3): the record `X-WAI-EVENT` carries, refused +/// unless every attribute this binding defines is as [`to_daterange`] writes it. +pub fn from_daterange(line: &str, t0_unix_us: u64) -> Result, Reason> { + let list = line.strip_prefix(HLS_TAG).ok_or(Reason::BindingMalformed)?; + let got = attribute_list(list).ok_or(Reason::BindingMalformed)?; + let carried = got.get(HLS_ATTRIBUTE).ok_or(Reason::BindingMalformed)?; + let inner = carried.strip_prefix('"').and_then(|v| v.strip_suffix('"')).ok_or(Reason::BindingMalformed)?; + let record = b64url_decode(inner).ok_or(Reason::BindingMalformed)?; + let want: BTreeMap<&str, String> = daterange_attributes(&record, t0_unix_us)?.into_iter().collect(); + for name in DATERANGE_NAMES { + if got.get(name).map(String::as_str) != want.get(name).map(String::as_str) { + return Err(Reason::BindingMismatch); + } + } + Ok(record) +} + +/// The `event_duration` of an event's `emsg` (§8.4), in milliseconds. +fn emsg_duration(payload: &Option) -> u32 { + let ms = match payload { + Some(Payload::Cue(c)) => c.duration_ms, + Some(Payload::Caption(c)) => c.duration_ms, + _ => return 0, + }; + if ms == 0 { u32::MAX } else { ms } +} + +/// The version 1 `emsg` box that carries `record` (§8.4), the presentation time of the +/// room's `t0` given in milliseconds. +pub fn to_emsg(record: &[u8], pt0_ms: u64) -> Result, Reason> { + let (ev, payload) = binding_record(record)?; + let name = kind_name(ev.kind).ok_or(Reason::BindingMalformed)?; + let pt = pt0_ms.checked_add(ev.t / 1000).ok_or(Reason::BindingMalformed)?; + let digest = ev.digest(); + let mut body = vec![1u8, 0, 0, 0]; + body.extend_from_slice(&EMSG_TIMESCALE.to_be_bytes()); + body.extend_from_slice(&pt.to_be_bytes()); + body.extend_from_slice(&emsg_duration(&payload).to_be_bytes()); + body.extend_from_slice(&digest[..4]); + body.extend_from_slice(EVENT_TYPE.as_bytes()); + body.push(0); + body.extend_from_slice(name.as_bytes()); + body.push(0); + body.extend_from_slice(record); + let size = u32::try_from(8 + body.len()).map_err(|_| Reason::BindingMalformed)?; + let mut out = size.to_be_bytes().to_vec(); + out.extend_from_slice(b"emsg"); + out.extend_from_slice(&body); + Ok(out) +} + +/// Read an event back from its `emsg` (§8.4): the record `message_data` carries, refused +/// unless the box is, byte for byte, the one [`to_emsg`] writes for it. +pub fn from_emsg(b: &[u8], pt0_ms: u64) -> Result, Reason> { + let mal = Reason::BindingMalformed; + if b.len() < 32 || u32::from_be_bytes(b[0..4].try_into().unwrap()) as usize != b.len() || &b[4..8] != b"emsg" || b[8] != 1 { + return Err(mal); + } + let rest = &b[32..]; + let z1 = rest.iter().position(|&c| c == 0).ok_or(mal)?; + let z2 = rest[z1 + 1..].iter().position(|&c| c == 0).ok_or(mal)? + z1 + 1; + let record = rest[z2 + 1..].to_vec(); + binding_record(&record)?; + if to_emsg(&record, pt0_ms)? != b { + return Err(Reason::BindingMismatch); + } + Ok(record) +} + +/// The index member of an event's MSF record (§8.1): `l` for an anchored event whose group +/// and object JSON carries exactly, `t` otherwise. +enum MsfIndex { + L(u64, u64), + T(u64), +} + +fn msf_index(ev: &Event, t0_unix_us: u64) -> Result { + match &ev.anchor { + Some(a) if a.group <= MAX_SAFE_INTEGER && a.object <= MAX_SAFE_INTEGER => Ok(MsfIndex::L(a.group, a.object)), + _ => { + let ms = wallclock_ms(ev, t0_unix_us)?; + if ms > MAX_SAFE_INTEGER { + return Err(Reason::BindingMalformed); + } + Ok(MsfIndex::T(ms)) + } + } +} + +/// The MSF event timeline record that carries `record` (§8.1), as JSON. +pub fn to_msf_record(record: &[u8], t0_unix_us: u64) -> Result { + let (ev, _) = binding_record(record)?; + let index = match msf_index(&ev, t0_unix_us)? { + MsfIndex::L(g, o) => format!("\"l\":[{g},{o}]"), + MsfIndex::T(ms) => format!("\"t\":{ms}"), + }; + Ok(format!("{{{index},\"data\":{{\"wev1\":\"{}\"}}}}", b64url_encode(record))) +} + +/// Read an event back from an MSF record (§8.1): the record `data.wev1` carries, refused +/// unless the record holds exactly one index member and it is the one +/// [`to_msf_record`] writes. Members this binding does not define are ignored. +pub fn from_msf_record(json: &str, t0_unix_us: u64) -> Result, Reason> { + let mal = Reason::BindingMalformed; + let v: serde_json::Value = serde_json::from_str(json).map_err(|_| mal)?; + let obj = v.as_object().ok_or(mal)?; + let wev1 = obj.get("data").and_then(|d| d.as_object()).and_then(|d| d.get("wev1")).and_then(|w| w.as_str()).ok_or(mal)?; + let record = b64url_decode(wev1).ok_or(mal)?; + let (ev, _) = binding_record(&record)?; + let present: Vec<&str> = ["t", "l", "m"].into_iter().filter(|k| obj.contains_key(*k)).collect(); + if present.len() != 1 { + return Err(mal); + } + let ok = match msf_index(&ev, t0_unix_us)? { + MsfIndex::L(g, o) => obj.get("l").and_then(|l| l.as_array()).is_some_and(|l| { + l.len() == 2 && l[0].as_u64() == Some(g) && l[1].as_u64() == Some(o) && l.iter().all(|x| x.is_u64()) + }), + MsfIndex::T(ms) => obj.get("t").is_some_and(|t| t.is_u64() && t.as_u64() == Some(ms)), + }; + if !ok { + return Err(Reason::BindingMismatch); + } + Ok(record) +} + +/// The MoQ group of an event on its principal's track (§8.1): the room-clock minute. +pub fn moq_group(t: u64) -> u64 { + t / GROUP_US +} + +/// The join set of a principal's track at the start of group `group` (§8.2): from the +/// principal's events before that group, in seq order, the ones a subscriber joining then +/// needs — every `poll_open` of a poll still open, the principal's last vote in each open +/// poll, every `caption` whose interval holds the group's start, and every `cue` of type +/// out or break still open (no later `in` with its `cue_id`). +pub fn join_set(events: &[(Event, Payload)], group: u64) -> Vec { + let start = group.saturating_mul(GROUP_US); + let before: Vec<&(Event, Payload)> = events.iter().filter(|(e, _)| e.t < start).collect(); + let mut closed = BTreeSet::new(); + for (_, p) in &before { + if let Payload::PollClose { poll, .. } = p { + closed.insert(*poll); + } + } + let open_polls: BTreeSet<[u8; 32]> = before + .iter() + .filter(|(_, p)| matches!(p, Payload::PollOpen { .. })) + .map(|(e, _)| e.digest()) + .filter(|d| !closed.contains(d)) + .collect(); + let mut last_vote: BTreeMap<[u8; 32], u64> = BTreeMap::new(); + let mut in_ids = BTreeMap::new(); + for (e, p) in &before { + match p { + Payload::Vote { poll, .. } if open_polls.contains(poll) => { + last_vote.insert(*poll, e.seq); + } + Payload::Cue(c) if c.cue_type == cue_type::IN => { + in_ids.insert(c.cue_id, e.seq); + } + _ => {} + } + } + let mut out = Vec::new(); + for (e, p) in &before { + let keep = match p { + Payload::PollOpen { .. } => open_polls.contains(&e.digest()), + Payload::Vote { poll, .. } => last_vote.get(poll) == Some(&e.seq), + Payload::Caption(c) => c.duration_ms > 0 && e.t + c.duration_ms as u64 * 1000 > start, + Payload::Cue(c) => { + matches!(c.cue_type, cue_type::OUT | cue_type::BREAK) && in_ids.get(&c.cue_id).is_none_or(|&s| s < e.seq) + } + _ => false, + }; + if keep { + out.push(e.clone()); + } + } + out.sort_by_key(|e| e.seq); + out +} + +#[cfg(test)] +mod tests { + use super::*; + + fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&[i; 32]) + } + + const ROOM: [u8; 32] = [7; 32]; + + struct Author { + key: SigningKey, + seq: u64, + prev: [u8; 32], + } + + impl Author { + fn new(i: u8) -> Self { + Author { key: key(i), seq: 0, prev: [0; 32] } + } + fn emit(&mut self, t: u64, p: Payload) -> Event { + let ev = Event::sign(&self.key, ROOM, self.seq, self.prev, t, None, p.kind(), p.encode()); + self.seq += 1; + self.prev = ev.digest(); + ev + } + } + + fn chat(s: &str) -> Payload { + Payload::Chat { text: s.into() } + } + + #[test] + fn a_record_round_trips_and_verifies() { + let mut a = Author::new(1); + let ev = a.emit(5, chat("hi")); + let b = ev.to_bytes(); + assert_eq!(&b[..4], b"WEV1"); + assert_eq!(Event::parse(&b).unwrap(), ev); + ev.verify_signature().unwrap(); + // Every proper prefix is refused, as truncated or (the first byte) malformed. + for n in 0..b.len() { + let r = Event::parse(&b[..n]).unwrap_err(); + assert!(matches!(r, Reason::Truncated | Reason::Malformed), "prefix {n}: {r}"); + } + let mut long = b.clone(); + long.push(0); + assert_eq!(Event::parse(&long), Err(Reason::Malformed)); + let mut v2 = b.clone(); + v2[4] = 2; + assert_eq!(Event::parse(&v2), Err(Reason::UnknownVersion)); + } + + /// The signature is verified strictly (SPEC §7 *Signatures*): each forgery a lenient + /// verifier accepts is refused, a key's defect as `bad_key`. + #[test] + fn the_signature_is_verified_strictly() { + let ev = Author::new(2).emit(0, chat("x")); + for f in crate::sig::forgeries(|k| { + let mut e = ev.clone(); + e.principal = *k; + e.signing_bytes() + }) { + let mut e = ev.clone(); + e.principal = f.key; + e.sig = f.sig; + let want = match f.refusal { + crate::sig::SigError::BadKey => Reason::BadKey, + crate::sig::SigError::BadSignature => Reason::BadSignature, + }; + assert_eq!(e.verify_signature(), Err(want), "{}", f.name); + } + } + + #[test] + fn every_payload_round_trips() { + let d = [9u8; 32]; + let all = vec![ + Payload::Meta(vec![1, 2, 3]), + Payload::Cue(Cue { cue_type: cue_type::OUT, cue_id: 7, duration_ms: 30_000, scte: Some((1, vec![0xFC, 0x30, 0x00])) }), + Payload::Cue(Cue { cue_type: cue_type::BREAK, cue_id: 8, duration_ms: 0, scte: Some((2, vec![1])) }), + Payload::Cue(Cue { cue_type: cue_type::CHAPTER, cue_id: 9, duration_ms: 1, scte: None }), + chat("héllo"), + Payload::Reaction(Reaction { rtype: 1, value: 3, target: Some(d), remove: true }), + Payload::PollOpen { question: "q".into(), options: vec!["a".into(), "b".into()] }, + Payload::Vote { poll: d, option: 1 }, + Payload::PollClose { poll: d, counts: vec![1, 2] }, + Payload::Marker(Marker { taxonomy: 4, polarity: 2, text: "flat".into(), attachment: Some(d) }), + Payload::Control { target: d, command: Command::RecordStart { count_in_ms: 4000 } }, + Payload::Control { target: d, command: Command::Zoom { q16: 0x18000 } }, + Payload::Control { target: d, command: Command::Mute { on: true } }, + Payload::Control { target: d, command: Command::LayerRequest { layer: 2 } }, + Payload::Control { target: d, command: Command::RecordStop }, + Payload::Caption(Caption { duration_ms: 2500, origin: 2, model: Some(d), lang: "de-DE".into(), text: "Hallo".into() }), + Payload::Decision { verdict: 3, target: d, reason: 12 }, + Payload::TakeCommit(vec![0; 40]), + Payload::Lifecycle { kind: kind::TAKEOVER, subject: d, detail: b"video".to_vec() }, + ]; + for p in all { + let b = p.encode(); + assert_eq!(parse_payload(p.kind(), &b, 500).unwrap(), p); + let mut extra = b.clone(); + extra.push(0); + if !matches!(p, Payload::Meta(_) | Payload::TakeCommit(_) | Payload::Lifecycle { .. }) { + assert_eq!(parse_payload(p.kind(), &extra, 500), Err(Reason::MalformedPayload), "{p:?}"); + } + } + } + + #[test] + fn text_rules() { + let mut b = vec![2, 0, 0xC0, 0xAF]; + assert_eq!(parse_payload(kind::CHAT, &b, 500), Err(Reason::BadUtf8)); + b = vec![3, 0, 0xED, 0xA0, 0x80]; + assert_eq!(parse_payload(kind::CHAT, &b, 500), Err(Reason::BadUtf8)); + let p = chat(&"é".repeat(5)).encode(); + assert!(parse_payload(kind::CHAT, &p, 5).is_ok()); + assert_eq!(parse_payload(kind::CHAT, &p, 4), Err(Reason::TextTooLong)); + assert!(lang_tag_ok("en") && lang_tag_ok("zh-Hant-TW") && lang_tag_ok("de-DE-1996")); + assert!(!lang_tag_ok("e") && !lang_tag_ok("en-") && !lang_tag_ok("-en") && !lang_tag_ok("en--US") && !lang_tag_ok("1en")); + } + + #[test] + fn policy_round_trips_and_refuses() { + let p = Policy::default(); + let b = p.to_bytes(); + assert_eq!(b.len(), POLICY_LEN); + assert_eq!(Policy::parse(&b).unwrap(), p); + assert!(p.permits(kind::CHAT) && !p.permits(kind::JOIN) && Policy::authority().permits(kind::FAILOVER)); + assert_eq!(Policy::parse(&b[..64]), Err(Reason::Truncated)); + let mut x = b.clone(); + x.push(0); + assert_eq!(Policy::parse(&x), Err(Reason::PolicyMalformed)); + let mut x = b.clone(); + x[5 + 1] |= 1 << 5; // kind 0x0D + assert_eq!(Policy::parse(&x), Err(Reason::PolicyMalformed)); + let mut x = b.clone(); + x[4] = 2; + assert_eq!(Policy::parse(&x), Err(Reason::UnknownVersion)); + } + + #[test] + fn chain_rules() { + let mut a = Author::new(3); + let e0 = a.emit(10, chat("a")).to_bytes(); + let e1 = a.emit(20, chat("b")).to_bytes(); + let e2 = a.emit(30, chat("c")).to_bytes(); + let run = |rs: &[&Vec]| verify_chain(ROOM, Policy::default(), &rs.iter().map(|r| (*r).clone()).collect::>()); + assert_eq!(run(&[&e0, &e1, &e2]), Outcome::Accept); + assert_eq!(run(&[&e0, &e1, &e1, &e2]), Outcome::Accept); + let p = Event::parse(&e0).unwrap().principal; + assert_eq!(run(&[&e0, &e2]), Outcome::Gap(vec![Gap { principal: p, first: 1, last: 1 }])); + assert_eq!(run(&[&e0, &e2, &e1]), Outcome::Refuse { index: 2, reason: Reason::SeqNotIncreasing }); + let mut b = Author::new(3); + b.emit(10, chat("a")); + let fork = b.emit(20, chat("B")).to_bytes(); + assert_eq!(run(&[&e0, &e1, &fork]), Outcome::Refuse { index: 2, reason: Reason::SeqReplay }); + let mut c = Author::new(3); + c.emit(10, chat("a")); + c.prev = [1; 32]; + let broken = c.emit(20, chat("b")).to_bytes(); + assert_eq!(run(&[&e0, &broken]), Outcome::Refuse { index: 1, reason: Reason::ChainBroken }); + let mut d = Author::new(3); + d.emit(10, chat("a")); + let back = d.emit(9, chat("b")).to_bytes(); + assert_eq!(run(&[&e0, &back]), Outcome::Refuse { index: 1, reason: Reason::TimeReversed }); + } + + #[test] + fn rates() { + let p = Policy { max_events: 2, ..Policy::default() }; + let mut a = Author::new(4); + let rs: Vec> = [0, 500_000, 999_999].iter().map(|&t| a.emit(t, chat("x")).to_bytes()).collect(); + assert_eq!(verify_chain(ROOM, p, &rs), Outcome::Refuse { index: 2, reason: Reason::RateExceeded }); + let mut a = Author::new(4); + let rs: Vec> = [0, 500_000, 1_000_000].iter().map(|&t| a.emit(t, chat("x")).to_bytes()).collect(); + assert_eq!(verify_chain(ROOM, p, &rs), Outcome::Accept); + let r = |target| Payload::Reaction(Reaction { rtype: 1, value: 1, target, remove: false }); + let mut a = Author::new(4); + let rs = vec![a.emit(0, r(None)).to_bytes(), a.emit(10, r(Some([1; 32]))).to_bytes(), a.emit(999_999, r(None)).to_bytes()]; + assert_eq!(verify_chain(ROOM, Policy::default(), &rs), Outcome::Refuse { index: 2, reason: Reason::RateExceeded }); + } + + /// The tally is what feed0 replays: the same ops through a `LiveWorld` reach the same + /// state hash, in any order. + #[test] + fn tallies_replay_through_feed0() { + use crate::world::{LiveWorld, SimContract, WorldContainer, NUMERIC_FIXED64, RESOLVE_LWW, CAP_SIM_FEED0}; + let mut host = Author::new(5); + let mut v1 = Author::new(6); + let mut v2 = Author::new(7); + let open = host.emit(0, Payload::PollOpen { question: "q".into(), options: vec!["a".into(), "b".into(), "c".into()] }); + let poll = open.digest(); + let evs = [ + open, + v1.emit(10, Payload::Vote { poll, option: 0 }), + v2.emit(20, Payload::Vote { poll, option: 2 }), + v1.emit(30, Payload::Vote { poll, option: 1 }), + host.emit(40, Payload::PollClose { poll, counts: vec![0, 1, 1] }), + v2.emit(50, Payload::Vote { poll, option: 0 }), + ]; + let mut v = RoomVerifier::new(ROOM, Policy::default()); + let records: Vec> = evs.iter().map(Event::to_bytes).collect(); + assert_eq!(verify_stream(&mut v, &records), Outcome::Accept); + let t = v.tally(); + assert_eq!(t.polls, vec![PollTally { poll, open: false, counts: vec![0, 1, 1] }]); + + let contract = SimContract { + tick_rate: 1, + numeric: NUMERIC_FIXED64.into(), + rng_alg: "xoshiro256++".into(), + rng_seed: [0u8; 32], + sim: CAP_SIM_FEED0.into(), + resolve_default: RESOLVE_LWW.into(), + checkpoint_every: 1, + }; + let mut ops = tally_ops(v.accepted()); + ops.reverse(); + let mut ws: WorldState = WorldState::new(); + // CREATE must come first; the rest commute. + let creates: Vec<_> = ops.iter().filter(|o| o.mutation_kind == feed_mutation::CREATE).cloned().collect(); + for o in creates.iter().chain(ops.iter().filter(|o| o.mutation_kind != feed_mutation::CREATE)) { + FeedState.apply(&mut ws, o).unwrap(); + } + assert_eq!(ws.state_hash(&FeedState), t.state_hash); + let _ = (contract, LiveWorld::::open, WorldContainer::to_bytes); + + // A stated tally that disagrees is refused at its poll_close. + let mut host = Author::new(5); + let mut v1 = Author::new(6); + let open = host.emit(0, Payload::PollOpen { question: "q".into(), options: vec!["a".into(), "b".into()] }); + let poll = open.digest(); + let records = vec![ + open.to_bytes(), + v1.emit(10, Payload::Vote { poll, option: 1 }).to_bytes(), + host.emit(40, Payload::PollClose { poll, counts: vec![1, 0] }).to_bytes(), + ]; + assert_eq!(verify_chain(ROOM, Policy::default(), &records), Outcome::Refuse { index: 2, reason: Reason::TallyMismatch }); + } + + #[test] + fn base64url_and_dates() { + for n in 0..40u8 { + let b: Vec = (0..n).map(|i| i.wrapping_mul(37)).collect(); + let s = b64url_encode(&b); + assert!(!s.contains('=')); + assert_eq!(b64url_decode(&s).unwrap(), b); + } + assert_eq!(b64url_encode(b"\xfb\xff"), "-_8"); + assert!(b64url_decode("-_9").is_none(), "non-zero trailing bits"); + assert!(b64url_decode("AA==").is_none() && b64url_decode("A").is_none() && b64url_decode("A+").is_none()); + assert_eq!(iso8601_ms(0).unwrap(), "1970-01-01T00:00:00.000Z"); + assert_eq!(iso8601_ms(951_782_400_000).unwrap(), "2000-02-29T00:00:00.000Z"); + assert_eq!(iso8601_ms(1_792_108_800_123).unwrap(), "2026-10-16T00:00:00.123Z"); + assert_eq!(iso8601_ms(253_402_300_799_999).unwrap(), "9999-12-31T23:59:59.999Z"); + assert!(iso8601_ms(253_402_300_800_000).is_none()); + } + + #[test] + fn bindings_round_trip() { + let mut a = Author::new(8); + let section = { + let mut s = vec![0xFC, 0x30, 0x05, 0, 0, 0, 0, 0]; + s[2] = (s.len() - 3) as u8; + s + }; + let cue = a.emit(1_500_000, Payload::Cue(Cue { cue_type: cue_type::OUT, cue_id: 1, duration_ms: 30_000, scte: Some((1, section)) })); + let rec = cue.to_bytes(); + let t0 = 1_792_108_800_000_000; + let tag = to_daterange(&rec, t0).unwrap(); + assert!(tag.contains("START-DATE=\"2026-10-16T00:00:01.500Z\"") && tag.contains("PLANNED-DURATION=30.000") && tag.contains("SCTE35-OUT=0xFC30")); + assert_eq!(from_daterange(&tag, t0).unwrap(), rec); + assert_eq!(from_daterange(&tag, t0 + 1000), Err(Reason::BindingMismatch)); + let shuffled = { + let list = tag.strip_prefix(HLS_TAG).unwrap(); + let mut parts: Vec<&str> = list.split(',').collect(); + parts.reverse(); + format!("{HLS_TAG}{},X-COM-EXAMPLE-NOTE=\"a,b\"", parts.join(",")) + }; + assert_eq!(from_daterange(&shuffled, t0).unwrap(), rec); + let e = to_emsg(&rec, 10_000).unwrap(); + assert_eq!(from_emsg(&e, 10_000).unwrap(), rec); + assert_eq!(from_emsg(&e, 10_001), Err(Reason::BindingMismatch)); + let m = to_msf_record(&rec, t0).unwrap(); + assert!(m.starts_with("{\"t\":1792108801500,")); + assert_eq!(from_msf_record(&m, t0).unwrap(), rec); + let anchored = Event::sign(&key(8), ROOM, 0, [0; 32], 0, Some(Anchor { track: anchor_track("r/h", "video"), group: 3, object: 9 }), kind::CHAT, chat("x").encode()); + let m = to_msf_record(&anchored.to_bytes(), t0).unwrap(); + assert!(m.starts_with("{\"l\":[3,9],")); + assert_eq!(from_msf_record(&m, t0).unwrap(), anchored.to_bytes()); + } + + #[test] + fn join_sets() { + let mut h = Author::new(9); + let open = h.emit(1_000_000, Payload::PollOpen { question: "q".into(), options: vec!["a".into(), "b".into()] }); + let poll = open.digest(); + let cap_live = h.emit(59_000_000, Payload::Caption(Caption { duration_ms: 3000, origin: 1, model: None, lang: "en".into(), text: "x".into() })); + let cap_gone = h.emit(59_500_000, Payload::Caption(Caption { duration_ms: 100, origin: 1, model: None, lang: "en".into(), text: "y".into() })); + let v_old = h.emit(59_600_000, Payload::Vote { poll, option: 0 }); + let v_new = h.emit(59_700_000, Payload::Vote { poll, option: 1 }); + let chatted = h.emit(59_800_000, chat("z")); + let evs: Vec<(Event, Payload)> = [open.clone(), cap_live.clone(), cap_gone, v_old, v_new.clone(), chatted] + .into_iter() + .map(|e| { + let p = parse_payload(e.kind, &e.payload, 500).unwrap(); + (e, p) + }) + .collect(); + assert_eq!(join_set(&evs, 1), vec![open, cap_live, v_new]); + assert!(join_set(&evs, 0).is_empty()); + } + + #[test] + fn reason_codes_are_distinct() { + let codes: BTreeSet<&str> = Reason::ALL.iter().map(|r| r.code()).collect(); + assert_eq!(codes.len(), Reason::ALL.len()); + for r in Reason::ALL { + assert_eq!(Reason::from_code(r.code()), Some(r)); + } + } +} diff --git a/wai/wai-rs/src/live_events/corpus.rs b/wai/wai-rs/src/live_events/corpus.rs new file mode 100644 index 000000000..f1c964351 --- /dev/null +++ b/wai/wai-rs/src/live_events/corpus.rs @@ -0,0 +1,1029 @@ +//! The conformance corpus of extensions/live-events.md §10: `live-conformance/events/vectors.json`. +//! +//! [`generate`] writes it from fixed seeds: every key is SHA-256 of a fixed label and an +//! index, every time is a constant, and Ed25519 signing is deterministic (RFC 8032), so +//! the file is the same bytes on every machine. Each vector states the outcome it was +//! written to have, and the generator asserts that this module reaches it before writing +//! it, so a defect here cannot write itself into the corpus as expected. +//! +//! [`verify`] checks a corpus file against this module: every vector's outcome, reason, +//! index, gaps, digests, tally and bindings, every policy case and every binding case. +//! `live-conformance/live_events_verify.py` checks the same file from the extension's +//! text, sharing no code with this module. + +use super::*; +use serde_json::{json, Map, Value}; + +/// The room's `t0` in the bindings that need a wallclock: 2026-10-16T00:00:00Z. +const T0_UNIX_US: u64 = 1_792_108_800_000_000; +/// The presentation time of `t0` in the `emsg` binding, in milliseconds. +const PT0_MS: u64 = 10_000; + +const AUTHORITY: u8 = 0; +const HOST: u8 = 1; +const ALICE: u8 = 2; +const BOB: u8 = 3; +const CAROL: u8 = 4; +const MODERATOR: u8 = 5; +const PRINCIPALS: [(&str, u8); 6] = + [("authority", AUTHORITY), ("host", HOST), ("alice", ALICE), ("bob", BOB), ("carol", CAROL), ("moderator", MODERATOR)]; + +const S: u64 = 1_000_000; + +fn sha(parts: &[&[u8]]) -> [u8; 32] { + let mut h = Sha256::new(); + for p in parts { + h.update(p); + } + h.finalize().into() +} + +fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&sha(&[b"wai:live-events/corpus/key\x00", &[i]])) +} + +fn pk(i: u8) -> [u8; 32] { + key(i).verifying_key().to_bytes() +} + +fn room(i: u8) -> [u8; 32] { + sha(&[b"wai:live-events/corpus/room\x00", &[i]]) +} + +fn hex(b: &[u8]) -> String { + hex_lower(b) +} + +fn unhex(s: &str) -> Option> { + if !s.len().is_multiple_of(2) { + return None; + } + (0..s.len()).step_by(2).map(|i| u8::from_str_radix(s.get(i..i + 2)?, 16).ok()).collect() +} + +/// A principal emitting its chain. +struct Author { + key: SigningKey, + room: [u8; 32], + seq: u64, + prev: [u8; 32], +} + +impl Author { + fn new(i: u8) -> Self { + Author { key: key(i), room: room(1), seq: 0, prev: [0; 32] } + } + fn raw(&mut self, t: u64, anchor: Option, kind: u8, payload: Vec) -> Event { + let ev = Event::sign(&self.key, self.room, self.seq, self.prev, t, anchor, kind, payload); + self.seq += 1; + self.prev = ev.digest(); + ev + } + fn ev(&mut self, t: u64, p: Payload) -> Event { + self.raw(t, None, p.kind(), p.encode()) + } + fn at(&mut self, t: u64, p: Payload) -> Vec { + self.ev(t, p).to_bytes() + } + fn anchored(&mut self, t: u64, a: Anchor, p: Payload) -> Vec { + self.raw(t, Some(a), p.kind(), p.encode()).to_bytes() + } +} + +fn video(group: u64, object: u64) -> Anchor { + Anchor { track: anchor_track("room-1/host", "video"), group, object } +} + +fn chat(s: &str) -> Payload { + Payload::Chat { text: s.into() } +} + +fn digest_of(record: &[u8]) -> [u8; 32] { + Event::parse(record).expect("a corpus record parses").digest() +} + +// ---- SCTE-35 sections, built to SCTE 35-1's syntax (the corpus is their only user) ---- + +fn crc32_mpeg2(b: &[u8]) -> u32 { + let mut c = 0xFFFF_FFFFu32; + for &x in b { + c ^= (x as u32) << 24; + for _ in 0..8 { + c = if c & 0x8000_0000 != 0 { (c << 1) ^ 0x04C1_1DB7 } else { c << 1 }; + } + } + c +} + +/// A `splice_info_section()`: no encryption, `pts_adjustment` 0, tier 0xFFF, no +/// descriptors, and its CRC_32. +fn splice_info_section(command_type: u8, command: &[u8]) -> Vec { + let mut s = vec![0xFC, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let cl = command.len() as u16; + s.extend_from_slice(&[0xFF, 0xF0 | (cl >> 8) as u8, cl as u8, command_type]); + s.extend_from_slice(command); + s.extend_from_slice(&[0, 0]); + let section_length = (s.len() - 3 + 4) as u16; + s[1] = 0x30 | (section_length >> 8) as u8; + s[2] = section_length as u8; + let crc = crc32_mpeg2(&s); + s.extend_from_slice(&crc.to_be_bytes()); + s +} + +/// An immediate `splice_insert()`: out of network or back, with a break duration. +fn splice_insert(event_id: u32, out: bool, duration_90k: Option) -> Vec { + let mut c = event_id.to_be_bytes().to_vec(); + c.push(0x7F); + c.push((out as u8) << 7 | 1 << 6 | (duration_90k.is_some() as u8) << 5 | 1 << 4 | 1 << 3 | 0x07); + if let Some(d) = duration_90k { + let v: u64 = 1 << 39 | 0x3F << 33 | (d & ((1 << 33) - 1)); + c.extend_from_slice(&v.to_be_bytes()[3..]); + } + c.extend_from_slice(&[0, 1, 0, 0]); + splice_info_section(0x05, &c) +} + +/// A `time_signal()` with no time: immediate. +fn time_signal() -> Vec { + splice_info_section(0x06, &[0x7F]) +} + +/// A byte string standing in for an SCTE 35-2 event-based signaling message, which this +/// revision carries opaque. +fn event_based_35_2() -> Vec { + sha(&[b"wai:live-events/corpus/scte35-2"])[..24].to_vec() +} + +fn cue(cue_type: u8, cue_id: u32, duration_ms: u32, scte: Option<(u8, Vec)>) -> Payload { + Payload::Cue(Cue { cue_type, cue_id, duration_ms, scte }) +} + +fn caption(duration_ms: u32, origin: u8, lang: &str, text: &str) -> Payload { + let model = (origin != 1).then(|| sha(&[b"wai:live-events/corpus/model/", lang.as_bytes()])); + Payload::Caption(Caption { duration_ms, origin, model, lang: lang.into(), text: text.into() }) +} + +fn reaction(rtype: u8, value: u16, target: Option<[u8; 32]>, remove: bool) -> Payload { + Payload::Reaction(Reaction { rtype, value, target, remove }) +} + +fn lifecycle(kind: u8, subject: u8, detail: &[u8]) -> Payload { + Payload::Lifecycle { kind, subject: pk(subject), detail: detail.to_vec() } +} + +fn control(target: u8, command: Command) -> Payload { + Payload::Control { target: pk(target), command } +} + +fn poll_open(q: &str, options: &[&str]) -> Payload { + Payload::PollOpen { question: q.into(), options: options.iter().map(|s| s.to_string()).collect() } +} + +// ---- policies ---- + +fn policies() -> Vec<(&'static str, Policy)> { + let slow = Policy { max_events: 3, ..Policy::default() }; + vec![ + ("default", Policy::default()), + ("authority", Policy::authority()), + ("chat_only", Policy::with_kinds(&[kind::CHAT, kind::REACTION, kind::VOTE])), + ("slow", slow), + ] +} + +fn policy(name: &str) -> Policy { + policies().into_iter().find(|(n, _)| *n == name).expect("a named policy").1 +} + +// ---- vectors ---- + +/// What a vector was written to do. +enum Intent { + Accept, + Gap(Vec<(u8, u64, u64)>), + Refuse(usize, Reason), +} + +struct Vector { + name: &'static str, + about: &'static str, + room: &'static str, + default_policy: &'static str, + own: Vec<(u8, &'static str)>, + events: Vec>, + intent: Intent, +} + +fn v(name: &'static str, about: &'static str, events: Vec>, intent: Intent) -> Vector { + Vector { name, about, room: "main", default_policy: "default", own: vec![], events, intent } +} + +fn good_vectors() -> Vec { + let mut out = Vec::new(); + + let mut h = Author::new(HOST); + out.push(v( + "kind_meta", + "meta (§4.2): an empty payload, an anchored one, and one of exactly the default bound of 1024 bytes", + vec![ + h.at(S, Payload::Meta(vec![])), + h.anchored(2 * S, video(0, 48), Payload::Meta(b"scene=intro;camera=2".to_vec())), + h.at(3 * S, Payload::Meta((0..1024u32).map(|i| (i * 7) as u8).collect())), + ], + Intent::Accept, + )); + + let mut h = Author::new(HOST); + out.push(v( + "kind_cue", + "cue (§4.3): an anchored splice out with a planned duration and its splice_insert() section, the splice back in with the actual duration, a chapter with no SCTE-35 message, a chapter carrying a time_signal() section, and a break carrying an opaque SCTE 35-2 message", + vec![ + h.anchored(10 * S, video(0, 240), cue(cue_type::OUT, 101, 30_000, Some((1, splice_insert(101, true, Some(30 * 90_000)))))), + h.at(40 * S, cue(cue_type::IN, 101, 30_000, Some((1, splice_insert(101, false, None))))), + h.at(45 * S, cue(cue_type::CHAPTER, 102, 120_000, None)), + h.at(50 * S, cue(cue_type::CHAPTER, 103, 0, Some((1, time_signal())))), + h.at(55 * S, cue(cue_type::BREAK, 104, 15_000, Some((2, event_based_35_2())))), + ], + Intent::Accept, + )); + + let mut a = Author::new(ALICE); + out.push(v( + "kind_chat", + "chat (§4.4): ASCII, text across scripts with a character outside the Basic Multilingual Plane, exactly the default bound of 500 code points (1000 bytes), and the empty text", + vec![ + a.at(S, chat("Hello, room.")), + a.at(2 * S, chat("Ünïcödé ✓ 日本語 🎵")), + a.at(3 * S, chat(&"é".repeat(500))), + a.at(4 * S, chat("")), + ], + Intent::Accept, + )); + + let mut a = Author::new(ALICE); + let said = a.at(S, chat("nice")); + let target = digest_of(&said); + out.push(v( + "kind_reaction", + "reaction (§4.5): standalone reactions exactly one window apart (the default rate of one per second), reactions targeting a chat event and one retracting, which the standalone rate does not count", + vec![ + said, + a.at(1_200_000, reaction(1, 1, None, false)), + a.at(1_300_000, reaction(1, 3, Some(target), false)), + a.at(2_200_000, reaction(3, 1, None, false)), + a.at(2_500_000, reaction(1, 3, Some(target), true)), + a.at(3_200_000, reaction(4, 1, None, false)), + a.at(4_300_000, reaction(5, 200, None, false)), + ], + Intent::Accept, + )); + + let mut h = Author::new(HOST); + let mut a = Author::new(ALICE); + let mut b = Author::new(BOB); + let mut c = Author::new(CAROL); + let open_a = h.at(S, poll_open("What next?", &["Encore", "Next song", "Break"])); + let pa = digest_of(&open_a); + let mut evs = vec![ + open_a, + a.at(2 * S, Payload::Vote { poll: pa, option: 0 }), + b.at(3 * S, Payload::Vote { poll: pa, option: 1 }), + c.at(4 * S, Payload::Vote { poll: pa, option: 1 }), + a.at(5 * S, Payload::Vote { poll: pa, option: 2 }), + ]; + let open_b = h.at(6 * S, poll_open("Stay for questions?", &["Yes", "No"])); + let pb = digest_of(&open_b); + evs.push(open_b); + evs.push(c.at(7 * S, Payload::Vote { poll: pb, option: 0 })); + evs.push(h.at(8 * S, Payload::PollClose { poll: pa, counts: vec![0, 2, 1] })); + evs.push(b.at(9 * S, Payload::Vote { poll: pa, option: 0 })); + evs.push(a.at(10 * S, Payload::Vote { poll: sha(&[b"no such poll"]), option: 0 })); + out.push(v( + "kind_poll", + "poll_open, vote, poll_close (§4.6, §7): three voters, one changing its vote, a vote after the close and a vote for a poll no one opened (neither counted), a close stating the tally the replay reaches, and a second poll left open", + evs, + Intent::Accept, + )); + + let mut h = Author::new(HOST); + out.push(v( + "kind_marker", + "marker (§4.8): an anchored positive marker, a negative one with an attachment digest, and a neutral one with no text", + vec![ + h.anchored(5 * S, video(0, 120), Payload::Marker(Marker { taxonomy: 1, polarity: 1, text: "on the beat".into(), attachment: None })), + h.at(12 * S, Payload::Marker(Marker { taxonomy: 2, polarity: 2, text: "flat in bar 12".into(), attachment: Some(sha(&[b"wai:live-events/corpus/voice-note"])) })), + h.at(20 * S, Payload::Marker(Marker { taxonomy: 3, polarity: 0, text: String::new(), attachment: None })), + ], + Intent::Accept, + )); + + let mut h = Author::new(HOST); + out.push(v( + "kind_control", + "control (§4.9): every command, sent to one target principal: recording started with a count-in, zoom, mute on, a layer request, mute off, recording stopped", + vec![ + h.at(S, control(ALICE, Command::RecordStart { count_in_ms: 4000 })), + h.at(2 * S, control(ALICE, Command::Zoom { q16: 0x0001_8000 })), + h.at(3 * S, control(ALICE, Command::Mute { on: true })), + h.at(4 * S, control(ALICE, Command::LayerRequest { layer: 2 })), + h.at(5 * S, control(ALICE, Command::Mute { on: false })), + h.at(60 * S, control(ALICE, Command::RecordStop)), + ], + Intent::Accept, + )); + + let mut h = Author::new(HOST); + out.push(v( + "kind_caption", + "caption (§4.10): human, machine and machine-reviewed origins, the latter two with a model digest, three language tags, and a caption with no stated duration", + vec![ + h.at(S, caption(2500, 1, "en", "Welcome, everyone.")), + h.at(3_500_000, caption(2500, 2, "fr", "Bienvenue à tous.")), + h.at(6 * S, caption(2000, 3, "de-DE", "Willkommen.")), + h.at(8 * S, caption(0, 1, "zh-Hant", "歡迎")), + ], + Intent::Accept, + )); + + let mut a = Author::new(ALICE); + let mut m = Author::new(MODERATOR); + let first = a.at(S, chat("first!")); + let spam = a.at(2 * S, chat("buy now buy now")); + let (d1, d2) = (digest_of(&first), digest_of(&spam)); + out.push(v( + "kind_decision", + "decision (§4.11): a moderator allows one chat event, denies another, then redacts it", + vec![ + first, + m.at(1_100_000, Payload::Decision { verdict: 1, target: d1, reason: 0 }), + spam, + m.at(2_100_000, Payload::Decision { verdict: 2, target: d2, reason: 3 }), + m.at(2_200_000, Payload::Decision { verdict: 3, target: d2, reason: 7 }), + ], + Intent::Accept, + )); + + let mut a = Author::new(ALICE); + out.push(v( + "kind_take_commit", + "take_commit (§4.12): opaque blobs, read for their length alone", + vec![ + a.at(2 * S, Payload::TakeCommit(sha(&[b"wai:live-events/corpus/take/0"]).iter().chain(&[0u8; 8]).copied().collect())), + a.at(4 * S, Payload::TakeCommit([sha(&[b"wai:live-events/corpus/take/1"]), sha(&[b"wai:live-events/corpus/take/2"])].concat().into_iter().chain([1u8; 8]).collect())), + ], + Intent::Accept, + )); + + let mut au = Author::new(AUTHORITY); + let mut lc = v( + "kind_lifecycle", + "the lifecycle kinds (§4.13), authored by the room authority under a policy that permits them", + vec![ + au.at(0, lifecycle(kind::JOIN, ALICE, b"")), + au.at(S, lifecycle(kind::PUBLISH, ALICE, b"video")), + au.at(2 * S, lifecycle(kind::GRANT_EXCHANGE, ALICE, &sha(&[b"wai:live-events/corpus/grant/2"]))), + au.at(3 * S, lifecycle(kind::JOIN, BOB, b"")), + au.at(4 * S, lifecycle(kind::TAKEOVER, BOB, b"video")), + au.at(5 * S, lifecycle(kind::FAILOVER, BOB, b"audio")), + au.at(6 * S, lifecycle(kind::UNPUBLISH, ALICE, b"video")), + au.at(7 * S, lifecycle(kind::LEAVE, ALICE, b"")), + ], + Intent::Accept, + ); + lc.own = vec![(AUTHORITY, "authority")]; + out.push(lc); + + out.push(room_interleaved()); + + // A host's track over three groups, as a continuous subscriber and as one that joins + // at group 1 receive it (§8.2). + let mut h = Author::new(HOST); + let hs: Vec = vec![ + h.ev(5 * S, chat("doors open")), + h.ev(10 * S, poll_open("Favourite set?", &["First", "Second"])), + h.ev(50 * S, caption(15_000, 1, "en", "Thank you for coming.")), + h.ev(55 * S, chat("one more")), + h.ev(61 * S, Payload::Meta(b"scene=2".to_vec())), + h.ev(70 * S, caption(1000, 1, "en", "Next up.")), + ]; + let poll = hs[1].digest(); + let close = h.ev(121 * S, Payload::PollClose { poll, counts: vec![0, 0] }); + let read = |es: &[Event]| -> Vec<(Event, Payload)> { + es.iter().map(|e| (e.clone(), parse_payload(e.kind, &e.payload, u16::MAX).expect("a corpus payload parses"))).collect() + }; + let js1 = join_set(&read(&hs[..4]), 1); + let js2 = join_set(&read(&hs), 2); + let bytes = |es: &[Event]| es.iter().map(Event::to_bytes).collect::>(); + let mut continuous = bytes(&hs[..4]); + continuous.extend(bytes(&js1)); + continuous.extend(bytes(&hs[4..])); + continuous.extend(bytes(&js2)); + continuous.push(close.to_bytes()); + out.push(v( + "join_set_repeats", + "a host's track over three one-minute groups (§8.1) as a continuous subscriber receives it: the first object of groups 1 and 2 repeats the join set (§8.2: the open poll and the caption still showing), which the subscriber already holds and ignores as duplicates (§6.2)", + continuous, + Intent::Accept, + )); + let mut joiner = bytes(&js1); + joiner.extend(bytes(&hs[4..])); + joiner.extend(bytes(&js2)); + joiner.push(close.to_bytes()); + out.push(v( + "joiner_mid_stream", + "the same track as a subscriber joining at group 1 receives it: the join set, then the group's events; it reports what it does not hold, seq 0 before its first record and seq 3 between the join set and the group's events, as gaps (§6.2), not as corruption", + joiner, + Intent::Gap(vec![(HOST, 0, 0), (HOST, 3, 3)]), + )); + + let mut a = Author::new(ALICE); + let e0 = a.at(S, chat("one")); + let e1 = a.at(2 * S, chat("two")); + let _lost = a.at(3 * S, chat("three")); + let e3 = a.at(4 * S, chat("four")); + out.push(v( + "chain_gap", + "a chain whose seq 2 was not delivered: seq 3 follows seq 1, a delivery gap (§6.2) the receiver reports, not a refusal", + vec![e0, e1, e3], + Intent::Gap(vec![(ALICE, 2, 2)]), + )); + out +} + +/// Four participants and the authority, interleaved in delivery order across three +/// one-minute groups. +fn room_interleaved() -> Vector { + let mut au = Author::new(AUTHORITY); + let mut h = Author::new(HOST); + let mut a = Author::new(ALICE); + let mut b = Author::new(BOB); + let mut c = Author::new(CAROL); + let mut e = vec![ + au.at(0, lifecycle(kind::JOIN, HOST, b"")), + au.at(0, lifecycle(kind::JOIN, ALICE, b"")), + au.at(500_000, lifecycle(kind::JOIN, BOB, b"")), + h.at(S, caption(3000, 1, "en", "Good evening.")), + a.at(1_500_000, chat("hi all")), + au.at(2 * S, lifecycle(kind::JOIN, CAROL, b"")), + b.at(2 * S, chat("hello from the back")), + c.at(2_500_000, reaction(4, 1, None, false)), + h.anchored(3 * S, video(0, 72), Payload::Marker(Marker { taxonomy: 1, polarity: 1, text: "intro".into(), attachment: None })), + ]; + let open = h.at(5 * S, poll_open("Which song next?", &["Ballad", "Anthem"])); + let poll = digest_of(&open); + e.push(open); + e.push(a.at(6 * S, Payload::Vote { poll, option: 1 })); + e.push(c.at(6 * S, Payload::Vote { poll, option: 1 })); + e.push(b.at(6_200_000, Payload::Vote { poll, option: 0 })); + let said = c.at(7 * S, chat("anthem please")); + let target = digest_of(&said); + e.push(said); + e.push(a.at(7_100_000, reaction(1, 3, Some(target), false))); + e.push(b.at(7_100_000, reaction(1, 1, Some(target), false))); + e.push(h.at(30 * S, Payload::PollClose { poll, counts: vec![1, 2] })); + e.push(h.anchored(30 * S, video(0, 720), cue(cue_type::CHAPTER, 7, 90_000, None))); + e.push(a.at(59 * S, reaction(1, 1, None, false))); + e.push(h.at(61 * S, caption(4000, 2, "en", "This one is called Anthem."))); + e.push(c.at(62 * S, chat("🎶"))); + e.push(b.at(62 * S, reaction(4, 1, None, false))); + e.push(a.at(63 * S, reaction(4, 1, None, false))); + e.push(h.anchored(64 * S, video(1, 96), Payload::Marker(Marker { taxonomy: 2, polarity: 1, text: "chorus".into(), attachment: None }))); + e.push(au.at(90 * S, lifecycle(kind::LEAVE, BOB, b""))); + e.push(h.at(119_999_999, chat("last song"))); + e.push(h.at(120 * S, caption(2000, 1, "en", "Thank you!"))); + e.push(a.at(121 * S, chat("bravo"))); + e.push(c.at(121 * S, reaction(1, 3, None, false))); + e.push(au.at(125 * S, lifecycle(kind::LEAVE, CAROL, b""))); + let mut vec = v( + "room_interleaved", + "a room of four participants and its authority, their chains interleaved in delivery order across three one-minute groups: lifecycle, captions, chat, reactions, anchored markers and a cue, and a poll closed with the tally the replay reaches", + e, + Intent::Accept, + ); + vec.own = vec![(AUTHORITY, "authority")]; + vec +} + +fn negative_vectors() -> Vec { + let mut out = Vec::new(); + let refuse = |i, r| Intent::Refuse(i, r); + + let mut a = Author::new(ALICE); + let e0 = a.at(S, chat("ok")); + let mut e1 = a.at(2 * S, chat("tampered in flight")); + let n = e1.len(); + e1[n - 54] ^= 0x01; + out.push(v("bad_signature", "one bit of the second event's signature flipped (§3.2)", vec![e0, e1], refuse(1, Reason::BadSignature))); + + let base = Event::sign(&key(ALICE), room(1), 0, [0; 32], S, None, kind::CHAT, chat("forged").encode()); + for f in crate::sig::forgeries(|k| { + let mut e = base.clone(); + e.principal = *k; + e.signing_bytes() + }) { + let mut e = base.clone(); + e.principal = f.key; + e.sig = f.sig; + let (name, about, reason): (&'static str, &'static str, Reason) = match f.name { + "key_identity" => ("forgery_key_identity", "the identity point as the principal, with (R, S) = (B, 1): a lenient verifier accepts it over any message; the key is of small order (SPEC §7 *Signatures* step 2)", Reason::BadKey), + "key_identity_y_not_reduced" => ("forgery_key_identity_y_not_reduced", "the identity spelled with y = p + 1, with (R, S) = (B, 1): not the canonical encoding of its point (SPEC §7 *Signatures* step 1)", Reason::BadKey), + _ => ("forgery_r_small_order", "the base point as the principal, R the identity and S = k: the equation holds and R is of small order (SPEC §7 *Signatures* step 4)", Reason::BadSignature), + }; + assert_eq!(f.refusal == crate::sig::SigError::BadKey, reason == Reason::BadKey); + out.push(v(name, about, vec![e.to_bytes()], refuse(0, reason))); + } + + let mut a = Author::new(ALICE); + let e0 = a.at(S, chat("one")); + a.prev = [0xAB; 32]; + let e1 = a.at(2 * S, chat("two")); + out.push(v("chain_broken", "seq 1 follows seq 0, but its prev is not seq 0's digest (§6.2)", vec![e0, e1], refuse(1, Reason::ChainBroken))); + + let mut a = Author::new(ALICE); + a.prev = [0x01; 32]; + out.push(v("chain_broken_genesis", "seq 0 with a prev that is not 32 zero bytes (§6.2)", vec![a.at(S, chat("first"))], refuse(0, Reason::ChainBroken))); + + let mut a = Author::new(ALICE); + let (e0, e1, e2) = (a.at(S, chat("one")), a.at(2 * S, chat("two")), a.at(3 * S, chat("three"))); + out.push(v("reorder", "seq 0, seq 2, then seq 1: in stream order seq 1 arrives behind the head and is not held (§6.2)", vec![e0, e2, e1], refuse(2, Reason::SeqNotIncreasing))); + + let mut a = Author::new(ALICE); + let e0 = a.at(S, chat("one")); + let mut fork = Author { key: key(ALICE), room: room(1), seq: a.seq, prev: a.prev }; + let e1 = a.at(2 * S, chat("two")); + let e1b = fork.at(2 * S, chat("two, said differently")); + out.push(v("seq_replay", "a second, different event with seq 1, after seq 1 is held (§6.2)", vec![e0, e1, e1b], refuse(2, Reason::SeqReplay))); + + let mut a = Author::new(ALICE); + out.push(v( + "time_reversed", + "seq 1's t is one microsecond before seq 0's (§6.2)", + vec![a.at(5 * S, chat("later")), a.at(5 * S - 1, chat("earlier"))], + refuse(1, Reason::TimeReversed), + )); + + let mut h = Author::new(HOST); + out.push(v("payload_too_large", "a meta payload of 1025 bytes under the default bound of 1024 (§5, §6.1)", vec![h.at(S, Payload::Meta(vec![0x5A; 1025]))], refuse(0, Reason::PayloadTooLarge))); + + let mut a = Author::new(ALICE); + let mut kn = v( + "kind_not_permitted", + "a cue from a principal whose policy permits chat, reaction and vote only (§5, §6.1)", + vec![a.at(S, chat("ok")), a.at(2 * S, cue(cue_type::CHAPTER, 1, 0, None))], + refuse(1, Reason::KindNotPermitted), + ); + kn.own = vec![(ALICE, "chat_only")]; + out.push(kn); + + let mut a = Author::new(ALICE); + out.push(v( + "lifecycle_not_permitted", + "a join authored by a participant under the default policy, which permits no lifecycle kind (§5)", + vec![a.at(S, lifecycle(kind::JOIN, ALICE, b""))], + refuse(0, Reason::KindNotPermitted), + )); + + let mut a = Author::new(ALICE); + let mut rv = v( + "rate_exceeded", + "a fourth event within one second under a policy of three per second (§6.3)", + vec![a.at(0, chat("a")), a.at(250_000, chat("b")), a.at(500_000, chat("c")), a.at(999_999, chat("d"))], + refuse(3, Reason::RateExceeded), + ); + rv.own = vec![(ALICE, "slow")]; + out.push(rv); + + let mut a = Author::new(ALICE); + out.push(v( + "reaction_rate_exceeded", + "a second standalone reaction half a second after the first, under the default of one per second (§6.3)", + vec![a.at(10 * S, reaction(4, 1, None, false)), a.at(10_500_000, reaction(4, 1, None, false))], + refuse(1, Reason::RateExceeded), + )); + + let mut a = Author::new(ALICE); + out.push(v("bad_utf8_overlong", "a chat text that is the overlong encoding C0 AF (§4.1)", vec![a.raw(S, None, kind::CHAT, vec![2, 0, 0xC0, 0xAF]).to_bytes()], refuse(0, Reason::BadUtf8))); + let mut a = Author::new(ALICE); + out.push(v("bad_utf8_surrogate", "a chat text that encodes the surrogate U+D800 (ED A0 80) (§4.1)", vec![a.raw(S, None, kind::CHAT, vec![3, 0, 0xED, 0xA0, 0x80]).to_bytes()], refuse(0, Reason::BadUtf8))); + let mut a = Author::new(ALICE); + out.push(v("text_too_long", "a chat of 501 code points under the default of 500 (§4.1, §5)", vec![a.at(S, chat(&"a".repeat(501)))], refuse(0, Reason::TextTooLong))); + + let mut a = Author::new(ALICE); + let whole = a.at(S, chat("cut short")); + out.push(v("truncated_tail", "a record missing its last ten bytes (§3.3)", vec![whole[..whole.len() - 10].to_vec()], refuse(0, Reason::Truncated))); + out.push(v("truncated_header", "a record cut inside its prev field (§3.3)", vec![whole[..100].to_vec()], refuse(0, Reason::Truncated))); + let mut v2 = whole.clone(); + v2[4] = 2; + out.push(v("unknown_version", "a record whose version is 2 (§3.3)", vec![v2], refuse(0, Reason::UnknownVersion))); + let mut magic = whole.clone(); + magic[3] = b'2'; + out.push(v("malformed_magic", "a record that begins WEV2 (§3.3)", vec![magic], refuse(0, Reason::Malformed))); + let mut trailing = whole.clone(); + trailing.push(0); + out.push(v("malformed_trailing", "a record followed by one more byte (§3.3)", vec![trailing], refuse(0, Reason::Malformed))); + let mut flag = whole.clone(); + flag[117] = 2; + out.push(v("malformed_anchor_flag", "a record whose anchor flag is 2 (§3.3)", vec![flag], refuse(0, Reason::Malformed))); + + let mut a = Author::new(ALICE); + out.push(v("unknown_kind", "a signed record of kind 0x0D, which this revision does not define (§4, §6.1)", vec![a.raw(S, None, 0x0D, vec![]).to_bytes()], refuse(0, Reason::UnknownKind))); + let mut au = Author::new(AUTHORITY); + let mut uk = v( + "unknown_kind_lifecycle_reserved", + "a signed record of kind 0x17, in the lifecycle range but not defined in this revision (§4.13)", + vec![au.raw(S, None, 0x17, pk(ALICE).to_vec()).to_bytes()], + refuse(0, Reason::UnknownKind), + ); + uk.own = vec![(AUTHORITY, "authority")]; + out.push(uk); + + let mut a = Author::new(ALICE); + a.room = room(2); + out.push(v("wrong_room", "an event signed for another room (§6.1)", vec![a.at(S, chat("wrong place"))], refuse(0, Reason::WrongRoom))); + + let mut h = Author::new(HOST); + let mut section = splice_insert(9, true, None); + section[2] += 1; + out.push(v( + "malformed_payload_cue", + "a cue whose splice_info_section() states a section_length one more than it holds (§4.3)", + vec![h.at(S, cue(cue_type::OUT, 9, 0, Some((1, section))))], + refuse(0, Reason::MalformedPayload), + )); + let mut h = Author::new(HOST); + out.push(v("malformed_payload_lang", "a caption whose language tag is one letter (§4.10)", vec![h.at(S, caption(1000, 1, "e", "x"))], refuse(0, Reason::MalformedPayload))); + let mut h = Author::new(HOST); + out.push(v("malformed_payload_poll", "a poll_open with one option (§4.6)", vec![h.at(S, poll_open("Only one?", &["Yes"]))], refuse(0, Reason::MalformedPayload))); + + let mut h = Author::new(HOST); + let mut a = Author::new(ALICE); + let open = h.at(S, poll_open("Left or right?", &["Left", "Right"])); + let poll = digest_of(&open); + out.push(v( + "tally_mismatch", + "a poll_close stating counts the replay does not reach: one vote for Right, stated as one for Left (§7)", + vec![open, a.at(2 * S, Payload::Vote { poll, option: 1 }), h.at(3 * S, Payload::PollClose { poll, counts: vec![1, 0] })], + refuse(2, Reason::TallyMismatch), + )); + out +} + +fn vector_policies(vec: &Vector) -> RoomVerifier { + let r = if vec.room == "main" { room(1) } else { room(2) }; + let mut ver = RoomVerifier::new(r, policy(vec.default_policy)); + for (who, name) in &vec.own { + ver.set_policy(pk(*who), policy(name)); + } + ver +} + +fn gaps_json(gaps: &[Gap]) -> Value { + Value::Array(gaps.iter().map(|g| json!({"principal": hex(&g.principal), "first": g.first, "last": g.last})).collect()) +} + +fn tally_json(t: &Tally) -> Value { + json!({ + "state_hash": hex(&t.state_hash), + "polls": t.polls.iter().map(|p| json!({"poll": hex(&p.poll), "open": p.open, "counts": p.counts})).collect::>(), + }) +} + +fn bindings_json(record: &[u8]) -> Value { + json!({ + "msf": to_msf_record(record, T0_UNIX_US).expect("a corpus record binds"), + "daterange": to_daterange(record, T0_UNIX_US).expect("a corpus record binds"), + "emsg": hex(&to_emsg(record, PT0_MS).expect("a corpus record binds")), + }) +} + +fn vector_json(vec: &Vector) -> Value { + let mut ver = vector_policies(vec); + let outcome = verify_stream(&mut ver, &vec.events); + let want = match &vec.intent { + Intent::Accept => Outcome::Accept, + Intent::Gap(g) => Outcome::Gap(g.iter().map(|&(who, first, last)| Gap { principal: pk(who), first, last }).collect()), + Intent::Refuse(i, r) => Outcome::Refuse { index: *i, reason: *r }, + }; + assert_eq!(outcome, want, "vector {} does not reach the outcome it was written to have", vec.name); + let mut o = Map::new(); + o.insert("name".into(), json!(vec.name)); + o.insert("about".into(), json!(vec.about)); + o.insert("room".into(), json!(vec.room)); + o.insert("default_policy".into(), json!(vec.default_policy)); + let own: Map = vec.own.iter().map(|(who, name)| (hex(&pk(*who)), json!(name))).collect(); + o.insert("policies".into(), Value::Object(own)); + o.insert("events".into(), json!(vec.events.iter().map(|e| hex(e)).collect::>())); + match &outcome { + Outcome::Refuse { index, reason } => { + o.insert("outcome".into(), json!("refuse")); + o.insert("reason".into(), json!(reason.code())); + o.insert("index".into(), json!(index)); + } + Outcome::Gap(g) => { + o.insert("outcome".into(), json!("gap")); + o.insert("reason".into(), json!(Reason::DeliveryGap.code())); + o.insert("gaps".into(), gaps_json(g)); + o.insert("digests".into(), json!(vec.events.iter().map(|e| hex(&digest_of(e))).collect::>())); + } + Outcome::Accept => { + o.insert("outcome".into(), json!("accept")); + o.insert("digests".into(), json!(vec.events.iter().map(|e| hex(&digest_of(e))).collect::>())); + o.insert("tally".into(), tally_json(&ver.tally())); + o.insert("bindings".into(), Value::Array(vec.events.iter().map(|e| bindings_json(e)).collect())); + } + } + Value::Object(o) +} + +fn policy_cases() -> Value { + let d = Policy::default().to_bytes(); + let with = |f: &dyn Fn(&mut Vec)| { + let mut b = d.clone(); + f(&mut b); + b + }; + let mut cases: Vec<(&str, &str, Vec, Option)> = policies().into_iter().map(|(n, p)| (n, "a named policy of the vectors", p.to_bytes(), None)).collect(); + cases.extend([ + ("truncated", "the default policy without its last byte", d[..POLICY_LEN - 1].to_vec(), Some(Reason::Truncated)), + ("bad_magic", "a record that begins WEPX", with(&|b| b[3] = b'X'), Some(Reason::PolicyMalformed)), + ("unknown_version", "a record of version 2", with(&|b| b[4] = 2), Some(Reason::UnknownVersion)), + ("undefined_kind_0x0d", "kind 0x0D permitted, which this revision does not define", with(&|b| b[5 + 1] |= 1 << 5), Some(Reason::PolicyMalformed)), + ("undefined_kind_0x00", "kind 0x00 permitted", with(&|b| b[5] |= 1), Some(Reason::PolicyMalformed)), + ("zero_window", "window_us 0", with(&|b| b[45..53].copy_from_slice(&0u64.to_le_bytes())), Some(Reason::PolicyMalformed)), + ("zero_max_events", "max_events 0", with(&|b| b[41..45].copy_from_slice(&0u32.to_le_bytes())), Some(Reason::PolicyMalformed)), + ("trailing", "the default policy followed by one more byte", with(&|b| b.push(0)), Some(Reason::PolicyMalformed)), + ]); + Value::Array( + cases + .into_iter() + .map(|(name, about, bytes, want)| { + let got = Policy::parse(&bytes).err(); + assert_eq!(got, want, "policy case {name}"); + let mut o = json!({"name": name, "about": about, "policy": hex(&bytes)}); + match want { + None => o["outcome"] = json!("accept"), + Some(r) => { + o["outcome"] = json!("refuse"); + o["reason"] = json!(r.code()); + } + } + o + }) + .collect(), + ) +} + +fn binding_cases() -> Value { + let mut h = Author::new(HOST); + let cue_out = h.anchored(10 * S, video(0, 240), cue(cue_type::OUT, 101, 30_000, Some((1, splice_insert(101, true, Some(30 * 90_000)))))); + let cap = h.at(12 * S, caption(2500, 2, "en", "Hello.")); + let mut a = Author::new(ALICE); + let plain = a.at(1_234_567, chat("plain")); + let anchored = a.anchored(2 * S, video(0, 48), chat("anchored")); + + let tag = to_daterange(&cue_out, T0_UNIX_US).unwrap(); + let edit = |from: &str, to: &str| { + assert!(tag.contains(from), "{from}"); + tag.replacen(from, to, 1) + }; + let attrs: Vec<&str> = tag.strip_prefix(HLS_TAG).unwrap().split(',').collect(); + let reordered = format!("{HLS_TAG}X-COM-EXAMPLE-NOTE=\"a,b\",{}", attrs.iter().rev().copied().collect::>().join(",")); + let start = iso8601_ms((T0_UNIX_US + 10 * S) / 1000).unwrap(); + let start_off = iso8601_ms((T0_UNIX_US + 10 * S) / 1000 + 1).unwrap(); + let scte_hex = tag.split("SCTE35-OUT=").nth(1).unwrap().split(',').next().unwrap().to_string(); + let b64 = b64url_encode(&cue_out); + let without = |name: &str| { + format!("{HLS_TAG}{}", attrs.iter().filter(|a| !a.starts_with(&format!("{name}="))).copied().collect::>().join(",")) + }; + + let em = to_emsg(&cue_out, PT0_MS).unwrap(); + let em_with = |f: &dyn Fn(&mut Vec)| { + let mut b = em.clone(); + f(&mut b); + b + }; + let em_scheme = { + let other = b"urn:example:x:1"; + let mut b = em[..32].to_vec(); + b.extend_from_slice(other); + b.extend_from_slice(&em[32 + EVENT_TYPE.len()..]); + let n = b.len() as u32; + b[..4].copy_from_slice(&n.to_be_bytes()); + b + }; + let em_value = { + let mut b = em[..32 + EVENT_TYPE.len() + 1].to_vec(); + b.extend_from_slice(b"chat"); + b.extend_from_slice(&em[32 + EVENT_TYPE.len() + 1 + "cue".len()..]); + let n = b.len() as u32; + b[..4].copy_from_slice(&n.to_be_bytes()); + b + }; + + let msf_plain = to_msf_record(&plain, T0_UNIX_US).unwrap(); + let msf_anch = to_msf_record(&anchored, T0_UNIX_US).unwrap(); + let ms = (T0_UNIX_US + 1_234_567) / 1000; + let b64p = b64url_encode(&plain); + let b64a = b64url_encode(&anchored); + + use Reason::{BindingMalformed as Mal, BindingMismatch as Mis}; + const NONE: &[u8] = &[]; + let (cue_out, cap, plain, anchored) = (cue_out.as_slice(), cap.as_slice(), plain.as_slice(), anchored.as_slice()); + let cases: Vec = vec![ + ("daterange_cue_out", "§8.3: a splice out with its planned duration and SCTE35-OUT", "daterange", tag.clone(), None, cue_out), + ("daterange_caption", "§8.3: a caption with its DURATION", "daterange", to_daterange(cap, T0_UNIX_US).unwrap(), None, cap), + ("daterange_chat", "§8.3: an event with no duration", "daterange", to_daterange(plain, T0_UNIX_US).unwrap(), None, plain), + ("daterange_reordered_extra", "§8.3: the attributes in reverse order, with a client attribute this binding does not define, whose quoted value holds a comma", "daterange", reordered, None, cue_out), + ("daterange_start_date_off", "§8.3: START-DATE one millisecond late", "daterange", edit(&start, &start_off), Some(Mis), NONE), + ("daterange_class_other", "§8.3: another CLASS", "daterange", edit(HLS_CLASS, "com.example.other"), Some(Mis), NONE), + ("daterange_scte_dropped", "§8.3: the SCTE35-OUT a 35-1 out cue carries, removed", "daterange", without("SCTE35-OUT"), Some(Mis), NONE), + ("daterange_scte_lowercase", "§8.3: SCTE35-OUT in lowercase hexadecimal", "daterange", edit(&scte_hex, &format!("0x{}", scte_hex[2..].to_lowercase())), Some(Mis), NONE), + ("daterange_duration_respelled", "§8.3: PLANNED-DURATION written 30 instead of 30.000", "daterange", edit("PLANNED-DURATION=30.000", "PLANNED-DURATION=30"), Some(Mis), NONE), + ("daterange_id_other", "§8.3: an ID that is not the event's digest", "daterange", edit("ID=\"", "ID=\"0"), Some(Mis), NONE), + ("daterange_padded", "§8.3: X-WAI-EVENT with base64 padding", "daterange", edit(&format!("\"{b64}\""), &format!("\"{b64}==\"")), Some(Mal), NONE), + ("daterange_unterminated", "§8.3: X-WAI-EVENT's closing quote removed", "daterange", tag[..tag.len() - 1].to_string(), Some(Mal), NONE), + ("daterange_no_event", "§8.3: no X-WAI-EVENT", "daterange", without(HLS_ATTRIBUTE), Some(Mal), NONE), + ("daterange_other_tag", "§8.3: not an EXT-X-DATERANGE tag", "daterange", tag.replacen("#EXT-X-DATERANGE:", "#EXT-X-DATERANGES:", 1), Some(Mal), NONE), + ("emsg_cue_out", "§8.4: a cue's box, event_duration its planned duration", "emsg", hex(&em), None, cue_out), + ("emsg_chat", "§8.4: a chat's box, event_duration 0", "emsg", hex(&to_emsg(plain, PT0_MS).unwrap()), None, plain), + ("emsg_caption", "§8.4: a caption's box", "emsg", hex(&to_emsg(cap, PT0_MS).unwrap()), None, cap), + ("emsg_presentation_time_off", "§8.4: presentation_time one millisecond late", "emsg", hex(&em_with(&|b| b[23] += 1)), Some(Mis), NONE), + ("emsg_scheme_other", "§8.4: another scheme_id_uri", "emsg", hex(&em_scheme), Some(Mis), NONE), + ("emsg_value_other", "§8.4: value names another kind", "emsg", hex(&em_value), Some(Mis), NONE), + ("emsg_timescale_other", "§8.4: timescale 90000", "emsg", hex(&em_with(&|b| b[12..16].copy_from_slice(&90_000u32.to_be_bytes()))), Some(Mis), NONE), + ("emsg_version_0", "§8.4: a version 0 box", "emsg", hex(&em_with(&|b| b[8] = 0)), Some(Mal), NONE), + ("emsg_size_wrong", "§8.4: a size one more than the box", "emsg", hex(&em_with(&|b| b[3] += 1)), Some(Mal), NONE), + ("msf_t", "§8.1: an unanchored event, indexed by t", "msf", msf_plain.clone(), None, plain), + ("msf_l", "§8.1: an anchored event, indexed by l", "msf", msf_anch.clone(), None, anchored), + ("msf_respaced", "§8.1: the same record with its members reordered, whitespace, and a member this binding does not define", "msf", format!("{{ \"data\" : {{ \"note\": 1, \"wev1\" : \"{b64p}\" }} ,\n \"t\" : {ms} }}"), None, plain), + ("msf_t_for_anchored", "§8.1: an anchored event indexed by t", "msf", format!("{{\"t\":{},\"data\":{{\"wev1\":\"{b64a}\"}}}}", (T0_UNIX_US + 2 * S) / 1000), Some(Mis), NONE), + ("msf_t_off", "§8.1: t one millisecond late", "msf", format!("{{\"t\":{},\"data\":{{\"wev1\":\"{b64p}\"}}}}", ms + 1), Some(Mis), NONE), + ("msf_t_float", "§8.1: t written as a fraction", "msf", format!("{{\"t\":{ms}.0,\"data\":{{\"wev1\":\"{b64p}\"}}}}"), Some(Mis), NONE), + ("msf_m_index", "§8.1: indexed by m, which this binding never writes", "msf", format!("{{\"m\":0,\"data\":{{\"wev1\":\"{b64p}\"}}}}"), Some(Mis), NONE), + ("msf_two_indexes", "§8.1: both t and l (MSF §8.1: one index per record)", "msf", format!("{{\"t\":{ms},\"l\":[0,48],\"data\":{{\"wev1\":\"{b64a}\"}}}}"), Some(Mal), NONE), + ("msf_no_data", "§8.1: no data member", "msf", format!("{{\"t\":{ms}}}"), Some(Mal), NONE), + ]; + Value::Array( + cases + .into_iter() + .map(|(name, about, binding, input, want, record)| { + let got = run_binding(binding, &input); + match want { + None => assert_eq!(got.as_deref(), Ok(record), "binding case {name}"), + Some(r) => assert_eq!(got, Err(r), "binding case {name}"), + } + let mut o = json!({"name": name, "about": about, "binding": binding, "input": input}); + match want { + None => { + o["outcome"] = json!("accept"); + o["record"] = json!(hex(record)); + } + Some(r) => { + o["outcome"] = json!("refuse"); + o["reason"] = json!(r.code()); + } + } + o + }) + .collect(), + ) +} + +/// A binding case: name, about, binding, input, the refusal or none, the record read. +type BindingCase<'a> = (&'a str, &'a str, &'a str, String, Option, &'a [u8]); + +/// Read a binding case's input with the corpus's `t0` and presentation time. +fn run_binding(binding: &str, input: &str) -> Result, Reason> { + match binding { + "daterange" => from_daterange(input, T0_UNIX_US), + "emsg" => from_emsg(&unhex(input).ok_or(Reason::BindingMalformed)?, PT0_MS), + "msf" => from_msf_record(input, T0_UNIX_US), + _ => Err(Reason::BindingMalformed), + } +} + +/// The corpus file, `vectors.json`. +pub fn generate() -> String { + let mut vectors: Vec = good_vectors().iter().map(vector_json).collect(); + vectors.extend(negative_vectors().iter().map(vector_json)); + let doc = json!({ + "corpus": "wai.live.events", + "extension": "extensions/live-events.md", + "t0_unix_us": T0_UNIX_US, + "pt0_ms": PT0_MS, + "principals": PRINCIPALS.iter().map(|(n, i)| (n.to_string(), json!(hex(&pk(*i))))).collect::>(), + "rooms": {"main": hex(&room(1)), "other": hex(&room(2))}, + "policies": policies().into_iter().map(|(n, p)| (n.to_string(), json!(hex(&p.to_bytes())))).collect::>(), + "vectors": vectors, + "policy_cases": policy_cases(), + "binding_cases": binding_cases(), + }); + serde_json::to_string_pretty(&doc).expect("the corpus serialises") + "\n" +} + +fn d32(v: &Value) -> Option<[u8; 32]> { + unhex(v.as_str()?)?.try_into().ok() +} + +/// Check a corpus file against this module; the failures, one line each. +pub fn verify(doc: &str) -> Vec { + let mut fails = Vec::new(); + let root: Value = match serde_json::from_str(doc) { + Ok(v) => v, + Err(e) => return vec![format!("the corpus does not parse: {e}")], + }; + let t0 = root["t0_unix_us"].as_u64().unwrap_or(0); + let pt0 = root["pt0_ms"].as_u64().unwrap_or(0); + let mut named: BTreeMap = BTreeMap::new(); + for (n, h) in root["policies"].as_object().into_iter().flatten() { + match h.as_str().and_then(unhex).map(|b| Policy::parse(&b)) { + Some(Ok(p)) => { + named.insert(n.clone(), p); + } + _ => fails.push(format!("policy {n} does not read")), + } + } + let rooms: BTreeMap = + root["rooms"].as_object().into_iter().flatten().filter_map(|(n, h)| Some((n.clone(), d32(h)?))).collect(); + for vec in root["vectors"].as_array().into_iter().flatten() { + let name = vec["name"].as_str().unwrap_or("?"); + let mut fail = |m: String| fails.push(format!("{name}: {m}")); + let (Some(r), Some(dp)) = (vec["room"].as_str().and_then(|r| rooms.get(r)), vec["default_policy"].as_str().and_then(|p| named.get(p))) else { + fail("room or default policy not found".into()); + continue; + }; + let mut ver = RoomVerifier::new(*r, *dp); + for (who, p) in vec["policies"].as_object().into_iter().flatten() { + match (unhex(who).and_then(|b| <[u8; 32]>::try_from(b).ok()), p.as_str().and_then(|p| named.get(p))) { + (Some(w), Some(p)) => ver.set_policy(w, *p), + _ => fail(format!("policy entry {who} does not read")), + } + } + let events: Vec> = vec["events"].as_array().into_iter().flatten().filter_map(|e| e.as_str().and_then(unhex)).collect(); + let outcome = verify_stream(&mut ver, &events); + let want = vec["outcome"].as_str().unwrap_or("?"); + match (&outcome, want) { + (Outcome::Refuse { index, reason }, "refuse") => { + if vec["reason"].as_str() != Some(reason.code()) || vec["index"].as_u64() != Some(*index as u64) { + fail(format!("refused at {index} with {reason}, the corpus states {} at {}", vec["reason"], vec["index"])); + } + } + (Outcome::Gap(g), "gap") => { + if gaps_json(g) != vec["gaps"] { + fail(format!("gaps {} differ from the corpus's", gaps_json(g))); + } + } + (Outcome::Accept, "accept") => { + if tally_json(&ver.tally()) != vec["tally"] { + fail("the tally differs".into()); + } + let bindings = vec["bindings"].as_array().cloned().unwrap_or_default(); + if bindings.len() != events.len() { + fail("not one binding entry per event".into()); + } + for (i, (e, b)) in events.iter().zip(&bindings).enumerate() { + if bindings_json(e) != *b { + fail(format!("event {i}: a rendering differs")); + } + let back = [ + b["msf"].as_str().map(|s| from_msf_record(s, t0)), + b["daterange"].as_str().map(|s| from_daterange(s, t0)), + b["emsg"].as_str().and_then(unhex).map(|x| from_emsg(&x, pt0)), + ]; + if back.iter().any(|r| r.as_ref().map(|r| r.as_deref()) != Some(Ok(e.as_slice()))) { + fail(format!("event {i}: a binding does not read back to the record")); + } + } + } + _ => fail(format!("outcome {outcome:?}, the corpus states {want}")), + } + if matches!(outcome, Outcome::Accept | Outcome::Gap(_)) { + let got: Vec = events.iter().map(|e| json!(hex(&digest_of(e)))).collect(); + if Value::Array(got) != vec["digests"] { + fail("the digests differ".into()); + } + } + } + for c in root["policy_cases"].as_array().into_iter().flatten() { + let got = c["policy"].as_str().and_then(unhex).map(|b| Policy::parse(&b).err()); + let want = match c["outcome"].as_str() { + Some("accept") => Some(None), + _ => Some(c["reason"].as_str().and_then(Reason::from_code)), + }; + if got != want { + fails.push(format!("policy case {}: {got:?}", c["name"])); + } + } + for c in root["binding_cases"].as_array().into_iter().flatten() { + let got = run_binding(c["binding"].as_str().unwrap_or(""), c["input"].as_str().unwrap_or("")); + let ok = match c["outcome"].as_str() { + Some("accept") => c["record"].as_str().and_then(unhex).is_some_and(|r| got.as_deref() == Ok(r.as_slice())), + _ => c["reason"].as_str().and_then(Reason::from_code).is_some_and(|r| got == Err(r)), + }; + if !ok { + fails.push(format!("binding case {}: {:?}", c["name"], got.map(|r| hex(&r)))); + } + } + fails +} diff --git a/wai/wai-rs/src/live_room.rs b/wai/wai-rs/src/live_room.rs new file mode 100644 index 000000000..e9fc7b207 --- /dev/null +++ b/wai/wai-rs/src/live_room.rs @@ -0,0 +1,2133 @@ +//! Live rooms — `wai.live.room` ([extensions/live-rooms.md]). +//! +//! A room is fixed by a signed **room descriptor** (`WRD1`): its authority, its clock and +//! `t0`, the roles a principal may hold, its limits, the virtual tracks (slots) several +//! publishers may stand behind, the publish profiles, and its review and recording +//! policies. The room's id is the descriptor's digest, the 32 bytes every `WEV1` event of +//! [`crate::live_events`] names. A principal takes part under a **room grant** (`WRG1`), +//! which the authority signs: its role and capabilities, its window (`nbf`, `exp`, at most +//! fourteen days), the delivery origins it is good for, a single-use nonce, a viewer id +//! for revocation, the `WEP1` event policy of live-events §5 it is held to, its joule and +//! funds ceilings, the profiles it publishes with, and composition attributes. +//! +//! What this module implements, by section of the extension: +//! +//! - §3: the descriptor, read, its field rules, its digest and signature; +//! - §4: the grant, read, its field rules, its digest and signature, its exchange link +//! and its bound by the role and by the room's ceiling; +//! - §5: revocation through the room authority's key log (jwp-receipts §7): the head the +//! caller reached is held for the descriptor's origin, lists the authority with +//! `live/room`, and its `revoked_modules` list the grants and viewers revoked; +//! - §6: track naming, a MoQ Full Track Name per principal (or slot), media and layer; +//! - §7: precedence and redundancy over slots, as lifecycle `detail`; +//! - §8: the publish profiles, as data; +//! - §9: room verification, which merges every principal's chain by room clock, verifies +//! every event with [`crate::live_events::RoomVerifier`] under the policy of the grant +//! in effect at its `t`, and replays the lifecycle into room state; +//! - §10: the `moqt` claim scopes a grant maps onto (`draft-ietf-moq-c4m-01`), as data. +//! +//! The corpus `live-conformance/rooms/` is written by [`corpus::generate`] and checked by +//! [`corpus::verify`] here, and by `live-conformance/live_rooms_verify.py`, which shares no +//! code with this module. +//! +//! [extensions/live-rooms.md]: ../../extensions/live-rooms.md + +use std::collections::{BTreeMap, BTreeSet}; + +use ed25519_dalek::{Signer, SigningKey}; +use sha2::{Digest, Sha256}; + +use crate::key_log::{EntryStatus, Revision}; +use crate::live_events::{self as events, kind, Command, Event, Payload, Policy, RoomVerifier}; + +pub mod corpus; + +/// The magic of a room descriptor (§3.1). +pub const DESCRIPTOR_MAGIC: [u8; 4] = *b"WRD1"; +/// The magic of a room grant (§4.1). +pub const GRANT_MAGIC: [u8; 4] = *b"WRG1"; +/// The version of both records this revision defines. +pub const RECORD_VERSION: u8 = 1; +/// The domain a descriptor's signature is made over (§3.2). +pub const DESCRIPTOR_DOMAIN: &[u8] = b"wai:live-room\x01"; +/// The domain a grant's signature is made over (§4.2). +pub const GRANT_DOMAIN: &[u8] = b"wai:live-room-grant\x01"; +/// The domain of a viewer's revocation tag (§5). +pub const VIEWER_DOMAIN: &[u8] = b"wai:live-viewer\x01"; +/// The key-log authority a room authority's key needs (§5, jwp-receipts §7.5). +pub const KEY_LOG_AUTHORITY: &str = "live/room"; +/// The capability a receipt's grant reference names for a room grant (§4.5). +pub const CAPABILITY: &str = "wai.live.room"; +/// The longest a grant may be good for, `exp − nbf`, in seconds: fourteen days (§4.3). +pub const MAX_GRANT_S: u64 = 14 * 86_400; +/// The most bytes a grant's attributes take (§4.4). +pub const MAX_ATTRS: usize = 1024; +/// "No ceiling", for `joules_ceiling` and `funds_ceiling` (§4.1). +pub const NO_CEILING: u64 = u64::MAX; + +/// Media kinds (§6.1): a publish capability is a bit per kind, bit `m − 1`. +pub mod media { + pub const AUDIO: u8 = 1; + pub const VIDEO: u8 = 2; + pub const SCREEN: u8 = 3; +} + +/// The name of a media kind in a track namespace (§6.1); `None` for another code. +pub fn media_name(m: u8) -> Option<&'static str> { + match m { + media::AUDIO => Some("audio"), + media::VIDEO => Some("video"), + media::SCREEN => Some("screen"), + _ => None, + } +} + +/// The namespace field of a principal's events track (§6.1). +pub const EVENTS_FIELD: &str = "events"; + +/// The powers of a capability set (§3.3), one bit each. +pub mod power { + pub const MODERATE: u8 = 1; + pub const DIRECT: u8 = 2; + pub const COMPOSE: u8 = 4; + pub const RECORD: u8 = 8; +} + +/// The layering of a publish profile (§8.1). +pub mod layering { + pub const SINGLE: u8 = 0; + pub const SIMULCAST: u8 = 1; + pub const SVC: u8 = 2; + pub const STAGED: u8 = 3; +} + +/// The audio processing a profile turns on (§8.1), one bit each. +pub mod processing { + pub const ECHO_CANCELLATION: u8 = 1; + pub const NOISE_SUPPRESSION: u8 = 2; + pub const GAIN_CONTROL: u8 = 4; + pub const DTX: u8 = 8; +} + +/// Why a room, a grant, a key-log head or a chain is refused (§11). The codes of +/// live-events §9 are raised here too, wherever that extension's rules apply. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Reason { + /// A code of live-events §9. + Events(events::Reason), + DescriptorInvalid, + KeyLogMissing, + KeyLogNotHeld, + AuthorityNotListed, + AuthorityRevoked, + GrantInvalid, + GrantTooLong, + CapsExceedRole, + GrantExceedsRoom, + ExchangeUnlinked, + ExchangeMismatch, + LifecycleMalformed, + GrantUnknown, + GrantWrongPrincipal, + GrantRevoked, + GrantReused, + AlreadyPresent, + NotPresent, + ParticipantLimit, + OutsideGrantWindow, + PowerNotGranted, + PublishNotPermitted, + ProfileNotGranted, + AlreadyPublished, + NotPublished, + SlotUnknown, + SlotFull, + PublisherLimit, + ExchangeNotCurrent, + ExchangeOffTick, + TakeoverNotHigher, + FailoverNotStandby, + FailoverEarly, +} + +impl From for Reason { + fn from(r: events::Reason) -> Self { + Reason::Events(r) + } +} + +impl Reason { + /// The codes this extension adds, in §11's order. + pub const ALL: [Reason; 33] = [ + Reason::DescriptorInvalid, + Reason::KeyLogMissing, + Reason::KeyLogNotHeld, + Reason::AuthorityNotListed, + Reason::AuthorityRevoked, + Reason::GrantInvalid, + Reason::GrantTooLong, + Reason::CapsExceedRole, + Reason::GrantExceedsRoom, + Reason::ExchangeUnlinked, + Reason::ExchangeMismatch, + Reason::LifecycleMalformed, + Reason::GrantUnknown, + Reason::GrantWrongPrincipal, + Reason::GrantRevoked, + Reason::GrantReused, + Reason::AlreadyPresent, + Reason::NotPresent, + Reason::ParticipantLimit, + Reason::OutsideGrantWindow, + Reason::PowerNotGranted, + Reason::PublishNotPermitted, + Reason::ProfileNotGranted, + Reason::AlreadyPublished, + Reason::NotPublished, + Reason::SlotUnknown, + Reason::SlotFull, + Reason::PublisherLimit, + Reason::ExchangeNotCurrent, + Reason::ExchangeOffTick, + Reason::TakeoverNotHigher, + Reason::FailoverNotStandby, + Reason::FailoverEarly, + ]; + + /// The conformance code. + pub fn code(self) -> &'static str { + match self { + Reason::Events(r) => r.code(), + Reason::DescriptorInvalid => "descriptor_invalid", + Reason::KeyLogMissing => "key_log_missing", + Reason::KeyLogNotHeld => "key_log_not_held", + Reason::AuthorityNotListed => "authority_not_listed", + Reason::AuthorityRevoked => "authority_revoked", + Reason::GrantInvalid => "grant_invalid", + Reason::GrantTooLong => "grant_too_long", + Reason::CapsExceedRole => "caps_exceed_role", + Reason::GrantExceedsRoom => "grant_exceeds_room", + Reason::ExchangeUnlinked => "exchange_unlinked", + Reason::ExchangeMismatch => "exchange_mismatch", + Reason::LifecycleMalformed => "lifecycle_malformed", + Reason::GrantUnknown => "grant_unknown", + Reason::GrantWrongPrincipal => "grant_wrong_principal", + Reason::GrantRevoked => "grant_revoked", + Reason::GrantReused => "grant_reused", + Reason::AlreadyPresent => "already_present", + Reason::NotPresent => "not_present", + Reason::ParticipantLimit => "participant_limit", + Reason::OutsideGrantWindow => "outside_grant_window", + Reason::PowerNotGranted => "power_not_granted", + Reason::PublishNotPermitted => "publish_not_permitted", + Reason::ProfileNotGranted => "profile_not_granted", + Reason::AlreadyPublished => "already_published", + Reason::NotPublished => "not_published", + Reason::SlotUnknown => "slot_unknown", + Reason::SlotFull => "slot_full", + Reason::PublisherLimit => "publisher_limit", + Reason::ExchangeNotCurrent => "exchange_not_current", + Reason::ExchangeOffTick => "exchange_off_tick", + Reason::TakeoverNotHigher => "takeover_not_higher", + Reason::FailoverNotStandby => "failover_not_standby", + Reason::FailoverEarly => "failover_early", + } + } + + /// The reason with this code: one of this extension's, or one of live-events §9. + pub fn from_code(code: &str) -> Option { + Reason::ALL.iter().copied().find(|r| r.code() == code).or_else(|| events::Reason::from_code(code).map(Reason::Events)) + } +} + +impl std::fmt::Display for Reason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.code()) + } +} + +impl std::error::Error for Reason {} + +const TRUNCATED: Reason = Reason::Events(events::Reason::Truncated); +const MALFORMED: Reason = Reason::Events(events::Reason::Malformed); +const UNKNOWN_VERSION: Reason = Reason::Events(events::Reason::UnknownVersion); + +// --------------------------------------------------------------------------------------- +// Reading +// --------------------------------------------------------------------------------------- + +/// A cursor; running out is `truncated` (§3.4, §4.3). +struct Rd<'a> { + b: &'a [u8], + p: usize, +} + +impl<'a> Rd<'a> { + fn take(&mut self, n: usize) -> Result<&'a [u8], Reason> { + let end = self.p.checked_add(n).ok_or(TRUNCATED)?; + let s = self.b.get(self.p..end).ok_or(TRUNCATED)?; + self.p = end; + Ok(s) + } + fn u8(&mut self) -> Result { + Ok(self.take(1)?[0]) + } + fn u16(&mut self) -> Result { + Ok(u16::from_le_bytes(self.take(2)?.try_into().expect("two bytes"))) + } + fn u32(&mut self) -> Result { + Ok(u32::from_le_bytes(self.take(4)?.try_into().expect("four bytes"))) + } + fn u64(&mut self) -> Result { + Ok(u64::from_le_bytes(self.take(8)?.try_into().expect("eight bytes"))) + } + fn d32(&mut self) -> Result<[u8; 32], Reason> { + Ok(self.take(32)?.try_into().expect("32 bytes")) + } + fn arr(&mut self) -> Result<[u8; N], Reason> { + Ok(self.take(N)?.try_into().expect("N bytes")) + } + /// A name: a u8 length and that many bytes (§3.1). + fn name(&mut self) -> Result, Reason> { + let n = self.u8()? as usize; + Ok(self.take(n)?.to_vec()) + } + /// A string: a u16 length and that many bytes (§3.1). + fn string(&mut self) -> Result, Reason> { + let n = self.u16()? as usize; + Ok(self.take(n)?.to_vec()) + } +} + +/// The magic, then the version, as live-events §3.3 reads a record's first five bytes. +fn read_head(b: &[u8], magic: &[u8; 4]) -> Result<(), Reason> { + if b.len() < 4 { + return Err(TRUNCATED); + } + if &b[..4] != magic { + return Err(MALFORMED); + } + if b.len() < 5 { + return Err(TRUNCATED); + } + if b[4] != RECORD_VERSION { + return Err(UNKNOWN_VERSION); + } + Ok(()) +} + +fn put_name(o: &mut Vec, s: &str) { + assert!(s.len() <= u8::MAX as usize, "a name is at most 255 bytes"); + o.push(s.len() as u8); + o.extend_from_slice(s.as_bytes()); +} + +fn put_string(o: &mut Vec, s: &[u8]) { + assert!(s.len() <= u16::MAX as usize, "a string is at most 65535 bytes"); + o.extend_from_slice(&(s.len() as u16).to_le_bytes()); + o.extend_from_slice(s); +} + +/// A name of a role or a profile (§3.1): 1 to 32 of `a`–`z`, `0`–`9`, `_` and `-`. +pub fn name_ok(b: &[u8]) -> bool { + (1..=32).contains(&b.len()) && b.iter().all(|&c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == b'_' || c == b'-') +} + +/// A slot's name or an attribute's key (§3.1): 1 to 32 of `a`–`z`, `0`–`9` and `_`. +pub fn slot_name_ok(b: &[u8]) -> bool { + (1..=32).contains(&b.len()) && b.iter().all(|&c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == b'_') +} + +/// A token (§3.1): visible ASCII, `!` to `~`, no space. +fn token_ok(b: &[u8], max: usize) -> bool { + (1..=max).contains(&b.len()) && b.iter().all(|&c| (0x21..=0x7E).contains(&c)) +} + +fn text(b: &[u8]) -> String { + String::from_utf8_lossy(b).into_owned() +} + +fn sha256(parts: &[&[u8]]) -> [u8; 32] { + let mut h = Sha256::new(); + for p in parts { + h.update(p); + } + h.finalize().into() +} + +fn hex(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() +} + +fn subset(a: u8, b: u8) -> bool { + a & !b == 0 +} + +fn kinds_subset(a: &[u8; 32], b: &[u8; 32]) -> bool { + a.iter().zip(b).all(|(x, y)| x & !y == 0) +} + +fn permits_lifecycle(p: &Policy) -> bool { + (0x10..=0x1F).any(|k| p.permits(k)) +} + +// --------------------------------------------------------------------------------------- +// §3 The room descriptor +// --------------------------------------------------------------------------------------- + +/// A capability set (§3.3): what a role, or a grant within it, may do. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub struct Caps { + /// Bit `m − 1` for each media kind `m` it may publish. + pub publish: u8, + /// Whether it may subscribe. + pub subscribe: bool, + /// The highest layer it may subscribe to. + pub max_layer: u8, + /// [`power`] bits. + pub powers: u8, +} + +impl Caps { + pub fn publishes(&self, m: u8) -> bool { + (1..=3).contains(&m) && self.publish & (1 << (m - 1)) != 0 + } +} + +/// A role (§3.3): a name, a capability set, and the event kinds it may send. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Role { + pub name: String, + pub caps: Caps, + /// The kinds bitmap of live-events §5. + pub events: [u8; 32], +} + +/// A slot (§7.1): a virtual track one live publisher stands behind, with a standby when +/// its redundancy is 2. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Slot { + pub name: String, + pub media: u8, + pub redundancy: u8, + pub failover_ms: u32, +} + +/// One layer of a publish profile (§8.1). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Layer { + pub width: u16, + pub height: u16, + pub fps: u16, + pub min_kbps: u32, + pub max_kbps: u32, +} + +/// A publish profile (§8): codec choices, layers and limits, as data. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Profile { + pub name: String, + pub media: u8, + /// RFC 6381 `codecs` values, in the order a publisher prefers them. + pub codecs: Vec, + pub layering: u8, + /// The scalability mode of a layered (SVC) profile, by its W3C name; empty otherwise. + pub mode: String, + pub layers: Vec, + pub sample_rate: u32, + pub channels: u8, + pub processing: u8, +} + +/// The review policy (§3.6): semantics only. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Review { + pub kinds: [u8; 32], + pub deadline_ms: u32, + /// 0 when no kind is reviewed; 1 allow, 2 deny. + pub fallback: u8, +} + +/// The recording policy (§3.7). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Recording { + /// 0 never, 1 on a `record_start` command, 2 always. + pub mode: u8, + /// 0: no bound. + pub retention_days: u16, + /// The interval, in milliseconds, at which a capturing device commits its take + /// (capture-binding §5); 0 when `mode` is 0. + pub commit_interval_ms: u32, + /// The jitter, in milliseconds, a take's timing is allowed (capture-binding §7); 0 when + /// `mode` is 0, and at most `commit_interval_ms`. + pub jitter_ms: u32, + /// The region pin: ISO 3166-1 alpha-2 codes, ascending; empty for no pin. + pub regions: Vec<[u8; 2]>, +} + +/// The room's limits (§3.5). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Limits { + pub max_present: u32, + pub max_publishers: u16, + /// The `moqt-reval` interval a grant's token carries, in seconds; 0: none (§10). + pub reval_s: u32, + /// The event ceiling no grant's policy may exceed: a `WEP1` record. + pub ceiling: Policy, +} + +/// A room descriptor (§3). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Descriptor { + pub authority: [u8; 32], + pub clock: [u8; 32], + /// The room's `t0`, in microseconds since 1970-01-01T00:00:00Z. + pub t0_us: u64, + /// The room-clock tick a grant exchange takes effect on, in microseconds. + pub tick_us: u64, + /// The origin whose key log lists the authority; empty for none. + pub origin: String, + pub limits: Limits, + pub roles: Vec, + pub slots: Vec, + pub profiles: Vec, + pub review: Review, + pub recording: Recording, + pub sig: [u8; 64], +} + +/// A profile's texts as read (§8.1): its name, its codecs and its mode. +type ProfileTexts = (Vec, Vec>, Vec); + +/// The descriptor as read (§3.4), before its field rules: texts kept as bytes. +struct RawDescriptor { + d: Descriptor, + body: Vec, + names: Vec>, + subscribe: Vec, + slot_names: Vec>, + profile_texts: Vec, + origin: Vec, + ceiling: [u8; 65], +} + +fn put_layer(o: &mut Vec, l: &Layer) { + o.extend_from_slice(&l.width.to_le_bytes()); + o.extend_from_slice(&l.height.to_le_bytes()); + o.extend_from_slice(&l.fps.to_le_bytes()); + o.extend_from_slice(&l.min_kbps.to_le_bytes()); + o.extend_from_slice(&l.max_kbps.to_le_bytes()); +} + +impl Profile { + /// The profile's bytes (§8.1). + pub fn encode(&self, o: &mut Vec) { + put_name(o, &self.name); + o.push(self.media); + assert!(self.codecs.len() <= u8::MAX as usize); + o.push(self.codecs.len() as u8); + for c in &self.codecs { + put_name(o, c); + } + o.push(self.layering); + put_name(o, &self.mode); + assert!(self.layers.len() <= u8::MAX as usize); + o.push(self.layers.len() as u8); + for l in &self.layers { + put_layer(o, l); + } + o.extend_from_slice(&self.sample_rate.to_le_bytes()); + o.push(self.channels); + o.push(self.processing); + } + + fn read(r: &mut Rd) -> Result<(Profile, ProfileTexts), Reason> { + let name = r.name()?; + let media = r.u8()?; + let n = r.u8()? as usize; + let mut codecs = Vec::with_capacity(n); + for _ in 0..n { + codecs.push(r.name()?); + } + let layering = r.u8()?; + let mode = r.name()?; + let n = r.u8()? as usize; + let mut layers = Vec::with_capacity(n); + for _ in 0..n { + layers.push(Layer { width: r.u16()?, height: r.u16()?, fps: r.u16()?, min_kbps: r.u32()?, max_kbps: r.u32()? }); + } + let p = Profile { + name: text(&name), + media, + codecs: codecs.iter().map(|c| text(c)).collect(), + layering, + mode: text(&mode), + layers, + sample_rate: r.u32()?, + channels: r.u8()?, + processing: r.u8()?, + }; + Ok((p, (name, codecs, mode))) + } + + /// §8.1's rules over one profile, given its texts as read. + fn valid(&self, name: &[u8], codecs: &[Vec], mode: &[u8]) -> bool { + if !name_ok(name) || media_name(self.media).is_none() || !(1..=4).contains(&codecs.len()) { + return false; + } + if !codecs.iter().all(|c| token_ok(c, 64)) || self.layering > layering::STAGED { + return false; + } + let mode_ok = (1..=16).contains(&mode.len()) && mode.iter().all(|&c| c.is_ascii_uppercase() || c.is_ascii_digit() || c == b'_'); + if (self.layering == layering::SVC) != (!mode.is_empty()) || (!mode.is_empty() && !mode_ok) { + return false; + } + let n = self.layers.len(); + if !(1..=8).contains(&n) || (self.layering == layering::SINGLE && n != 1) { + return false; + } + let audio = self.media == media::AUDIO; + for l in &self.layers { + if l.max_kbps == 0 || l.min_kbps > l.max_kbps { + return false; + } + let pictured = l.width > 0 && l.height > 0 && l.fps > 0; + let silent = l.width == 0 && l.height == 0 && l.fps == 0; + if (audio && !silent) || (!audio && !pictured) { + return false; + } + } + if audio { + self.sample_rate > 0 && (1..=8).contains(&self.channels) && subset(self.processing, 0x0F) + } else { + self.sample_rate == 0 && self.channels == 0 && self.processing == 0 + } + } +} + +impl Descriptor { + /// The descriptor without `sig` (§3.1): what the digest covers and the signature signs. + pub fn body(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&DESCRIPTOR_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.authority); + o.extend_from_slice(&self.clock); + o.extend_from_slice(&self.t0_us.to_le_bytes()); + o.extend_from_slice(&self.tick_us.to_le_bytes()); + put_string(&mut o, self.origin.as_bytes()); + o.extend_from_slice(&self.limits.max_present.to_le_bytes()); + o.extend_from_slice(&self.limits.max_publishers.to_le_bytes()); + o.extend_from_slice(&self.limits.reval_s.to_le_bytes()); + o.extend_from_slice(&self.limits.ceiling.to_bytes()); + assert!(self.roles.len() <= u8::MAX as usize); + o.push(self.roles.len() as u8); + for r in &self.roles { + put_name(&mut o, &r.name); + o.push(r.caps.publish); + o.push(r.caps.subscribe as u8); + o.push(r.caps.max_layer); + o.push(r.caps.powers); + o.extend_from_slice(&r.events); + } + assert!(self.slots.len() <= u8::MAX as usize); + o.push(self.slots.len() as u8); + for s in &self.slots { + put_name(&mut o, &s.name); + o.push(s.media); + o.push(s.redundancy); + o.extend_from_slice(&s.failover_ms.to_le_bytes()); + } + assert!(self.profiles.len() <= u8::MAX as usize); + o.push(self.profiles.len() as u8); + for p in &self.profiles { + p.encode(&mut o); + } + o.extend_from_slice(&self.review.kinds); + o.extend_from_slice(&self.review.deadline_ms.to_le_bytes()); + o.push(self.review.fallback); + o.push(self.recording.mode); + o.extend_from_slice(&self.recording.retention_days.to_le_bytes()); + o.extend_from_slice(&self.recording.commit_interval_ms.to_le_bytes()); + o.extend_from_slice(&self.recording.jitter_ms.to_le_bytes()); + assert!(self.recording.regions.len() <= u8::MAX as usize); + o.push(self.recording.regions.len() as u8); + for r in &self.recording.regions { + o.extend_from_slice(r); + } + o + } + + /// The whole record. + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// The room id (§3.2): SHA-256 over [`Descriptor::body`]. + pub fn room_id(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Sign with `key`, which becomes the authority. + pub fn sign(mut self, key: &SigningKey) -> Descriptor { + self.authority = key.verifying_key().to_bytes(); + let mut m = DESCRIPTOR_DOMAIN.to_vec(); + m.extend_from_slice(&self.body()); + self.sig = key.sign(&m).to_bytes(); + self + } + + fn read_raw(b: &[u8]) -> Result { + read_head(b, &DESCRIPTOR_MAGIC)?; + let mut r = Rd { b, p: 5 }; + let authority = r.d32()?; + let clock = r.d32()?; + let t0_us = r.u64()?; + let tick_us = r.u64()?; + let origin = r.string()?; + let max_present = r.u32()?; + let max_publishers = r.u16()?; + let reval_s = r.u32()?; + let ceiling: [u8; 65] = r.arr()?; + let n = r.u8()? as usize; + let (mut roles, mut names, mut subscribe) = (Vec::with_capacity(n), Vec::with_capacity(n), Vec::with_capacity(n)); + for _ in 0..n { + let name = r.name()?; + let publish = r.u8()?; + let sub = r.u8()?; + let caps = Caps { publish, subscribe: sub == 1, max_layer: r.u8()?, powers: r.u8()? }; + roles.push(Role { name: text(&name), caps, events: r.d32()? }); + names.push(name); + subscribe.push(sub); + } + let n = r.u8()? as usize; + let (mut slots, mut slot_names) = (Vec::with_capacity(n), Vec::with_capacity(n)); + for _ in 0..n { + let name = r.name()?; + slots.push(Slot { name: text(&name), media: r.u8()?, redundancy: r.u8()?, failover_ms: r.u32()? }); + slot_names.push(name); + } + let n = r.u8()? as usize; + let (mut profiles, mut profile_texts) = (Vec::with_capacity(n), Vec::with_capacity(n)); + for _ in 0..n { + let (p, t) = Profile::read(&mut r)?; + profiles.push(p); + profile_texts.push(t); + } + let review = Review { kinds: r.d32()?, deadline_ms: r.u32()?, fallback: r.u8()? }; + let mode = r.u8()?; + let retention_days = r.u16()?; + let commit_interval_ms = r.u32()?; + let jitter_ms = r.u32()?; + let n = r.u8()? as usize; + let mut regions = Vec::with_capacity(n); + for _ in 0..n { + regions.push(r.arr::<2>()?); + } + let body_len = r.p; + let sig: [u8; 64] = r.arr()?; + if r.p != b.len() { + return Err(MALFORMED); + } + let d = Descriptor { + authority, + clock, + t0_us, + tick_us, + origin: text(&origin), + limits: Limits { max_present, max_publishers, reval_s, ceiling: Policy::parse(&ceiling).unwrap_or_default() }, + roles, + slots, + profiles, + review, + recording: Recording { mode, retention_days, commit_interval_ms, jitter_ms, regions }, + sig, + }; + Ok(RawDescriptor { d, body: b[..body_len].to_vec(), names, subscribe, slot_names, profile_texts, origin, ceiling }) + } + + /// §3.4's field rules. + fn check(raw: &RawDescriptor) -> Result<(), Reason> { + let d = &raw.d; + let bad = Err(Reason::DescriptorInvalid); + if d.tick_us == 0 || !(raw.origin.is_empty() || token_ok(&raw.origin, 255)) { + return bad; + } + if d.limits.max_present == 0 || d.limits.max_publishers == 0 { + return bad; + } + let ceiling = match Policy::parse(&raw.ceiling) { + Ok(p) if !permits_lifecycle(&p) => p, + _ => return bad, + }; + if !(1..=16).contains(&d.roles.len()) { + return bad; + } + let mut seen = BTreeSet::new(); + for ((role, name), &sub) in d.roles.iter().zip(&raw.names).zip(&raw.subscribe) { + if !name_ok(name) || !seen.insert(name.clone()) || sub > 1 { + return bad; + } + let c = role.caps; + if !subset(c.publish, 0b111) || !subset(c.powers, 0b1111) || (!c.subscribe && c.max_layer != 0) { + return bad; + } + if !kinds_subset(&role.events, &ceiling.kinds) || !powers_cover(&role.events, c.powers) { + return bad; + } + } + if d.slots.len() > 16 { + return bad; + } + let mut seen = BTreeSet::new(); + for (s, name) in d.slots.iter().zip(&raw.slot_names) { + if !slot_name_ok(name) || !seen.insert(name.clone()) || media_name(s.media).is_none() { + return bad; + } + let ok = match s.redundancy { + 1 => s.failover_ms == 0, + 2 => s.failover_ms > 0, + _ => false, + }; + if !ok { + return bad; + } + } + if d.profiles.len() > 16 { + return bad; + } + let mut seen = BTreeSet::new(); + for (p, (name, codecs, mode)) in d.profiles.iter().zip(&raw.profile_texts) { + if !p.valid(name, codecs, mode) || !seen.insert(name.clone()) { + return bad; + } + if let Some(reg) = registered_profile(&p.name) + && reg != *p + { + return bad; + } + } + let rv = &d.review; + let reviewed = rv.kinds.iter().any(|&b| b != 0); + if reviewed { + if !kinds_subset(&rv.kinds, &ceiling.kinds) || rv.deadline_ms == 0 || !(1..=2).contains(&rv.fallback) { + return bad; + } + } else if rv.deadline_ms != 0 || rv.fallback != 0 { + return bad; + } + let rec = &d.recording; + if rec.mode > 2 || rec.regions.len() > 16 { + return bad; + } + let timing = if rec.mode == 0 { + rec.commit_interval_ms == 0 && rec.jitter_ms == 0 + } else { + rec.commit_interval_ms > 0 && rec.jitter_ms <= rec.commit_interval_ms + }; + if !timing { + return bad; + } + if !rec.regions.iter().all(|r| r.iter().all(u8::is_ascii_uppercase)) || !rec.regions.windows(2).all(|w| w[0] < w[1]) { + return bad; + } + Ok(()) + } + + /// Read and check a descriptor (§3.4), and verify its signature (§3.2): the first + /// refusal of §9.1 step 1. + pub fn parse(b: &[u8]) -> Result { + let raw = Descriptor::read_raw(b)?; + Descriptor::check(&raw)?; + let mut m = DESCRIPTOR_DOMAIN.to_vec(); + m.extend_from_slice(&raw.body); + crate::sig::verify_strict(&raw.d.authority, &m, &raw.d.sig).map_err(sig_reason)?; + debug_assert_eq!(raw.body, raw.d.body(), "a descriptor that passes §3.4 re-encodes to its bytes"); + Ok(raw.d) + } + + /// Whether `key` is one of the room's own keys: its authority or its clock (§3.2). + pub fn is_room_key(&self, key: &[u8; 32]) -> bool { + *key == self.authority || *key == self.clock + } + + fn slot(&self, name: &str, m: u8) -> Option { + self.slots.iter().position(|s| s.name == name && s.media == m) + } +} + +fn sig_reason(e: crate::sig::SigError) -> Reason { + match e { + crate::sig::SigError::BadKey => Reason::Events(events::Reason::BadKey), + crate::sig::SigError::BadSignature => Reason::Events(events::Reason::BadSignature), + } +} + +/// The powers a set of event kinds needs (§3.3): `decision` needs moderate, `control` +/// direct or record. +fn powers_cover(kinds: &[u8; 32], powers: u8) -> bool { + let has = |k: u8| kinds[(k / 8) as usize] & (1 << (k % 8)) != 0; + (!has(kind::DECISION) || powers & power::MODERATE != 0) && (!has(kind::CONTROL) || powers & (power::DIRECT | power::RECORD) != 0) +} + +// --------------------------------------------------------------------------------------- +// §8 Publish profiles +// --------------------------------------------------------------------------------------- + +fn audio_layer(min_kbps: u32, max_kbps: u32) -> Layer { + Layer { width: 0, height: 0, fps: 0, min_kbps, max_kbps } +} + +fn video_layer(width: u16, height: u16, fps: u16, min_kbps: u32, max_kbps: u32) -> Layer { + Layer { width, height, fps, min_kbps, max_kbps } +} + +/// The registered profiles (§8.2), in the order the table lists them. +pub fn registered_profiles() -> Vec { + let p = |name: &str, m: u8, codecs: &[&str], lay: u8, mode: &str, layers: Vec, sr: u32, ch: u8, proc: u8| Profile { + name: name.into(), + media: m, + codecs: codecs.iter().map(|c| c.to_string()).collect(), + layering: lay, + mode: mode.into(), + layers, + sample_rate: sr, + channels: ch, + processing: proc, + }; + use processing::*; + vec![ + p("speech", media::AUDIO, &["opus"], layering::SINGLE, "", vec![audio_layer(16, 64)], 48_000, 1, ECHO_CANCELLATION | NOISE_SUPPRESSION | GAIN_CONTROL | DTX), + p("music", media::AUDIO, &["opus"], layering::SINGLE, "", vec![audio_layer(128, 510)], 48_000, 2, 0), + p("screen", media::SCREEN, &["av01.0.08M.08", "avc1.640028"], layering::SVC, "L1T3", vec![video_layer(1920, 1080, 15, 300, 2500)], 0, 0, 0), + p( + "camera-720", + media::VIDEO, + &["av01.0.05M.08", "avc1.64001F"], + layering::SIMULCAST, + "", + vec![video_layer(640, 360, 30, 150, 500), video_layer(1280, 720, 30, 500, 1500)], + 0, + 0, + 0, + ), + p( + "camera-1080", + media::VIDEO, + &["av01.0.08M.08", "avc1.640028"], + layering::SIMULCAST, + "", + vec![video_layer(640, 360, 30, 150, 500), video_layer(1280, 720, 30, 500, 1500), video_layer(1920, 1080, 30, 1500, 4000)], + 0, + 0, + 0, + ), + ] +} + +/// The registered profile of this name, if there is one. +pub fn registered_profile(name: &str) -> Option { + registered_profiles().into_iter().find(|p| p.name == name) +} + +// --------------------------------------------------------------------------------------- +// §4 The room grant +// --------------------------------------------------------------------------------------- + +/// A room grant (§4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Grant { + pub room: [u8; 32], + pub principal: [u8; 32], + /// The digest of the grant this one is exchanged for; zero for a first grant. + pub prev: [u8; 32], + /// Room-clock µs an exchanged grant takes effect at; 0 for a first grant. + pub effective: u64, + /// Seconds since 1970, as a CWT NumericDate. + pub nbf: u64, + pub exp: u64, + /// The index of its role in the descriptor. + pub role: u8, + pub caps: Caps, + pub precedence: u8, + /// A single-use nonce; zero when the grant may be used again in its window. + pub once: [u8; 16], + /// The viewer id revocation names; zero for none. + pub viewer: [u8; 16], + /// The event policy of live-events §5. + pub policy: Policy, + pub joules_ceiling: u64, + pub funds_ceiling: u64, + /// ISO 4217, three capitals; zero bytes when there is no funds ceiling. + pub currency: [u8; 3], + /// Indices of the descriptor's profiles it publishes with, one per media kind at most. + pub profiles: Vec, + pub origins: Vec, + /// Composition attributes (§4.4), keys ascending. + pub attrs: Vec<(String, String)>, + pub sig: [u8; 64], +} + +/// The bytes of a grant's attributes (§4.4). +pub fn attrs_bytes(attrs: &[(String, String)]) -> Vec { + let mut o = Vec::new(); + for (k, v) in attrs { + put_name(&mut o, k); + put_string(&mut o, v.as_bytes()); + } + o +} + +/// Read attributes (§4.4); `None` when they break a rule. +pub fn read_attrs(b: &[u8]) -> Option> { + if b.len() > MAX_ATTRS { + return None; + } + let mut r = Rd { b, p: 0 }; + let mut out: Vec<(String, String)> = Vec::new(); + let mut last: Option> = None; + while r.p < b.len() { + let k = r.name().ok()?; + let v = r.string().ok()?; + if !slot_name_ok(&k) || last.as_ref().is_some_and(|l| *l >= k) { + return None; + } + let v = String::from_utf8(v).ok()?; + out.push((text(&k), v)); + last = Some(k); + } + Some(out) +} + +/// The grant as read (§4.3), before its field rules. +struct RawGrant { + g: Grant, + subscribe: u8, + policy: [u8; 65], + origins: Vec>, + attrs: Vec, +} + +impl Grant { + /// The grant without `sig` (§4.1). + pub fn body(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&GRANT_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.room); + o.extend_from_slice(&self.principal); + o.extend_from_slice(&self.prev); + o.extend_from_slice(&self.effective.to_le_bytes()); + o.extend_from_slice(&self.nbf.to_le_bytes()); + o.extend_from_slice(&self.exp.to_le_bytes()); + o.push(self.role); + o.push(self.caps.publish); + o.push(self.caps.subscribe as u8); + o.push(self.caps.max_layer); + o.push(self.caps.powers); + o.push(self.precedence); + o.extend_from_slice(&self.once); + o.extend_from_slice(&self.viewer); + o.extend_from_slice(&self.policy.to_bytes()); + o.extend_from_slice(&self.joules_ceiling.to_le_bytes()); + o.extend_from_slice(&self.funds_ceiling.to_le_bytes()); + o.extend_from_slice(&self.currency); + assert!(self.profiles.len() <= u8::MAX as usize); + o.push(self.profiles.len() as u8); + o.extend_from_slice(&self.profiles); + assert!(self.origins.len() <= u8::MAX as usize); + o.push(self.origins.len() as u8); + for s in &self.origins { + put_name(&mut o, s); + } + put_string(&mut o, &attrs_bytes(&self.attrs)); + o + } + + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// The grant's digest (§4.2): SHA-256 over [`Grant::body`]. + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Sign under the room authority's key. + pub fn sign(mut self, authority: &SigningKey) -> Grant { + let mut m = GRANT_DOMAIN.to_vec(); + m.extend_from_slice(&self.body()); + self.sig = authority.sign(&m).to_bytes(); + self + } + + fn read_raw(b: &[u8]) -> Result { + read_head(b, &GRANT_MAGIC)?; + let mut r = Rd { b, p: 5 }; + let room = r.d32()?; + let principal = r.d32()?; + let prev = r.d32()?; + let effective = r.u64()?; + let nbf = r.u64()?; + let exp = r.u64()?; + let role = r.u8()?; + let publish = r.u8()?; + let subscribe = r.u8()?; + let max_layer = r.u8()?; + let powers = r.u8()?; + let precedence = r.u8()?; + let once = r.arr::<16>()?; + let viewer = r.arr::<16>()?; + let policy: [u8; 65] = r.arr()?; + let joules_ceiling = r.u64()?; + let funds_ceiling = r.u64()?; + let currency = r.arr::<3>()?; + let n = r.u8()? as usize; + let profiles = r.take(n)?.to_vec(); + let n = r.u8()? as usize; + let mut origins = Vec::with_capacity(n); + for _ in 0..n { + origins.push(r.name()?); + } + let attrs = r.string()?; + let sig: [u8; 64] = r.arr()?; + if r.p != b.len() { + return Err(MALFORMED); + } + let g = Grant { + room, + principal, + prev, + effective, + nbf, + exp, + role, + caps: Caps { publish, subscribe: subscribe == 1, max_layer, powers }, + precedence, + once, + viewer, + policy: Policy::parse(&policy).unwrap_or_default(), + joules_ceiling, + funds_ceiling, + currency, + profiles, + origins: origins.iter().map(|o| text(o)).collect(), + attrs: read_attrs(&attrs).unwrap_or_default(), + sig, + }; + Ok(RawGrant { g, subscribe, policy, origins, attrs }) + } + + /// §4.3's field rules, against the room's descriptor. + fn check(raw: &RawGrant, d: &Descriptor) -> Result<(), Reason> { + let g = &raw.g; + let bad = Err(Reason::GrantInvalid); + if g.exp <= g.nbf { + return bad; + } + if g.prev == [0; 32] { + if g.effective != 0 { + return bad; + } + } else if !g.effective.is_multiple_of(d.tick_us) { + return bad; + } + if g.role as usize >= d.roles.len() || raw.subscribe > 1 { + return bad; + } + let c = g.caps; + if !subset(c.publish, 0b111) || !subset(c.powers, 0b1111) || (!c.subscribe && c.max_layer != 0) { + return bad; + } + let policy = match Policy::parse(&raw.policy) { + Ok(p) if !permits_lifecycle(&p) => p, + _ => return bad, + }; + if !powers_cover(&policy.kinds, c.powers) { + return bad; + } + let funded = g.funds_ceiling != NO_CEILING; + if funded != (g.currency != [0; 3]) || (funded && !g.currency.iter().all(u8::is_ascii_uppercase)) { + return bad; + } + let mut kinds = BTreeSet::new(); + for &i in &g.profiles { + match d.profiles.get(i as usize) { + Some(p) if kinds.insert(p.media) && c.publishes(p.media) => {} + _ => return bad, + } + } + if raw.origins.len() > 8 || !raw.origins.iter().all(|o| token_ok(o, 255)) { + return bad; + } + if read_attrs(&raw.attrs).is_none() { + return bad; + } + Ok(()) + } + + /// The bound a role and the room's ceiling put on the grant (§4.3 steps 6–8). + fn bounded(&self, d: &Descriptor) -> Result<(), Reason> { + if self.exp - self.nbf > MAX_GRANT_S { + return Err(Reason::GrantTooLong); + } + let role = &d.roles[self.role as usize]; + let (c, rc) = (self.caps, role.caps); + if !subset(c.publish, rc.publish) + || (c.subscribe && !rc.subscribe) + || c.max_layer > rc.max_layer + || !subset(c.powers, rc.powers) + || !kinds_subset(&self.policy.kinds, &role.events) + { + return Err(Reason::CapsExceedRole); + } + let (p, ceil) = (&self.policy, &d.limits.ceiling); + if p.max_payload > ceil.max_payload + || p.max_text_cp > ceil.max_text_cp + || p.max_events > ceil.max_events + || p.window_us < ceil.window_us + || p.max_reactions > ceil.max_reactions + || p.reaction_window_us < ceil.reaction_window_us + { + return Err(Reason::GrantExceedsRoom); + } + Ok(()) + } + + /// The revocation tag of the grant's viewer (§5), when it names one. + pub fn viewer_tag(&self) -> Option<[u8; 32]> { + (self.viewer != [0; 16]).then(|| sha256(&[VIEWER_DOMAIN, &self.viewer])) + } + + /// Whether room-clock `t` falls in the grant's window (§4.3): `nbf` ≤ ⌊(t0 + t) / 10^6⌋ + /// < `exp`. + pub fn covers(&self, t0_us: u64, t: u64) -> bool { + let now = t0_us as u128 + t as u128; + self.nbf as u128 * 1_000_000 <= now && now < self.exp as u128 * 1_000_000 + } + + /// The fields a receipt's grant reference carries for this grant (§4.5): the digest, + /// [`CAPABILITY`], the joule ceiling in µJ (`u64::MAX` for none) and the funds ceiling + /// in minor units of `currency` (`None` for none). + pub fn grant_ref(&self) -> ([u8; 32], &'static str, u64, Option) { + (self.digest(), CAPABILITY, self.joules_ceiling, (self.funds_ceiling != NO_CEILING).then_some(self.funds_ceiling)) + } +} + +/// Read a grant of the room `d` fixes (§4.3 steps 1–2): the record, and its signature +/// under the room's authority. Its digest is over the bytes as given. +fn read_grant(b: &[u8], d: &Descriptor) -> Result<(RawGrant, [u8; 32]), Reason> { + let raw = Grant::read_raw(b)?; + let body = &b[..b.len() - 64]; + let mut m = GRANT_DOMAIN.to_vec(); + m.extend_from_slice(body); + crate::sig::verify_strict(&d.authority, &m, &raw.g.sig).map_err(sig_reason)?; + Ok((raw, sha256(&[body]))) +} + +/// A grant a room verifier holds, with its digest. +#[derive(Clone, Debug)] +pub struct HeldGrant { + pub grant: Grant, + pub digest: [u8; 32], +} + +/// §4.3 over every grant, in the order given: the first refusal and the grant's index, or +/// the grants by digest. +pub fn check_grants(d: &Descriptor, room: &[u8; 32], grants: &[Vec]) -> Result, (usize, Reason)> { + let mut held: Vec = Vec::new(); + for (i, b) in grants.iter().enumerate() { + let (raw, digest) = read_grant(b, d).map_err(|r| (i, r))?; + let g = raw.g.clone(); + if g.prev != [0; 32] { + let old = held.iter().find(|h| h.digest == g.prev).ok_or((i, Reason::ExchangeUnlinked))?; + if old.grant.room != g.room || old.grant.principal != g.principal { + return Err((i, Reason::ExchangeMismatch)); + } + } + if g.room != *room { + return Err((i, Reason::Events(events::Reason::WrongRoom))); + } + Grant::check(&raw, d).map_err(|r| (i, r))?; + debug_assert_eq!(digest, g.digest(), "a grant that passes §4.3 re-encodes to its bytes"); + if held.iter().any(|h| h.digest == digest) { + return Err((i, Reason::GrantInvalid)); + } + g.bounded(d).map_err(|r| (i, r))?; + held.push(HeldGrant { grant: g, digest }); + } + Ok(held) +} + +// --------------------------------------------------------------------------------------- +// §5 Revocation through the key log +// --------------------------------------------------------------------------------------- + +/// What a room verifier takes from the authority's key log (§5): the digests its head +/// revokes. +#[derive(Clone, Debug, Default)] +pub struct KeyLogState { + pub revoked: BTreeSet<[u8; 32]>, +} + +/// §9.1 step 2: the head the caller reached for the descriptor's origin (jwp-receipts +/// §7.4 step 3), held for it, listing the authority with `live/room`, not revoked. +pub fn check_key_log(d: &Descriptor, head: Option<&str>) -> Result { + if d.origin.is_empty() { + return Ok(KeyLogState::default()); + } + let text = head.ok_or(Reason::KeyLogMissing)?; + let rev = Revision::from_json(text).map_err(|_| Reason::KeyLogNotHeld)?; + rev.check_held(&d.origin).map_err(|_| Reason::KeyLogNotHeld)?; + let entry = rev + .keys + .iter() + .find(|e| e.key == d.authority && e.may_sign.iter().any(|a| a == KEY_LOG_AUTHORITY)) + .ok_or(Reason::AuthorityNotListed)?; + if entry.status == EntryStatus::Revoked { + return Err(Reason::AuthorityRevoked); + } + Ok(KeyLogState { revoked: rev.revoked_modules.iter().copied().collect() }) +} + +impl KeyLogState { + /// Whether the head revokes the grant or its viewer (§5). + pub fn revokes(&self, h: &HeldGrant) -> bool { + self.revoked.contains(&h.digest) || h.grant.viewer_tag().is_some_and(|t| self.revoked.contains(&t)) + } +} + +// --------------------------------------------------------------------------------------- +// §6 Track naming +// --------------------------------------------------------------------------------------- + +/// Who a track's namespace names (§6.1): a principal, or a slot. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Owner { + Principal([u8; 32]), + Slot(String), +} + +impl Owner { + fn field(&self) -> String { + match self { + Owner::Principal(k) => hex(k), + Owner::Slot(s) => format!("_{s}"), + } + } +} + +/// The Track Namespace of a track (§6.1): the room, the owner, the media kind's name (or +/// `events`), each one field. +pub fn track_namespace(room: &[u8; 32], owner: &Owner, media: &str) -> Vec { + vec![hex(room), owner.field(), media.to_string()] +} + +/// A track's name (§6.1): its layer, in decimal. +pub fn track_name(layer: u8) -> String { + layer.to_string() +} + +/// One field as `draft-ietf-moq-transport-22` §8.8 renders it: `a`–`z`, `A`–`Z`, `0`–`9` +/// and `_` as themselves, every other byte as `.` and two lowercase hexadecimal digits. +fn render_field(f: &[u8]) -> String { + let mut s = String::new(); + for &b in f { + if b.is_ascii_alphanumeric() || b == b'_' { + s.push(b as char); + } else { + s.push_str(&format!(".{b:02x}")); + } + } + s +} + +/// A namespace as `draft-ietf-moq-transport-22` §8.8 renders it, fields joined by `-`: +/// the `namespace` of the track's MSF catalog entry (§6.2), and what an anchor's `track` +/// digest takes (live-events §3.1). +pub fn render_namespace(ns: &[String]) -> String { + ns.iter().map(|f| render_field(f.as_bytes())).collect::>().join("-") +} + +/// A Full Track Name as §8.8 renders it: the namespace, `--`, the name. +pub fn render_full(ns: &[String], name: &str) -> String { + format!("{}--{}", render_namespace(ns), render_field(name.as_bytes())) +} + +// --------------------------------------------------------------------------------------- +// §7 Lifecycle detail +// --------------------------------------------------------------------------------------- + +/// A lifecycle event's `detail`, read (§7.2). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Detail { + Join { grant: [u8; 32] }, + Leave { reason: u8 }, + /// `slot` empty: the subject's own track. + Publish { slot: String, media: u8, profile: u8, layers: u8 }, + Unpublish { slot: String, media: u8 }, + GrantExchange { old: [u8; 32], new: [u8; 32] }, + Takeover { slot: String, media: u8, profile: u8, layers: u8, previous: [u8; 32] }, + Failover { slot: String, media: u8, failed: [u8; 32], last_seen: u64 }, +} + +/// `leave` reasons (§7.2). +pub mod leave { + pub const LEFT: u8 = 1; + pub const REMOVED: u8 = 2; + pub const GRANT_ENDED: u8 = 3; + pub const CONNECTION_LOST: u8 = 4; +} + +impl Detail { + /// The lifecycle kind it is the detail of. + pub fn kind(&self) -> u8 { + match self { + Detail::Join { .. } => kind::JOIN, + Detail::Leave { .. } => kind::LEAVE, + Detail::Publish { .. } => kind::PUBLISH, + Detail::Unpublish { .. } => kind::UNPUBLISH, + Detail::GrantExchange { .. } => kind::GRANT_EXCHANGE, + Detail::Takeover { .. } => kind::TAKEOVER, + Detail::Failover { .. } => kind::FAILOVER, + } + } + + /// The detail's bytes (§7.2). + pub fn encode(&self) -> Vec { + let mut o = Vec::new(); + match self { + Detail::Join { grant } => o.extend_from_slice(grant), + Detail::Leave { reason } => o.push(*reason), + Detail::Publish { slot, media, profile, layers } => { + put_name(&mut o, slot); + o.extend_from_slice(&[*media, *profile, *layers]); + } + Detail::Unpublish { slot, media } => { + put_name(&mut o, slot); + o.push(*media); + } + Detail::GrantExchange { old, new } => { + o.extend_from_slice(old); + o.extend_from_slice(new); + } + Detail::Takeover { slot, media, profile, layers, previous } => { + put_name(&mut o, slot); + o.extend_from_slice(&[*media, *profile, *layers]); + o.extend_from_slice(previous); + } + Detail::Failover { slot, media, failed, last_seen } => { + put_name(&mut o, slot); + o.push(*media); + o.extend_from_slice(failed); + o.extend_from_slice(&last_seen.to_le_bytes()); + } + } + o + } + + /// Read the `detail` of a lifecycle event of `kind` (§7.2): `lifecycle_malformed` when + /// it does not read or breaks a rule. + pub fn parse(k: u8, b: &[u8]) -> Result { + let m = Reason::LifecycleMalformed; + let mut r = Rd { b, p: 0 }; + let slot = |r: &mut Rd, required: bool| -> Result { + let s = r.name().map_err(|_| m)?; + if (s.is_empty() && required) || (!s.is_empty() && !slot_name_ok(&s)) { + return Err(m); + } + Ok(text(&s)) + }; + let media_of = |r: &mut Rd| -> Result { + let x = r.u8().map_err(|_| m)?; + media_name(x).map(|_| x).ok_or(m) + }; + let d = match k { + kind::JOIN => Detail::Join { grant: r.d32().map_err(|_| m)? }, + kind::LEAVE => { + let reason = r.u8().map_err(|_| m)?; + if !(1..=4).contains(&reason) { + return Err(m); + } + Detail::Leave { reason } + } + kind::PUBLISH => { + let slot = slot(&mut r, false)?; + let media = media_of(&mut r)?; + let profile = r.u8().map_err(|_| m)?; + let layers = r.u8().map_err(|_| m)?; + if layers == 0 { + return Err(m); + } + Detail::Publish { slot, media, profile, layers } + } + kind::UNPUBLISH => { + let slot = slot(&mut r, false)?; + Detail::Unpublish { slot, media: media_of(&mut r)? } + } + kind::GRANT_EXCHANGE => Detail::GrantExchange { old: r.d32().map_err(|_| m)?, new: r.d32().map_err(|_| m)? }, + kind::TAKEOVER => { + let slot = slot(&mut r, true)?; + let media = media_of(&mut r)?; + let profile = r.u8().map_err(|_| m)?; + let layers = r.u8().map_err(|_| m)?; + if layers == 0 { + return Err(m); + } + Detail::Takeover { slot, media, profile, layers, previous: r.d32().map_err(|_| m)? } + } + kind::FAILOVER => { + let slot = slot(&mut r, true)?; + let media = media_of(&mut r)?; + Detail::Failover { slot, media, failed: r.d32().map_err(|_| m)?, last_seen: r.u64().map_err(|_| m)? } + } + _ => return Err(m), + }; + if r.p != b.len() { + return Err(m); + } + Ok(d) + } +} + +// --------------------------------------------------------------------------------------- +// §9 Room verification +// --------------------------------------------------------------------------------------- + +/// Where a room verification stopped (§9.4). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum At { + Descriptor, + KeyLog, + Grant(usize), + /// A record: its chain's index among the chains given, and its index in that chain. + Record { chain: usize, record: usize }, +} + +/// A track a publisher holds (§9.3). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Held { + pub principal: [u8; 32], + pub profile: u8, + pub layers: u8, +} + +/// One slot's state (§9.3). +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub struct SlotState { + pub live: Option, + pub standby: Option, +} + +/// The room state the lifecycle replays to (§9.3). +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct RoomState { + /// Each present principal and the digest of the grant in effect for it. + pub present: BTreeMap<[u8; 32], [u8; 32]>, + /// The principals' own tracks, by (principal, media). + pub own: BTreeMap<([u8; 32], u8), Held>, + /// By the descriptor's slot order. + pub slots: Vec, + /// Each change of a principal's grant, in the order it took effect: (principal, + /// grant digest, room-clock t). + pub timeline: Vec<([u8; 32], [u8; 32], u64)>, + used_once: BTreeSet<[u8; 16]>, +} + +impl RoomState { + /// The principals that publish (§7.3): an own track, or live or standby in a slot. + pub fn publishers(&self) -> BTreeSet<[u8; 32]> { + let mut s: BTreeSet<[u8; 32]> = self.own.keys().map(|(p, _)| *p).collect(); + for st in &self.slots { + s.extend(st.live.iter().chain(st.standby.iter()).map(|h| h.principal)); + } + s + } + +} + +/// The outcome of a room verification (§9.4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum RoomOutcome { + Accept, + Gap(Vec), + Refuse { at: At, reason: Reason }, +} + +/// What a room verification holds at its end, for the corpus. +#[derive(Clone, Debug)] +pub struct RoomRun { + pub outcome: RoomOutcome, + pub room: Option<[u8; 32]>, + pub state: RoomState, + /// The records in the merged order (§9.2): (chain, record, the grant they were + /// verified under, or `None` for a room key's). + pub order: Vec<(usize, usize, Option<[u8; 32]>)>, + pub tally: Option, + pub grants: Vec, + pub descriptor: Option, +} + +/// The key a record sorts by in the merged order (§9.2): its `t`, 0 for a room key and 1 +/// for any other, and its chain's index. A record that does not read sorts first. +fn merge_key(b: &[u8], d: &Descriptor, chain: usize) -> (u64, u8, usize) { + match Event::parse(b) { + Ok(e) => (e.t, if d.is_room_key(&e.principal) { 0 } else { 1 }, chain), + Err(_) => (0, 0, chain), + } +} + +/// The merged order (§9.2): repeatedly the chain whose next record has the least key. +/// Each chain's own order is kept. +pub fn merged_order(d: &Descriptor, chains: &[Vec>]) -> Vec<(usize, usize)> { + let mut next = vec![0usize; chains.len()]; + let mut out = Vec::new(); + loop { + let pick = (0..chains.len()) + .filter(|&c| next[c] < chains[c].len()) + .min_by_key(|&c| merge_key(&chains[c][next[c]], d, c)); + match pick { + Some(c) => { + out.push((c, next[c])); + next[c] += 1; + } + None => return out, + } + } +} + +struct Replay<'a> { + d: &'a Descriptor, + grants: &'a [HeldGrant], + log: &'a KeyLogState, + state: RoomState, +} + +impl Replay<'_> { + fn grant(&self, digest: &[u8; 32]) -> Option<&HeldGrant> { + self.grants.iter().find(|h| h.digest == *digest) + } + + fn current(&self, p: &[u8; 32]) -> Option<&HeldGrant> { + self.state.present.get(p).and_then(|g| self.grant(g)) + } + + /// The profile checks of a publish or a takeover (§7.2): the grant may publish the + /// media, and gives the profile for it with at least `layers` layers. + fn may_publish(&self, g: &Grant, m: u8, profile: u8, layers: u8) -> Result<(), Reason> { + if !g.caps.publishes(m) { + return Err(Reason::PublishNotPermitted); + } + match self.d.profiles.get(profile as usize) { + Some(p) if g.profiles.contains(&profile) && p.media == m && layers as usize <= p.layers.len() => Ok(()), + _ => Err(Reason::ProfileNotGranted), + } + } + + /// What `p` publishes, as (media, profile): its own tracks by media, then its places + /// in slots, in the descriptor's order. + fn publishing(&self, p: &[u8; 32]) -> Vec<(u8, u8)> { + let mut out: Vec<(u8, u8)> = self.state.own.iter().filter(|((q, _), _)| q == p).map(|((_, m), h)| (*m, h.profile)).collect(); + for (i, st) in self.state.slots.iter().enumerate() { + for h in st.live.iter().chain(st.standby.iter()).filter(|h| h.principal == *p) { + out.push((self.d.slots[i].media, h.profile)); + } + } + out + } + + fn publisher_limit(&self) -> Result<(), Reason> { + if self.state.publishers().len() > self.d.limits.max_publishers as usize { + return Err(Reason::PublisherLimit); + } + Ok(()) + } + + fn drop_from_slots(&mut self, p: &[u8; 32]) { + for s in &mut self.state.slots { + if s.standby.is_some_and(|h| h.principal == *p) { + s.standby = None; + } + if s.live.is_some_and(|h| h.principal == *p) { + s.live = s.standby.take(); + } + } + } + + /// §7.2: apply one lifecycle event of a room key at `t`. + fn apply(&mut self, subject: [u8; 32], detail: Detail, t: u64) -> Result<(), Reason> { + let present = |s: &Self| -> Result { s.current(&subject).cloned().ok_or(Reason::NotPresent) }; + match detail { + Detail::Join { grant } => { + let h = self.grant(&grant).cloned().ok_or(Reason::GrantUnknown)?; + if h.grant.principal != subject { + return Err(Reason::GrantWrongPrincipal); + } + if self.state.present.contains_key(&subject) { + return Err(Reason::AlreadyPresent); + } + if self.log.revokes(&h) { + return Err(Reason::GrantRevoked); + } + if h.grant.once != [0; 16] && self.state.used_once.contains(&h.grant.once) { + return Err(Reason::GrantReused); + } + if !h.grant.covers(self.d.t0_us, t) { + return Err(Reason::OutsideGrantWindow); + } + if self.state.present.len() + 1 > self.d.limits.max_present as usize { + return Err(Reason::ParticipantLimit); + } + if h.grant.once != [0; 16] { + self.state.used_once.insert(h.grant.once); + } + self.state.present.insert(subject, h.digest); + self.state.timeline.push((subject, h.digest, t)); + } + Detail::Leave { .. } => { + present(self)?; + self.state.present.remove(&subject); + self.state.own.retain(|(p, _), _| *p != subject); + self.drop_from_slots(&subject); + } + Detail::Publish { slot, media: m, profile, layers } => { + let h = present(self)?; + let si = if slot.is_empty() { None } else { Some(self.d.slot(&slot, m).ok_or(Reason::SlotUnknown)?) }; + self.may_publish(&h.grant, m, profile, layers)?; + let held = Held { principal: subject, profile, layers }; + match si { + None => { + if self.state.own.contains_key(&(subject, m)) { + return Err(Reason::AlreadyPublished); + } + self.state.own.insert((subject, m), held); + } + Some(i) => { + let st = self.state.slots[i]; + if st.live.iter().chain(st.standby.iter()).any(|x| x.principal == subject) { + return Err(Reason::AlreadyPublished); + } + if st.live.is_some() && (self.d.slots[i].redundancy < 2 || st.standby.is_some()) { + return Err(Reason::SlotFull); + } + let s = &mut self.state.slots[i]; + if s.live.is_none() { + s.live = Some(held); + } else { + s.standby = Some(held); + } + } + } + self.publisher_limit()?; + } + Detail::Unpublish { slot, media: m } => { + present(self)?; + if slot.is_empty() { + self.state.own.remove(&(subject, m)).ok_or(Reason::NotPublished)?; + } else { + let i = self.d.slot(&slot, m).ok_or(Reason::SlotUnknown)?; + let st = self.state.slots[i]; + if !st.live.iter().chain(st.standby.iter()).any(|x| x.principal == subject) { + return Err(Reason::NotPublished); + } + let s = &mut self.state.slots[i]; + if s.standby.is_some_and(|x| x.principal == subject) { + s.standby = None; + } else { + s.live = s.standby.take(); + } + } + } + Detail::GrantExchange { old, new } => { + let cur = present(self)?; + if cur.digest != old { + return Err(Reason::ExchangeNotCurrent); + } + let h = self.grant(&new).cloned().ok_or(Reason::GrantUnknown)?; + if h.grant.prev != old { + return Err(Reason::ExchangeUnlinked); + } + if t != h.grant.effective { + return Err(Reason::ExchangeOffTick); + } + if self.log.revokes(&h) { + return Err(Reason::GrantRevoked); + } + if !h.grant.covers(self.d.t0_us, t) { + return Err(Reason::OutsideGrantWindow); + } + for (m, profile) in self.publishing(&subject) { + if !h.grant.caps.publishes(m) { + return Err(Reason::PublishNotPermitted); + } + if !h.grant.profiles.contains(&profile) { + return Err(Reason::ProfileNotGranted); + } + } + self.state.present.insert(subject, h.digest); + self.state.timeline.push((subject, h.digest, t)); + } + Detail::Takeover { slot, media: m, profile, layers, previous } => { + let h = present(self)?; + let i = self.d.slot(&slot, m).ok_or(Reason::SlotUnknown)?; + let st = self.state.slots[i]; + let live = st.live.filter(|x| x.principal == previous).ok_or(Reason::NotPublished)?; + self.may_publish(&h.grant, m, profile, layers)?; + let theirs = self.current(&live.principal).map_or(0, |g| g.grant.precedence); + if subject == previous || h.grant.precedence <= theirs { + return Err(Reason::TakeoverNotHigher); + } + let s = &mut self.state.slots[i]; + if s.standby.is_some_and(|x| x.principal == subject) { + s.standby = None; + } + s.live = Some(Held { principal: subject, profile, layers }); + self.publisher_limit()?; + } + Detail::Failover { slot, media: m, failed, last_seen } => { + present(self)?; + let i = self.d.slot(&slot, m).ok_or(Reason::SlotUnknown)?; + let st = self.state.slots[i]; + if st.live.is_none_or(|x| x.principal != failed) { + return Err(Reason::NotPublished); + } + if st.standby.is_none_or(|x| x.principal != subject) { + return Err(Reason::FailoverNotStandby); + } + let wait = self.d.slots[i].failover_ms as u64 * 1000; + if last_seen > t || t - last_seen < wait { + return Err(Reason::FailoverEarly); + } + let s = &mut self.state.slots[i]; + s.live = s.standby.take(); + } + } + Ok(()) + } +} + +/// Verify a room (§9): its descriptor, its grants, the head of its authority's key log, +/// and its principals' chains. Each chain is one principal's records, in its stream order. +pub fn verify_room(descriptor: &[u8], grants: &[Vec], head: Option<&str>, chains: &[Vec>]) -> RoomRun { + let mut run = RoomRun { + outcome: RoomOutcome::Accept, + room: None, + state: RoomState::default(), + order: Vec::new(), + tally: None, + grants: Vec::new(), + descriptor: None, + }; + let refuse = |run: &mut RoomRun, at: At, reason: Reason| run.outcome = RoomOutcome::Refuse { at, reason }; + // Step 1: the descriptor. + let d = match Descriptor::parse(descriptor) { + Ok(d) => d, + Err(r) => { + refuse(&mut run, At::Descriptor, r); + return run; + } + }; + let room = d.room_id(); + run.room = Some(room); + run.descriptor = Some(d.clone()); + // Step 2: the key log. + let log = match check_key_log(&d, head) { + Ok(l) => l, + Err(r) => { + refuse(&mut run, At::KeyLog, r); + return run; + } + }; + // Step 3: the grants. + let held = match check_grants(&d, &room, grants) { + Ok(h) => h, + Err((i, r)) => { + refuse(&mut run, At::Grant(i), r); + return run; + } + }; + run.grants = held.clone(); + // Step 4: the records, in the merged order. + let order = merged_order(&d, chains); + let mut replay = Replay { d: &d, grants: &held, log: &log, state: RoomState { slots: vec![SlotState::default(); d.slots.len()], ..Default::default() } }; + let mut verifier = RoomVerifier::new(room, Policy::authority()); + let mut seen = Seen::new(); + let mut at_index: Vec<(usize, usize)> = Vec::new(); + for &(c, i) in &order { + let b = &chains[c][i]; + let at = At::Record { chain: c, record: i }; + at_index.push((c, i)); + match step(&mut replay, &mut verifier, &mut seen, b) { + Ok(under) => run.order.push((c, i, under)), + Err(r) => { + refuse(&mut run, at, r); + run.state = replay.state; + return run; + } + } + } + run.state = replay.state; + // Step 5: the outcome. + if !verifier.gaps().is_empty() { + run.outcome = RoomOutcome::Gap(verifier.gaps().to_vec()); + return run; + } + if let Some(index) = events::check_tallies(verifier.accepted()) { + let (chain, record) = at_index[index]; + refuse(&mut run, At::Record { chain, record }, Reason::Events(events::Reason::TallyMismatch)); + return run; + } + run.tally = Some(verifier.tally()); + run +} + +/// What a room verifier keeps of each record it accepted (§9.2): the policy it was +/// verified under and the grant in effect, so that a repeat of it is offered as it was. +type Seen = BTreeMap<[u8; 32], (Policy, Option<[u8; 32]>)>; + +/// §9.2's steps over one record: the grant it was verified under (`None` for a room key's). +fn step(replay: &mut Replay, verifier: &mut RoomVerifier, seen: &mut Seen, b: &[u8]) -> Result, Reason> { + let d = replay.d; + // a. live-events §6.1 steps 1 to 4. + let ev = Event::parse(b)?; + if events::kind_name(ev.kind).is_none() { + return Err(events::Reason::UnknownKind.into()); + } + if ev.room != d.room_id() { + return Err(events::Reason::WrongRoom.into()); + } + ev.verify_signature()?; + // b. A record already accepted is a duplicate (live-events §6.2 step 1): offered under + // the policy it was accepted under, it changes nothing. + let digest = ev.digest(); + if let Some((policy, under)) = seen.get(&digest).copied() { + verifier.set_policy(ev.principal, policy); + verifier.offer(b)?; + return Ok(under); + } + if d.is_room_key(&ev.principal) { + // c. A room key's record, held to the authority's policy; then its lifecycle. + let policy = Policy::authority(); + verifier.set_policy(ev.principal, policy); + verifier.offer(b)?; + seen.insert(digest, (policy, None)); + if let Some(Payload::Lifecycle { kind: k, subject, detail }) = verifier.accepted().last().map(|a| a.payload.clone()) { + let detail = Detail::parse(k, &detail)?; + replay.apply(subject, detail, ev.t)?; + } + return Ok(None); + } + // d. Any other principal's: present, in its grant's window, under its grant's policy. + let h = replay.current(&ev.principal).cloned().ok_or(Reason::NotPresent)?; + if !h.grant.covers(d.t0_us, ev.t) { + return Err(Reason::OutsideGrantWindow); + } + verifier.set_policy(ev.principal, h.grant.policy); + verifier.offer(b)?; + seen.insert(digest, (h.grant.policy, Some(h.digest))); + // e. A control command needs the power it exercises (§3.3). + if let Some(Payload::Control { command, .. }) = verifier.accepted().last().map(|a| &a.payload) { + let need = match command { + Command::RecordStart { .. } | Command::RecordStop => power::RECORD, + _ => power::DIRECT, + }; + if h.grant.caps.powers & need == 0 { + return Err(Reason::PowerNotGranted); + } + } + Ok(Some(h.digest)) +} + +// --------------------------------------------------------------------------------------- +// §10 Bindings: the `moqt` claim's scopes +// --------------------------------------------------------------------------------------- + +/// A `bin-match` of `draft-ietf-moq-c4m-01` §2.1, or the `nil` that ends a namespace match. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Match { + Exact(String), + Prefix(String), + End, +} + +/// One `moqt-scope`: the actions, the namespace matches, and the track match if any. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Scope { + pub actions: Vec, + pub namespace: Option>, + pub track: Option, +} + +/// The action codes of `draft-ietf-moq-c4m-01` Table 1 this binding uses. +pub mod action { + pub const CLIENT_SETUP: u8 = 0; + pub const PUBLISH_NAMESPACE: u8 = 2; + pub const SUBSCRIBE_NAMESPACE: u8 = 3; + pub const SUBSCRIBE: u8 = 4; + pub const PUBLISH: u8 = 6; + pub const FETCH: u8 = 7; + pub const TRACK_STATUS: u8 = 8; +} + +/// The `moqt` claim value a grant maps onto (§10.2), scope by scope. +pub fn moqt_scopes(d: &Descriptor, room: &[u8; 32], g: &Grant) -> Vec { + use action::*; + let r = hex(room); + let me = hex(&g.principal); + let exact = |s: &str| Match::Exact(s.to_string()); + let mut out = vec![Scope { actions: vec![CLIENT_SETUP], namespace: None, track: None }]; + for m in 1..=3u8 { + if g.caps.publishes(m) { + let name = media_name(m).expect("a media kind"); + out.push(Scope { actions: vec![PUBLISH_NAMESPACE, PUBLISH], namespace: Some(vec![exact(&r), exact(&me), exact(name), Match::End]), track: None }); + for s in d.slots.iter().filter(|s| s.media == m) { + out.push(Scope { actions: vec![PUBLISH], namespace: Some(vec![exact(&r), exact(&format!("_{}", s.name)), exact(name), Match::End]), track: None }); + } + } + } + if g.policy.kinds.iter().any(|&b| b != 0) { + out.push(Scope { + actions: vec![PUBLISH_NAMESPACE, PUBLISH], + namespace: Some(vec![exact(&r), exact(&me), exact(EVENTS_FIELD), Match::End]), + track: Some(exact("0")), + }); + } + if g.caps.subscribe { + out.push(Scope { actions: vec![SUBSCRIBE_NAMESPACE], namespace: Some(vec![exact(&r)]), track: None }); + for layer in 0..=g.caps.max_layer { + out.push(Scope { actions: vec![SUBSCRIBE, FETCH, TRACK_STATUS], namespace: Some(vec![exact(&r)]), track: Some(exact(&track_name(layer))) }); + } + } + out +} + +/// A scope as the corpus writes it (§10.2): `[actions]`, `[actions, [matches]]` or +/// `[actions, [matches], match]`, a match a string (exact), `{"prefix": s}` or `null`. +pub fn scope_json(s: &Scope) -> serde_json::Value { + use serde_json::{json, Value}; + let m = |x: &Match| match x { + Match::Exact(s) => json!(s), + Match::Prefix(s) => json!({ "prefix": s }), + Match::End => Value::Null, + }; + let mut a = vec![json!(s.actions)]; + if let Some(ns) = &s.namespace { + a.push(Value::Array(ns.iter().map(m).collect())); + if let Some(t) = &s.track { + a.push(m(t)); + } + } + Value::Array(a) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn registered_profiles_are_valid_and_named_once() { + let ps = registered_profiles(); + let names: BTreeSet<&str> = ps.iter().map(|p| p.name.as_str()).collect(); + assert_eq!(names.len(), ps.len()); + for p in &ps { + let mut b = Vec::new(); + p.encode(&mut b); + let mut r = Rd { b: &b, p: 0 }; + let (q, (n, c, m)) = Profile::read(&mut r).unwrap(); + assert_eq!(q, *p); + assert_eq!(r.p, b.len()); + assert!(q.valid(&n, &c, &m), "{} breaks §8.1", p.name); + } + let music = registered_profile("music").unwrap(); + assert_eq!((music.channels, music.sample_rate, music.processing), (2, 48_000, 0)); + assert!(music.layers[0].min_kbps >= 128, "music has a bitrate floor"); + } + + #[test] + fn names_render_as_moq_transport_section_8_8() { + let ns = vec!["ab".to_string(), "_stage".to_string(), "video".to_string()]; + assert_eq!(render_full(&ns, "0"), "ab-_stage-video--0"); + assert_eq!(render_field(b"a-b.c"), "a.2db.2ec"); + } + + #[test] + fn detail_round_trips_and_refuses_trailing_bytes() { + let ds = [ + Detail::Join { grant: [7; 32] }, + Detail::Leave { reason: leave::REMOVED }, + Detail::Publish { slot: String::new(), media: media::VIDEO, profile: 1, layers: 2 }, + Detail::Publish { slot: "stage".into(), media: media::AUDIO, profile: 0, layers: 1 }, + Detail::Unpublish { slot: "stage".into(), media: media::AUDIO }, + Detail::GrantExchange { old: [1; 32], new: [2; 32] }, + Detail::Takeover { slot: "stage".into(), media: media::VIDEO, profile: 2, layers: 3, previous: [3; 32] }, + Detail::Failover { slot: "main".into(), media: media::VIDEO, failed: [4; 32], last_seen: 99 }, + ]; + for d in ds { + let b = d.encode(); + assert_eq!(Detail::parse(d.kind(), &b), Ok(d.clone())); + let mut longer = b.clone(); + longer.push(0); + assert_eq!(Detail::parse(d.kind(), &longer), Err(Reason::LifecycleMalformed)); + } + assert_eq!(Detail::parse(kind::LEAVE, &[5]), Err(Reason::LifecycleMalformed)); + assert_eq!(Detail::parse(kind::TAKEOVER, &Detail::Publish { slot: String::new(), media: 2, profile: 0, layers: 1 }.encode()), Err(Reason::LifecycleMalformed)); + } + + #[test] + fn attributes_are_bounded_and_ordered() { + let a = vec![("featured".to_string(), "true".to_string()), ("order".to_string(), "2".to_string())]; + assert_eq!(read_attrs(&attrs_bytes(&a)), Some(a.clone())); + let backwards: Vec<_> = a.iter().rev().cloned().collect(); + assert_eq!(read_attrs(&attrs_bytes(&backwards)), None); + let big = vec![("note".to_string(), "x".repeat(MAX_ATTRS))]; + assert_eq!(read_attrs(&attrs_bytes(&big)), None); + } + + #[test] + fn codes_are_distinct_from_live_events() { + let mine: BTreeSet<&str> = Reason::ALL.iter().map(|r| r.code()).collect(); + assert_eq!(mine.len(), Reason::ALL.len()); + for r in events::Reason::ALL { + assert!(!mine.contains(r.code()), "{} is live-events' code", r.code()); + assert_eq!(Reason::from_code(r.code()), Some(Reason::Events(r))); + } + for r in Reason::ALL { + assert_eq!(Reason::from_code(r.code()), Some(r)); + } + } + + #[test] + fn a_grant_covers_its_window_by_the_second() { + let g = Grant { + room: [0; 32], + principal: [0; 32], + prev: [0; 32], + effective: 0, + nbf: 10, + exp: 20, + role: 0, + caps: Caps::default(), + precedence: 0, + once: [0; 16], + viewer: [0; 16], + policy: Policy::default(), + joules_ceiling: NO_CEILING, + funds_ceiling: NO_CEILING, + currency: [0; 3], + profiles: vec![], + origins: vec![], + attrs: vec![], + sig: [0; 64], + }; + assert!(!g.covers(9_999_999, 0)); + assert!(g.covers(10_000_000, 0)); + assert!(g.covers(0, 19_999_999)); + assert!(!g.covers(0, 20_000_000)); + assert_eq!(g.grant_ref().2, NO_CEILING); + assert_eq!(g.grant_ref().3, None); + } +} diff --git a/wai/wai-rs/src/live_room/corpus.rs b/wai/wai-rs/src/live_room/corpus.rs new file mode 100644 index 000000000..d39ea6616 --- /dev/null +++ b/wai/wai-rs/src/live_room/corpus.rs @@ -0,0 +1,1181 @@ +//! The conformance corpus of extensions/live-rooms.md §12: `live-conformance/rooms/vectors.json`. +//! +//! [`generate`] writes it from fixed seeds: every key is SHA-256 of a fixed label and an +//! index, every time is a constant, and Ed25519 signing is deterministic (RFC 8032), so the +//! file is the same bytes on every machine. Each vector states the outcome it was written +//! to have, and the generator asserts that this module reaches it before writing it, so a +//! defect here cannot write itself into the corpus as expected. +//! +//! [`verify`] checks a corpus file against this module. `live-conformance/live_rooms_verify.py` +//! checks the same file from the extension's text, sharing no code with this module. + +use super::*; +use crate::key_log::{commitment, KeyEntry}; +use crate::live_events::{Caption, Cue, Marker, Reaction}; +use serde_json::{json, Map, Value}; + +/// The rooms' `t0`: 2026-10-16T00:00:00Z, in microseconds and in seconds. +const T0_US: u64 = 1_792_108_800_000_000; +const T0_S: u64 = T0_US / 1_000_000; +const S: u64 = 1_000_000; +const ORIGIN: &str = "https://rooms.example"; + +const AUTHORITY: u8 = 0; +const RELAY: u8 = 1; +const DIRECTOR: u8 = 2; +const PERFORMER: u8 = 3; +const VIEWER_A: u8 = 4; +const VIEWER_B: u8 = 5; +const VIEWER_C: u8 = 6; +const MODERATOR: u8 = 7; +const HOST: u8 = 8; +const EMERGENCY: u8 = 9; +const ENCODER_A: u8 = 10; +const ENCODER_B: u8 = 11; +const OTHER_AUTHORITY: u8 = 12; +const LOG_ROOT: u8 = 13; +const LOG_NEXT: u8 = 14; + +const PRINCIPALS: [(&str, u8); 15] = [ + ("authority", AUTHORITY), + ("relay", RELAY), + ("director", DIRECTOR), + ("performer", PERFORMER), + ("viewer_a", VIEWER_A), + ("viewer_b", VIEWER_B), + ("viewer_c", VIEWER_C), + ("moderator", MODERATOR), + ("host", HOST), + ("emergency", EMERGENCY), + ("encoder_a", ENCODER_A), + ("encoder_b", ENCODER_B), + ("other_authority", OTHER_AUTHORITY), + ("log_root", LOG_ROOT), + ("log_next", LOG_NEXT), +]; + +fn sha(parts: &[&[u8]]) -> [u8; 32] { + sha256(parts) +} + +fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&sha(&[b"wai:live-rooms/corpus/key\x00", &[i]])) +} + +fn pk(i: u8) -> [u8; 32] { + key(i).verifying_key().to_bytes() +} + +fn nonce(label: &str, i: u8) -> [u8; 16] { + sha(&[b"wai:live-rooms/corpus/", label.as_bytes(), &[0, i]])[..16].try_into().expect("16 bytes") +} + +fn unhex(s: &str) -> Option> { + if !s.len().is_multiple_of(2) { + return None; + } + (0..s.len()).step_by(2).map(|i| u8::from_str_radix(s.get(i..i + 2)?, 16).ok()).collect() +} + +fn bits(ks: &[u8]) -> [u8; 32] { + let mut b = [0u8; 32]; + for &k in ks { + b[(k / 8) as usize] |= 1 << (k % 8); + } + b +} + +fn kinds_of(b: &[u8; 32]) -> Vec { + (0..=255u8).filter(|k| b[(k / 8) as usize] & (1 << (k % 8)) != 0).collect() +} + +// ---- roles, profiles and descriptors ---- + +fn role(name: &str, publish: u8, subscribe: bool, max_layer: u8, powers: u8, events: &[u8]) -> Role { + Role { name: name.into(), caps: Caps { publish, subscribe, max_layer, powers }, events: bits(events) } +} + +const A: u8 = 1; +const V: u8 = 2; +const SC: u8 = 4; + +fn director() -> Role { + use kind::*; + role("director", A, true, 2, power::MODERATE | power::DIRECT | power::RECORD, &[META, CUE, CHAT, REACTION, MARKER, CONTROL, CAPTION, DECISION]) +} +fn performer() -> Role { + use kind::*; + role("performer", A | V, true, 2, 0, &[CHAT, REACTION, MARKER, TAKE_COMMIT]) +} +fn audience() -> Role { + use kind::*; + role("audience", 0, true, 1, 0, &[CHAT, REACTION, VOTE]) +} +fn host() -> Role { + use kind::*; + role("host", A | V | SC, true, 1, power::DIRECT, &[META, CUE, CHAT, POLL_OPEN, POLL_CLOSE, CONTROL, CAPTION]) +} +fn moderator() -> Role { + use kind::*; + role("moderator", 0, true, 0, power::MODERATE, &[CHAT, DECISION]) +} +fn encoder() -> Role { + role("encoder", A | V, false, 0, 0, &[]) +} +fn guest() -> Role { + use kind::*; + role("guest", A | V, true, 1, 0, &[CHAT, REACTION, VOTE, MARKER]) +} + +fn profile(name: &str) -> Profile { + registered_profile(name).expect("a registered profile") +} + +fn descriptor(clock: u8, origin: &str, roles: Vec, slots: Vec, profiles: Vec) -> Descriptor { + Descriptor { + authority: pk(AUTHORITY), + clock: pk(clock), + t0_us: T0_US, + tick_us: S, + origin: origin.into(), + limits: Limits { max_present: 16, max_publishers: 4, reval_s: 300, ceiling: Policy::default() }, + roles, + slots, + profiles, + review: Review { kinds: [0; 32], deadline_ms: 0, fallback: 0 }, + recording: Recording { mode: 0, retention_days: 0, commit_interval_ms: 0, jitter_ms: 0, regions: vec![] }, + sig: [0; 64], + } +} + +fn slot(name: &str, m: u8, redundancy: u8, failover_ms: u32) -> Slot { + Slot { name: name.into(), media: m, redundancy, failover_ms } +} + +// ---- the key log ---- + +fn entry(id: &str, who: u8, may_sign: &[&str]) -> KeyEntry { + KeyEntry::active(id, pk(who), may_sign) +} + +fn revision(origin: &str, keys: Vec, revoked: Vec<[u8; 32]>) -> Revision { + Revision { + origin: origin.into(), + seq: 0, + prev: None, + issued_at: "2026-10-15T00:00:00Z".into(), + root: [0; 32], + next_root: commitment(&pk(LOG_NEXT)), + keys, + revoked_modules: revoked, + grant_max_s: 86_400, + status_max_age_s: 3_600, + sig: [0; 64], + } +} + +fn head(origin: &str, keys: Vec, revoked: Vec<[u8; 32]>) -> String { + Revision::seal(&key(LOG_ROOT), revision(origin, keys, revoked)).expect("a well-formed revision").to_json() +} + +fn authority_entry() -> KeyEntry { + entry("room-authority", AUTHORITY, &[KEY_LOG_AUTHORITY]) +} + +fn viewer_id(i: u8) -> [u8; 16] { + nonce("viewer", i) +} + +fn viewer_tag(v: &[u8; 16]) -> [u8; 32] { + sha(&[VIEWER_DOMAIN, v]) +} + +// ---- building a room ---- + +/// A principal emitting its chain. +struct Author { + who: u8, + key: SigningKey, + room: [u8; 32], + seq: u64, + prev: [u8; 32], + records: Vec>, +} + +/// A room being written: its descriptor, grants, head and chains. +struct Build { + d: Descriptor, + descriptor: Vec, + room: [u8; 32], + grants: Vec>, + head: Option, + authors: Vec, +} + +impl Build { + fn new(d: Descriptor) -> Build { + let d = d.sign(&key(AUTHORITY)); + let head = (!d.origin.is_empty()).then(|| head(&d.origin, vec![authority_entry()], vec![])); + Build { room: d.room_id(), descriptor: d.to_bytes(), d, grants: vec![], head, authors: vec![] } + } + + /// A grant for `who` under role `role`, its caps the role's and its policy the role's + /// kinds with the default bounds; good for a day either side of `t0`. + fn grant(&self, who: u8, role: usize) -> Grant { + let r = &self.d.roles[role]; + Grant { + room: self.room, + principal: pk(who), + prev: [0; 32], + effective: 0, + nbf: T0_S - 3_600, + exp: T0_S + 86_400, + role: role as u8, + caps: r.caps, + precedence: 0, + once: [0; 16], + viewer: [0; 16], + policy: Policy::with_kinds(&kinds_of(&r.events)), + joules_ceiling: NO_CEILING, + funds_ceiling: NO_CEILING, + currency: [0; 3], + profiles: vec![], + origins: vec!["https://relay.example".into()], + attrs: vec![], + sig: [0; 64], + } + } + + /// Sign `g` with the room's authority and add it; its digest. + fn add(&mut self, g: Grant) -> [u8; 32] { + let g = g.sign(&key(AUTHORITY)); + self.grants.push(g.to_bytes()); + g.digest() + } + + fn author(&mut self, who: u8) -> &mut Author { + if let Some(i) = self.authors.iter().position(|a| a.who == who) { + return &mut self.authors[i]; + } + self.authors.push(Author { who, key: key(who), room: self.room, seq: 0, prev: [0; 32], records: vec![] }); + self.authors.last_mut().expect("just pushed") + } + + fn raw(&mut self, who: u8, t: u64, k: u8, payload: Vec) -> Vec { + let a = self.author(who); + let ev = Event::sign(&a.key, a.room, a.seq, a.prev, t, None, k, payload); + a.seq += 1; + a.prev = ev.digest(); + let b = ev.to_bytes(); + a.records.push(b.clone()); + b + } + + fn ev(&mut self, who: u8, t: u64, p: Payload) -> [u8; 32] { + let b = self.raw(who, t, p.kind(), p.encode()); + Event::parse(&b).expect("a corpus record parses").digest() + } + + /// A lifecycle event of the room's clock about `subject`. + fn life(&mut self, t: u64, subject: u8, d: Detail) { + let clock = PRINCIPALS.iter().find(|(_, i)| pk(*i) == self.d.clock).expect("a corpus clock").1; + self.ev(clock, t, Payload::Lifecycle { kind: d.kind(), subject: pk(subject), detail: d.encode() }); + } + + fn join(&mut self, t: u64, who: u8, grant: [u8; 32]) { + self.life(t, who, Detail::Join { grant }); + } + + fn publish(&mut self, t: u64, who: u8, slot: &str, m: u8, profile: u8, layers: u8) { + self.life(t, who, Detail::Publish { slot: slot.into(), media: m, profile, layers }); + } + + fn chains(&self) -> Vec>> { + self.authors.iter().map(|a| a.records.clone()).collect() + } +} + +fn chat(s: &str) -> Payload { + Payload::Chat { text: s.into() } +} + +fn control(target: u8, command: Command) -> Payload { + Payload::Control { target: pk(target), command } +} + +fn take_commit(i: u8) -> Payload { + Payload::TakeCommit(sha(&[b"wai:live-rooms/corpus/take", &[i]]).iter().chain(&[i; 8]).copied().collect()) +} + +// ---- vectors ---- + +/// What a vector was written to do. +enum Intent { + Accept, + Gap, + Refuse(At, Reason), +} + +struct Vector { + name: &'static str, + about: &'static str, + descriptor: Vec, + grants: Vec>, + head: Option, + chains: Vec>>, + intent: Intent, +} + +fn vector(name: &'static str, about: &'static str, b: &Build, intent: Intent) -> Vector { + Vector { name, about, descriptor: b.descriptor.clone(), grants: b.grants.clone(), head: b.head.clone(), chains: b.chains(), intent } +} + +/// The lesson room: a director, a performer, an audience, and the director's remote +/// record control of the performer. +fn lesson() -> (Build, [u8; 32]) { + use kind::*; + let mut d = descriptor(RELAY, ORIGIN, vec![director(), performer(), audience()], vec![], vec![profile("speech"), profile("music"), profile("camera-1080")]); + d.limits = Limits { max_present: 8, max_publishers: 3, reval_s: 300, ceiling: Policy::default() }; + d.review = Review { kinds: bits(&[CHAT]), deadline_ms: 5_000, fallback: 1 }; + d.recording = Recording { mode: 1, retention_days: 30, commit_interval_ms: 2_000, jitter_ms: 500, regions: vec![*b"DE", *b"FR"] }; + let mut b = Build::new(d); + let gd = Grant { profiles: vec![0], precedence: 50, joules_ceiling: 5_000_000_000, attrs: vec![("order".into(), "2".into()), ("pip".into(), "true".into())], ..b.grant(DIRECTOR, 0) }; + let gp = Grant { + profiles: vec![1, 2], + joules_ceiling: 20_000_000_000, + funds_ceiling: 5_000, + currency: *b"EUR", + attrs: vec![("featured".into(), "true".into()), ("order".into(), "1".into())], + ..b.grant(PERFORMER, 1) + }; + let ga = Grant { once: nonce("once", 1), viewer: viewer_id(VIEWER_A), ..b.grant(VIEWER_A, 2) }; + let gb = Grant { once: nonce("once", 2), viewer: viewer_id(VIEWER_B), ..max_layer_of(b.grant(VIEWER_B, 2), 0) }; + let gc = Grant { once: nonce("once", 3), viewer: viewer_id(VIEWER_C), ..b.grant(VIEWER_C, 2) }; + let (dd, dp, da, db) = (b.add(gd), b.add(gp), b.add(ga), b.add(gb)); + let revoked = b.add(gc); + b.head = Some(head(ORIGIN, vec![authority_entry()], vec![revoked, viewer_tag(&viewer_id(0x99))])); + b.join(0, DIRECTOR, dd); + b.join(0, PERFORMER, dp); + b.join(500_000, VIEWER_A, da); + b.join(600_000, VIEWER_B, db); + b.publish(S, PERFORMER, "", media::AUDIO, 1, 1); + b.publish(S, PERFORMER, "", media::VIDEO, 2, 3); + b.publish(S, DIRECTOR, "", media::AUDIO, 0, 1); + b.ev(DIRECTOR, 2 * S, control(PERFORMER, Command::RecordStart { count_in_ms: 4_000 })); + b.ev(VIEWER_A, 2_500_000, chat("ready when you are")); + b.ev(PERFORMER, 6 * S, take_commit(0)); + b.ev(PERFORMER, 8 * S, take_commit(1)); + b.ev(DIRECTOR, 9 * S, Payload::Marker(Marker { taxonomy: 2, polarity: 2, text: "rushed bar 12".into(), attachment: None })); + b.ev(DIRECTOR, 10 * S, control(PERFORMER, Command::RecordStop)); + b.ev(VIEWER_B, 10_500_000, Payload::Reaction(Reaction { rtype: 4, value: 1, target: None, remove: false })); + b.ev(DIRECTOR, 11 * S, chat("again from bar 9")); + b.life(12 * S, VIEWER_B, Detail::Leave { reason: leave::LEFT }); + (b, revoked) +} + +/// A grant like `g` whose `max_layer` is `layer`. +fn max_layer_of(g: Grant, layer: u8) -> Grant { + Grant { caps: Caps { max_layer: layer, ..g.caps }, ..g } +} + +/// The broadcast room: one publisher, several viewers, a moderator; no key log, and the +/// authority is its own clock. +fn broadcast() -> Build { + let mut d = descriptor(AUTHORITY, "", vec![host(), moderator(), audience()], vec![], vec![profile("speech"), profile("camera-720")]); + d.limits = Limits { max_present: 64, max_publishers: 1, reval_s: 0, ceiling: Policy::default() }; + let mut b = Build::new(d); + let gh = Grant { profiles: vec![0, 1], ..b.grant(HOST, 0) }; + let gm = b.grant(MODERATOR, 1); + let viewers: Vec = [VIEWER_A, VIEWER_B, VIEWER_C].iter().map(|&v| Grant { once: nonce("once", v), ..b.grant(v, 2) }).collect(); + let (dh, dm) = (b.add(gh), b.add(gm)); + let dv: Vec<[u8; 32]> = viewers.into_iter().map(|g| b.add(g)).collect(); + b.join(0, HOST, dh); + b.join(0, MODERATOR, dm); + b.publish(0, HOST, "", media::VIDEO, 1, 2); + b.publish(0, HOST, "", media::AUDIO, 0, 1); + b.join(S, VIEWER_A, dv[0]); + b.join(1_100_000, VIEWER_B, dv[1]); + b.join(1_200_000, VIEWER_C, dv[2]); + b.ev(HOST, 2 * S, Payload::Caption(Caption { duration_ms: 3_000, origin: 1, model: None, lang: "en".into(), text: "Welcome to the stream.".into() })); + let poll = b.ev(HOST, 3 * S, Payload::PollOpen { question: "Next topic?".into(), options: vec!["Tooling".into(), "Roadmap".into()] }); + b.ev(VIEWER_A, 4 * S, Payload::Vote { poll, option: 1 }); + b.ev(VIEWER_B, 4_100_000, Payload::Vote { poll, option: 1 }); + b.ev(VIEWER_C, 4_200_000, Payload::Vote { poll, option: 0 }); + let spam = b.ev(VIEWER_C, 5 * S, chat("first!!! follow the link in my name")); + b.ev(MODERATOR, 5_500_000, Payload::Decision { verdict: 2, target: spam, reason: 3 }); + b.ev(VIEWER_A, 6 * S, Payload::Reaction(Reaction { rtype: 4, value: 1, target: None, remove: false })); + b.ev(HOST, 7 * S, Payload::PollClose { poll, counts: vec![1, 2] }); + b.life(8 * S, VIEWER_C, Detail::Leave { reason: leave::REMOVED }); + b +} + +/// The takeover room: a performer live on the `stage` slot, then a feed of higher +/// precedence taking it over with no new session. +fn takeover() -> (Build, [u8; 32], [u8; 32]) { + let mut d = descriptor(RELAY, "", vec![performer(), host(), audience()], vec![slot("stage", media::VIDEO, 1, 0)], vec![profile("camera-720")]); + d.limits.max_publishers = 2; + let mut b = Build::new(d); + let gp = Grant { profiles: vec![0], precedence: 10, ..b.grant(PERFORMER, 0) }; + let ge = Grant { profiles: vec![0], precedence: 200, ..b.grant(EMERGENCY, 1) }; + let gv = b.grant(VIEWER_A, 2); + let (dp, de, dv) = (b.add(gp), b.add(ge), b.add(gv)); + b.join(0, PERFORMER, dp); + b.join(0, EMERGENCY, de); + b.join(0, VIEWER_A, dv); + b.publish(S, PERFORMER, "stage", media::VIDEO, 0, 2); + b.ev(VIEWER_A, 2 * S, chat("sounds great")); + (b, dp, de) +} + +/// The redundant room: two encoders bound to the `main` slot, the second on standby. +fn redundant() -> Build { + let mut d = descriptor(RELAY, "", vec![encoder(), audience()], vec![slot("main", media::VIDEO, 2, 2_000)], vec![profile("camera-720")]); + d.limits.max_publishers = 2; + let mut b = Build::new(d); + let ga = Grant { profiles: vec![0], ..b.grant(ENCODER_A, 0) }; + let gb = Grant { profiles: vec![0], ..b.grant(ENCODER_B, 0) }; + let gv = b.grant(VIEWER_A, 1); + let (da, db, dv) = (b.add(ga), b.add(gb), b.add(gv)); + b.join(0, ENCODER_A, da); + b.join(0, ENCODER_B, db); + b.join(0, VIEWER_A, dv); + b.publish(S, ENCODER_A, "main", media::VIDEO, 0, 2); + b.publish(1_200_000, ENCODER_B, "main", media::VIDEO, 0, 2); + b +} + +/// The promotion room: a viewer whose grant is exchanged, at a tick, for a guest's that +/// lets it publish. +fn promote() -> (Build, [u8; 32], [u8; 32]) { + let d = descriptor(RELAY, "", vec![audience(), guest()], vec![], vec![profile("speech"), profile("camera-720")]); + let mut b = Build::new(d); + let gv = Grant { once: nonce("once", 0x40), ..b.grant(VIEWER_A, 0) }; + let gw = b.grant(VIEWER_B, 0); + let (dv, dw) = (b.add(gv), b.add(gw)); + let gg = Grant { prev: dv, effective: 10 * S, profiles: vec![0, 1], attrs: vec![("order".into(), "3".into())], ..b.grant(VIEWER_A, 1) }; + let dg = b.add(gg); + b.join(0, VIEWER_A, dv); + b.join(0, VIEWER_B, dw); + b.ev(VIEWER_A, 2 * S, chat("can I ask a question?")); + (b, dv, dg) +} + +fn good_vectors() -> Vec { + let mut out = Vec::new(); + let (b, _) = lesson(); + out.push(vector( + "lesson", + "a lesson room under a key log: a director with remote record control (record_start with a count-in, record_stop), a performer publishing music and three camera layers, an audience under single-use grants, review and recording policies with a region pin; the head revokes a grant the room never uses and a viewer it never admits", + &b, + Intent::Accept, + )); + out.push(vector( + "broadcast", + "a broadcast room with no key log, its authority its own clock: one publisher, three viewers voting in a poll, a moderator's deny decision, a viewer removed; one publisher at most", + &broadcast(), + Intent::Accept, + )); + let (mut b, dp, _) = takeover(); + b.life(30 * S, EMERGENCY, Detail::Takeover { slot: "stage".into(), media: media::VIDEO, profile: 0, layers: 1, previous: pk(PERFORMER) }); + b.ev(EMERGENCY, 31 * S, Payload::Cue(Cue { cue_type: 4, cue_id: 7, duration_ms: 60_000, scte: None })); + b.ev(VIEWER_A, 40 * S, chat("what happened?")); + let _ = dp; + out.push(vector( + "takeover", + "a feed of precedence 200 takes the stage slot over from a performer of precedence 10: the slot's subscribers keep their subscription and the publisher behind it changes (§7.1)", + &b, + Intent::Accept, + )); + let mut b = redundant(); + b.life(20 * S, ENCODER_B, Detail::Failover { slot: "main".into(), media: media::VIDEO, failed: pk(ENCODER_A), last_seen: 17_500_000 }); + b.ev(VIEWER_A, 21 * S, chat("picture is back")); + out.push(vector( + "redundant_failover", + "two encoders bound to the main slot, the second on standby; the first stops, and 2.5 s later, past the slot's 2 s failover rule, the standby goes live (§7.1)", + &b, + Intent::Accept, + )); + let (mut b, dv, dg) = promote(); + b.life(10 * S, VIEWER_A, Detail::GrantExchange { old: dv, new: dg }); + b.publish(11 * S, VIEWER_A, "", media::AUDIO, 0, 1); + b.publish(11 * S, VIEWER_A, "", media::VIDEO, 1, 2); + b.ev(VIEWER_A, 12 * S, Payload::Marker(Marker { taxonomy: 1, polarity: 1, text: "question".into(), attachment: None })); + b.ev(VIEWER_B, 12 * S, Payload::Reaction(Reaction { rtype: 4, value: 1, target: None, remove: false })); + out.push(vector( + "promote_viewer", + "a viewer's audience grant exchanged at the 10 s tick for a guest grant chained to it: before, it may chat only; after, it publishes audio and video and sends a marker (§4.6)", + &b, + Intent::Accept, + )); + let (mut b, _, _) = promote(); + b.ev(VIEWER_B, 3 * S, chat("one")); + let lost = b.raw(VIEWER_B, 4 * S, kind::CHAT, chat("two").encode()); + b.ev(VIEWER_B, 5 * S, chat("three")); + let i = b.authors.iter().position(|a| a.who == VIEWER_B).expect("viewer_b's chain"); + b.authors[i].records.retain(|r| *r != lost); + out.push(vector( + "room_gap", + "a viewer's chain whose record seq 1 was not delivered: a delivery gap the room reports, not a refusal (§9.4)", + &b, + Intent::Gap, + )); + out +} + +/// A compact room the negative vectors start from: under a key log, with a host, a +/// moderator, an audience role and a guest role, a stage slot and a redundant main slot. +fn base() -> Descriptor { + let mut d = descriptor( + RELAY, + ORIGIN, + vec![host(), moderator(), audience(), guest(), encoder()], + vec![slot("stage", media::VIDEO, 1, 0), slot("main", media::VIDEO, 2, 2_000)], + vec![profile("speech"), profile("camera-720")], + ); + d.limits = Limits { max_present: 8, max_publishers: 3, reval_s: 60, ceiling: Policy::default() }; + d +} + +/// The base room with a host and a viewer joined, the host publishing video. +fn base_joined() -> (Build, [u8; 32], [u8; 32]) { + let mut b = Build::new(base()); + let gh = Grant { profiles: vec![0, 1], precedence: 20, ..b.grant(HOST, 0) }; + let gv = Grant { once: nonce("once", VIEWER_A), viewer: viewer_id(VIEWER_A), ..b.grant(VIEWER_A, 2) }; + let (dh, dv) = (b.add(gh), b.add(gv)); + b.join(0, HOST, dh); + b.join(0, VIEWER_A, dv); + b.publish(S, HOST, "", media::VIDEO, 1, 2); + (b, dh, dv) +} + +fn rec(chain: usize, record: usize) -> At { + At::Record { chain, record } +} + +/// The index of `who`'s chain, and of its last record. +fn last(b: &Build, who: u8) -> (usize, usize) { + let c = b.authors.iter().position(|a| a.who == who).expect("an author"); + (c, b.authors[c].records.len() - 1) +} + +fn refuse_last(b: &Build, who: u8, r: Reason) -> Intent { + let (c, i) = last(b, who); + Intent::Refuse(rec(c, i), r) +} + +fn descriptor_vectors() -> Vec { + let mut out = Vec::new(); + let refuse = |r: Reason| Intent::Refuse(At::Descriptor, r); + let ok = Build::new(base()); + let with = |bytes: Vec| Build { descriptor: bytes, ..Build::new(base()) }; + let whole = ok.descriptor.clone(); + out.push(vector("descriptor_truncated", "the descriptor without its last byte (§3.4)", &with(whole[..whole.len() - 1].to_vec()), refuse(Reason::Events(events::Reason::Truncated)))); + let mut t = whole.clone(); + t.push(0); + out.push(vector("descriptor_trailing", "the descriptor followed by one more byte (§3.4)", &with(t), refuse(Reason::Events(events::Reason::Malformed)))); + let mut v = whole.clone(); + v[4] = 2; + out.push(vector("descriptor_unknown_version", "a descriptor of version 2 (§3.4)", &with(v), refuse(Reason::Events(events::Reason::UnknownVersion)))); + let mut s = whole.clone(); + let n = s.len(); + s[n - 40] ^= 0x01; + out.push(vector("descriptor_bad_signature", "one bit of the descriptor's signature flipped (§3.2)", &with(s), refuse(Reason::Events(events::Reason::BadSignature)))); + let mut d = base(); + d.tick_us = 0; + out.push(vector("descriptor_tick_zero", "a descriptor whose tick is 0 (§3.4)", &Build::new(d), refuse(Reason::DescriptorInvalid))); + let mut d = base(); + let mut music = profile("music"); + music.processing = processing::DTX; + d.profiles.push(music); + out.push(vector( + "descriptor_profile_mismatch", + "a profile named music that turns DTX on: a profile under a registered name must be the registered one (§8.2)", + &Build::new(d), + refuse(Reason::DescriptorInvalid), + )); + let mut d = base(); + d.roles[2].events = bits(&[kind::CHAT, kind::JOIN]); + out.push(vector("descriptor_role_lifecycle", "a role that may send join, which the ceiling never permits (§3.3)", &Build::new(d), refuse(Reason::DescriptorInvalid))); + let mut d = base(); + d.recording = Recording { mode: 1, retention_days: 0, commit_interval_ms: 2_000, jitter_ms: 2_001, regions: vec![] }; + out.push(vector( + "descriptor_recording_jitter", + "a recording policy whose jitter exceeds its commit interval (§3.7)", + &Build::new(d), + refuse(Reason::DescriptorInvalid), + )); + out +} + +fn key_log_vectors() -> Vec { + let mut out = Vec::new(); + let refuse = |r: Reason| Intent::Refuse(At::KeyLog, r); + let mut b = Build::new(base()); + b.head = None; + out.push(vector("key_log_missing", "a descriptor that names an origin, and no head of its key log (§5)", &b, refuse(Reason::KeyLogMissing))); + let mut b = Build::new(base()); + b.head = Some(head("https://elsewhere.example", vec![authority_entry()], vec![])); + out.push(vector("key_log_other_origin", "the head of another origin's key log (§5; jwp-receipts §7.2 rule 2)", &b, refuse(Reason::KeyLogNotHeld))); + let mut b = Build::new(base()); + let tampered = Revision::seal(&key(LOG_ROOT), revision(ORIGIN, vec![authority_entry()], vec![])).expect("well formed"); + let tampered = Revision { revoked_modules: vec![[0x5A; 32]], ..tampered }; + b.head = Some(tampered.to_json()); + out.push(vector( + "key_log_bad_signature", + "a head whose revoked list was changed after its root signed it (§5; jwp-receipts §7.2 rule 3)", + &b, + refuse(Reason::KeyLogNotHeld), + )); + let mut b = Build::new(base()); + b.head = Some(head(ORIGIN, vec![entry("room-authority", AUTHORITY, &["delivery"])], vec![])); + out.push(vector("authority_not_listed", "a head that lists the authority's key with delivery and not live/room (§5)", &b, refuse(Reason::AuthorityNotListed))); + let mut b = Build::new(base()); + let revoked = KeyEntry { status: EntryStatus::Revoked, compromised_since: Some("2026-10-14T00:00:00Z".into()), ..authority_entry() }; + b.head = Some(head(ORIGIN, vec![revoked], vec![])); + out.push(vector("authority_revoked", "a head that lists the authority's key as revoked (§5; jwp-receipts §7.6)", &b, refuse(Reason::AuthorityRevoked))); + out +} + +fn grant_vectors() -> Vec { + let mut out = Vec::new(); + let refuse = |i: usize, r: Reason| Intent::Refuse(At::Grant(i), r); + // Each adds one good grant, then the defective one at index 1. + let one = |f: &dyn Fn(&Build) -> Vec| { + let mut b = Build::new(base()); + let g = b.grant(HOST, 0); + b.add(g); + let bad = f(&b); + b.grants.push(bad); + b + }; + out.push(vector( + "grant_truncated", + "a grant without its last ten bytes (§4.3)", + &one(&|b| { + let g = b.grant(VIEWER_A, 2).sign(&key(AUTHORITY)).to_bytes(); + g[..g.len() - 10].to_vec() + }), + refuse(1, Reason::Events(events::Reason::Truncated)), + )); + out.push(vector( + "grant_bad_signature", + "a grant signed by a key that is not the room's authority (§4.2)", + &one(&|b| b.grant(VIEWER_A, 2).sign(&key(OTHER_AUTHORITY)).to_bytes()), + refuse(1, Reason::Events(events::Reason::BadSignature)), + )); + out.push(vector( + "grant_wrong_room", + "a grant of another room, signed by this room's authority (§4.3)", + &one(&|b| Grant { room: sha(&[b"wai:live-rooms/corpus/other-room"]), ..b.grant(VIEWER_A, 2) }.sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::Events(events::Reason::WrongRoom)), + )); + out.push(vector( + "grant_lifecycle_kind", + "a grant whose policy permits join: no grant permits a lifecycle kind (§4.3)", + &one(&|b| Grant { policy: Policy::with_kinds(&[kind::CHAT, kind::JOIN]), ..b.grant(VIEWER_A, 2) }.sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::GrantInvalid), + )); + out.push(vector( + "grant_attrs_too_long", + "a grant whose attributes take more than 1024 bytes (§4.4)", + &one(&|b| Grant { attrs: vec![("note".into(), "x".repeat(1_020))], ..b.grant(VIEWER_A, 2) }.sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::GrantInvalid), + )); + out.push(vector( + "grant_too_long", + "a grant good for fourteen days and one second (§4.3)", + &one(&|b| Grant { exp: T0_S - 3_600 + MAX_GRANT_S + 1, ..b.grant(VIEWER_A, 2) }.sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::GrantTooLong), + )); + out.push(vector( + "caps_exceed_role", + "an audience grant that may subscribe up to layer 2, above its role's layer 1 (§4.3)", + &one(&|b| max_layer_of(b.grant(VIEWER_A, 2), 2).sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::CapsExceedRole), + )); + out.push(vector( + "grant_exceeds_room", + "a grant whose payload bound of 4096 bytes is above the room's ceiling of 1024 (§4.3)", + &one(&|b| { + let g = b.grant(VIEWER_A, 2); + Grant { policy: Policy { max_payload: 4_096, ..g.policy }, ..g }.sign(&key(AUTHORITY)).to_bytes() + }), + refuse(1, Reason::GrantExceedsRoom), + )); + out.push(vector( + "exchange_unlinked_grant", + "a grant whose prev names no grant given before it (§4.6)", + &one(&|b| Grant { prev: [0x11; 32], effective: 5 * S, ..b.grant(VIEWER_A, 2) }.sign(&key(AUTHORITY)).to_bytes()), + refuse(1, Reason::ExchangeUnlinked), + )); + let mut b = Build::new(base()); + let g0 = b.grant(VIEWER_A, 2); + let d0 = b.add(g0); + let moved = Grant { prev: d0, effective: 5 * S, ..b.grant(VIEWER_B, 3) }; + b.add(moved); + out.push(vector( + "exchange_mismatch", + "a grant chained to viewer_a's that names viewer_b: an exchange that changes the principal (§4.6)", + &b, + refuse(1, Reason::ExchangeMismatch), + )); + out +} + +fn record_vectors() -> Vec { + use kind::*; + let mut out = Vec::new(); + + let (mut b, _, _) = base_joined(); + let mut bad = b.raw(VIEWER_A, 2 * S, CHAT, chat("tampered").encode()); + let n = bad.len(); + bad[n - 30] ^= 0x01; + let (c, i) = last(&b, VIEWER_A); + b.authors[c].records[i] = bad; + out.push(vector("event_bad_signature", "one bit of a viewer's event signature flipped (live-events §3.2)", &b, Intent::Refuse(rec(c, i), Reason::Events(events::Reason::BadSignature)))); + + let (mut b, _, _) = base_joined(); + let other = sha(&[b"wai:live-rooms/corpus/other-room"]); + let a = b.author(VIEWER_A); + let ev = Event::sign(&a.key, other, a.seq, a.prev, 2 * S, None, CHAT, chat("wrong place").encode()); + a.records.push(ev.to_bytes()); + let r = refuse_last(&b, VIEWER_A, Reason::Events(events::Reason::WrongRoom)); + out.push(vector("event_wrong_room", "a viewer's event signed for another room (live-events §6.1)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.ev(VIEWER_A, 2 * S, Payload::Cue(Cue { cue_type: 3, cue_id: 1, duration_ms: 0, scte: None })); + let r = refuse_last(&b, VIEWER_A, Reason::Events(events::Reason::KindNotPermitted)); + out.push(vector("kind_not_in_grant", "a viewer sends a cue, a kind its grant does not permit (§9.2; live-events §6.1 step 5)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.ev(VIEWER_A, 2 * S, Payload::Lifecycle { kind: JOIN, subject: pk(VIEWER_B), detail: [0; 32].to_vec() }); + let r = refuse_last(&b, VIEWER_A, Reason::Events(events::Reason::KindNotPermitted)); + out.push(vector("lifecycle_by_participant", "a viewer authors a join: only the room's keys author lifecycle (§9.2)", &b, r)); + + let mut b = Build::new(base()); + let g = Grant { exp: T0_S + 60, ..b.grant(VIEWER_A, 2) }; + let d = b.add(g); + b.join(0, VIEWER_A, d); + b.ev(VIEWER_A, 30 * S, chat("still here")); + b.ev(VIEWER_A, 60 * S, chat("one second too late")); + let r = refuse_last(&b, VIEWER_A, Reason::OutsideGrantWindow); + out.push(vector("outside_grant_window", "a viewer's event at t0 + 60 s under a grant whose exp is t0 + 60 s (§4.3, §9.2)", &b, r)); + + let mut b = Build::new(base()); + let g = Grant { nbf: T0_S + 10, ..b.grant(VIEWER_A, 2) }; + let d = b.add(g); + b.join(5 * S, VIEWER_A, d); + let r = refuse_last(&b, RELAY, Reason::OutsideGrantWindow); + out.push(vector("join_before_nbf", "a join at t0 + 5 s naming a grant whose nbf is t0 + 10 s (§7.2)", &b, r)); + + let mut b = Build::new(base()); + let g = b.grant(VIEWER_A, 2); + let d = b.add(g); + b.ev(VIEWER_A, 0, chat("early")); + b.join(S, VIEWER_A, d); + out.push(vector("not_present_before_join", "a viewer's chat at t 0, before its join at 1 s (§9.2)", &b, Intent::Refuse(rec(0, 0), Reason::NotPresent))); + + let (mut b, _, _) = base_joined(); + b.life(2 * S, VIEWER_A, Detail::Leave { reason: leave::LEFT }); + b.ev(VIEWER_A, 3 * S, chat("after leaving")); + let r = refuse_last(&b, VIEWER_A, Reason::NotPresent); + out.push(vector("not_present_after_leave", "a viewer's chat after its leave (§9.2)", &b, r)); + + let mut b = Build::new(base()); + let g = Grant { once: nonce("once", 0x51), ..b.grant(VIEWER_B, 2) }; + let d = b.add(g); + b.head = Some(head(ORIGIN, vec![authority_entry()], vec![d])); + b.join(0, VIEWER_B, d); + let r = refuse_last(&b, RELAY, Reason::GrantRevoked); + out.push(vector("grant_revoked", "a join naming a grant whose digest the head's revoked_modules lists (§5)", &b, r)); + + let mut b = Build::new(base()); + let g = Grant { viewer: viewer_id(VIEWER_C), ..b.grant(VIEWER_C, 2) }; + let d = b.add(g); + b.head = Some(head(ORIGIN, vec![authority_entry()], vec![viewer_tag(&viewer_id(VIEWER_C))])); + b.join(0, VIEWER_C, d); + let r = refuse_last(&b, RELAY, Reason::GrantRevoked); + out.push(vector("viewer_revoked", "a join naming a grant whose viewer's tag the head's revoked_modules lists (§5)", &b, r)); + + let (mut b, _, dv) = base_joined(); + b.life(2 * S, VIEWER_A, Detail::Leave { reason: leave::CONNECTION_LOST }); + b.join(3 * S, VIEWER_A, dv); + let r = refuse_last(&b, RELAY, Reason::GrantReused); + out.push(vector("grant_reused", "a single-use grant named by a second join after the first ended (§4.1, §7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.join(2 * S, VIEWER_B, [0x77; 32]); + let r = refuse_last(&b, RELAY, Reason::GrantUnknown); + out.push(vector("grant_unknown", "a join naming a digest no grant has (§7.2)", &b, r)); + + let (mut b, _, dv) = base_joined(); + b.join(2 * S, VIEWER_B, dv); + let r = refuse_last(&b, RELAY, Reason::GrantWrongPrincipal); + out.push(vector("grant_wrong_principal", "viewer_b joined under viewer_a's grant (§7.2)", &b, r)); + + let (mut b, dh, _) = base_joined(); + b.join(2 * S, HOST, dh); + let r = refuse_last(&b, RELAY, Reason::AlreadyPresent); + out.push(vector("already_present", "a second join of a principal already present (§7.2)", &b, r)); + + let mut d = base(); + d.limits.max_present = 2; + let mut b = Build::new(d); + let ds: Vec<[u8; 32]> = [VIEWER_A, VIEWER_B, VIEWER_C].iter().map(|&v| { + let g = b.grant(v, 2); + b.add(g) + }).collect(); + b.join(0, VIEWER_A, ds[0]); + b.join(0, VIEWER_B, ds[1]); + b.join(S, VIEWER_C, ds[2]); + let r = refuse_last(&b, RELAY, Reason::ParticipantLimit); + out.push(vector("participant_limit", "a third join in a room of at most two present (§3.5)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.ev(RELAY, 2 * S, Payload::Lifecycle { kind: LEAVE, subject: pk(VIEWER_A), detail: vec![9] }); + let r = refuse_last(&b, RELAY, Reason::LifecycleMalformed); + out.push(vector("lifecycle_malformed", "a leave whose reason is 9 (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.publish(2 * S, VIEWER_A, "", media::VIDEO, 1, 1); + let r = refuse_last(&b, RELAY, Reason::PublishNotPermitted); + out.push(vector("publish_not_permitted", "a viewer, whose grant publishes nothing, published (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.publish(2 * S, HOST, "", media::VIDEO, 0, 1); + let r = refuse_last(&b, RELAY, Reason::ProfileNotGranted); + out.push(vector("profile_not_granted", "video published under the speech profile, an audio profile (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.publish(2 * S, HOST, "", media::AUDIO, 0, 2); + let r = refuse_last(&b, RELAY, Reason::ProfileNotGranted); + out.push(vector("profile_layers_exceeded", "audio published with two layers under the one-layer speech profile (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.publish(2 * S, HOST, "", media::VIDEO, 1, 1); + let r = refuse_last(&b, RELAY, Reason::AlreadyPublished); + out.push(vector("already_published", "the host's video published a second time (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.life(2 * S, HOST, Detail::Unpublish { slot: String::new(), media: media::AUDIO }); + let r = refuse_last(&b, RELAY, Reason::NotPublished); + out.push(vector("not_published", "the host's audio unpublished, never published (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + b.publish(2 * S, HOST, "backstage", media::VIDEO, 1, 1); + let r = refuse_last(&b, RELAY, Reason::SlotUnknown); + out.push(vector("slot_unknown", "a publish into a slot the descriptor does not declare (§7.2)", &b, r)); + + let (mut b, _, _) = base_joined(); + let g = Grant { profiles: vec![1], ..b.grant(EMERGENCY, 0) }; + let d = b.add(g); + b.join(2 * S, EMERGENCY, d); + b.publish(3 * S, HOST, "stage", media::VIDEO, 1, 1); + b.publish(4 * S, EMERGENCY, "stage", media::VIDEO, 1, 1); + let r = refuse_last(&b, RELAY, Reason::SlotFull); + out.push(vector("slot_full", "a second publish into the stage slot, whose redundancy is 1 (§7.1)", &b, r)); + + let mut d = base(); + d.limits.max_publishers = 1; + let mut b = Build::new(d); + let gh = Grant { profiles: vec![0, 1], ..b.grant(HOST, 0) }; + let ge = Grant { profiles: vec![0, 1], ..b.grant(EMERGENCY, 0) }; + let (dh, de) = (b.add(gh), b.add(ge)); + b.join(0, HOST, dh); + b.join(0, EMERGENCY, de); + b.publish(S, HOST, "", media::VIDEO, 1, 2); + b.publish(S, HOST, "", media::AUDIO, 0, 1); + b.publish(2 * S, EMERGENCY, "", media::AUDIO, 0, 1); + let r = refuse_last(&b, RELAY, Reason::PublisherLimit); + out.push(vector("publisher_limit", "a second principal publishing in a room of at most one publisher (§3.5)", &b, r)); + + let (mut b, _, dv) = base_joined(); + let gw = b.grant(VIEWER_B, 2); + let dw = b.add(gw); + let gg = Grant { prev: dw, effective: 5 * S, ..b.grant(VIEWER_B, 3) }; + let dg = b.add(gg); + b.join(2 * S, VIEWER_B, dw); + b.life(5 * S, VIEWER_B, Detail::GrantExchange { old: dv, new: dg }); + let r = refuse_last(&b, RELAY, Reason::ExchangeNotCurrent); + out.push(vector("exchange_not_current", "an exchange whose old grant is not the subject's current one (§4.6)", &b, r)); + + let (mut b, _, dv) = base_joined(); + let gg = Grant { prev: dv, effective: 5 * S, ..b.grant(VIEWER_A, 3) }; + let dg = b.add(gg); + b.life(5_500_000, VIEWER_A, Detail::GrantExchange { old: dv, new: dg }); + let r = refuse_last(&b, RELAY, Reason::ExchangeOffTick); + out.push(vector("exchange_off_tick", "an exchange recorded at 5.5 s for a grant effective at the 5 s tick (§4.6)", &b, r)); + + let (mut b, _, dv) = base_joined(); + let g2 = Grant { prev: dv, effective: 5 * S, ..b.grant(VIEWER_A, 3) }; + let d2 = b.add(g2); + let g3 = Grant { prev: dv, effective: 9 * S, precedence: 1, ..b.grant(VIEWER_A, 3) }; + let d3 = b.add(g3); + b.life(5 * S, VIEWER_A, Detail::GrantExchange { old: dv, new: d2 }); + b.life(9 * S, VIEWER_A, Detail::GrantExchange { old: d2, new: d3 }); + let r = refuse_last(&b, RELAY, Reason::ExchangeUnlinked); + out.push(vector("exchange_unlinked_event", "an exchange to a grant chained to an earlier grant, not to the current one (§4.6)", &b, r)); + + let (mut b, dh, _) = base_joined(); + let gd = Grant { prev: dh, effective: 5 * S, ..b.grant(HOST, 2) }; + let dd = b.add(gd); + b.life(5 * S, HOST, Detail::GrantExchange { old: dh, new: dd }); + let r = refuse_last(&b, RELAY, Reason::PublishNotPermitted); + out.push(vector("exchange_while_publishing", "the host's grant exchanged for an audience grant while it still publishes video (§4.6)", &b, r)); + + let (mut b, _, _) = base_joined(); + let g = Grant { profiles: vec![1], precedence: 20, ..b.grant(EMERGENCY, 0) }; + let d = b.add(g); + b.join(2 * S, EMERGENCY, d); + b.publish(3 * S, HOST, "stage", media::VIDEO, 1, 1); + b.life(4 * S, EMERGENCY, Detail::Takeover { slot: "stage".into(), media: media::VIDEO, profile: 1, layers: 1, previous: pk(HOST) }); + let r = refuse_last(&b, RELAY, Reason::TakeoverNotHigher); + out.push(vector("takeover_not_higher", "a takeover of the stage slot by a grant of precedence 20 from a publisher of precedence 20 (§7.1)", &b, r)); + + let mut b = redundant(); + let gc = Grant { profiles: vec![0], ..b.grant(VIEWER_C, 0) }; + let dc = b.add(gc); + b.join(5 * S, VIEWER_C, dc); + b.life(20 * S, VIEWER_C, Detail::Failover { slot: "main".into(), media: media::VIDEO, failed: pk(ENCODER_A), last_seen: 15 * S }); + let r = refuse_last(&b, RELAY, Reason::FailoverNotStandby); + out.push(vector("failover_not_standby", "a failover to an encoder that is not the main slot's standby (§7.1)", &b, r)); + + let mut b = redundant(); + b.life(20 * S, ENCODER_B, Detail::Failover { slot: "main".into(), media: media::VIDEO, failed: pk(ENCODER_A), last_seen: 18_500_000 }); + let r = refuse_last(&b, RELAY, Reason::FailoverEarly); + out.push(vector("failover_early", "a failover 1.5 s after the live encoder was last seen, under the slot's 2 s rule (§7.1)", &b, r)); + + let mut b = Build::new(base()); + let g = Grant { caps: Caps { powers: power::DIRECT, ..b.grant(HOST, 0).caps }, profiles: vec![0, 1], ..b.grant(HOST, 0) }; + let gv = b.grant(VIEWER_A, 2); + let (d, dv) = (b.add(g), b.add(gv)); + b.join(0, HOST, d); + b.join(0, VIEWER_A, dv); + b.ev(HOST, S, control(VIEWER_A, Command::Mute { on: true })); + b.ev(HOST, 2 * S, control(VIEWER_A, Command::RecordStart { count_in_ms: 3_000 })); + let r = refuse_last(&b, HOST, Reason::PowerNotGranted); + out.push(vector("power_not_granted", "a host with the direct power but not record mutes a viewer, then sends record_start (§3.3)", &b, r)); + + let mut b = Build::new(base()); + let g = b.grant(VIEWER_A, 2); + let g = Grant { policy: Policy { max_events: 2, ..g.policy }, ..g }; + let d = b.add(g); + b.join(0, VIEWER_A, d); + b.ev(VIEWER_A, S, chat("a")); + b.ev(VIEWER_A, 1_300_000, chat("b")); + b.ev(VIEWER_A, 1_600_000, chat("c")); + let r = refuse_last(&b, VIEWER_A, Reason::Events(events::Reason::RateExceeded)); + out.push(vector("rate_exceeded", "a third event in one second under a grant of two per second (§4.1; live-events §6.3)", &b, r)); + + let mut b = Build::new(base()); + let g = b.grant(VIEWER_A, 2); + let g = Grant { policy: Policy { max_payload: 32, ..g.policy }, ..g }; + let d = b.add(g); + b.join(0, VIEWER_A, d); + b.ev(VIEWER_A, S, chat("this chat is longer than thirty-two bytes")); + let r = refuse_last(&b, VIEWER_A, Reason::Events(events::Reason::PayloadTooLarge)); + out.push(vector("payload_too_large", "a chat of 43 payload bytes under a grant whose payload bound is 32 (§4.1; live-events §6.1 step 6)", &b, r)); + + let mut b = broadcast(); + let i = b.authors.iter().position(|a| a.who == HOST).expect("the host"); + b.authors[i].records.pop(); + b.authors[i].seq -= 1; + b.authors[i].prev = Event::parse(b.authors[i].records.last().expect("a record")).expect("parses").digest(); + let poll = Event::parse(&b.authors[i].records[1]).expect("the poll_open").digest(); + b.ev(HOST, 7 * S, Payload::PollClose { poll, counts: vec![2, 1] }); + let r = refuse_last(&b, HOST, Reason::Events(events::Reason::TallyMismatch)); + out.push(vector("tally_mismatch", "the broadcast poll closed with a tally the replay does not reach (live-events §7)", &b, r)); + + out +} + +fn at_json(at: &At) -> Value { + match at { + At::Descriptor => json!(["descriptor"]), + At::KeyLog => json!(["key_log"]), + At::Grant(i) => json!(["grant", i]), + At::Record { chain, record } => json!(["record", chain, record]), + } +} + +fn state_json(run: &RoomRun) -> Value { + let d = run.descriptor.as_ref().expect("a room that read"); + let room = run.room.expect("a room id"); + let st = &run.state; + let precedence = |p: &[u8; 32]| { + st.present.get(p).and_then(|g| run.grants.iter().find(|h| h.digest == *g)).map(|h| h.grant.precedence) + }; + let mut tracks: Vec = Vec::new(); + for ((p, m), h) in &st.own { + let ns = track_namespace(&room, &Owner::Principal(*p), media_name(*m).expect("a media kind")); + tracks.extend((0..h.layers).map(|l| render_full(&ns, &track_name(l)))); + } + for (s, ss) in d.slots.iter().zip(&st.slots) { + if let Some(h) = ss.live { + let ns = track_namespace(&room, &Owner::Slot(s.name.clone()), media_name(s.media).expect("a media kind")); + tracks.extend((0..h.layers).map(|l| render_full(&ns, &track_name(l)))); + } + } + tracks.sort(); + json!({ + "present": st.present.iter().map(|(p, g)| json!({"principal": hex(p), "grant": hex(g)})).collect::>(), + "published": st.own.iter().map(|((p, m), h)| json!({ + "principal": hex(p), + "media": media_name(*m), + "profile": d.profiles[h.profile as usize].name, + "layers": h.layers, + })).collect::>(), + "slots": d.slots.iter().zip(&st.slots).map(|(s, ss)| json!({ + "slot": s.name, + "media": media_name(s.media), + "live": ss.live.map(|h| hex(&h.principal)), + "standby": ss.standby.map(|h| hex(&h.principal)), + "precedence": ss.live.and_then(|h| precedence(&h.principal)), + })).collect::>(), + "tracks": tracks, + "timeline": st.timeline.iter().map(|(p, g, t)| json!({"principal": hex(p), "grant": hex(g), "t": t})).collect::>(), + }) +} + +fn tally_json(t: &events::Tally) -> Value { + json!({ + "state_hash": hex(&t.state_hash), + "polls": t.polls.iter().map(|p| json!({"poll": hex(&p.poll), "open": p.open, "counts": p.counts})).collect::>(), + }) +} + +fn moqt_json(run: &RoomRun) -> Value { + let d = run.descriptor.as_ref().expect("a room that read"); + let room = run.room.expect("a room id"); + Value::Array( + run.grants + .iter() + .map(|h| json!({"grant": hex(&h.digest), "reval": d.limits.reval_s, "scopes": moqt_scopes(d, &room, &h.grant).iter().map(scope_json).collect::>()})) + .collect(), + ) +} + +fn gaps_json(gaps: &[events::Gap]) -> Value { + Value::Array(gaps.iter().map(|g| json!({"principal": hex(&g.principal), "first": g.first, "last": g.last})).collect()) +} + +fn order_json(run: &RoomRun) -> Value { + Value::Array(run.order.iter().map(|(c, i, g)| json!([c, i, g.map(|g| hex(&g))])).collect()) +} + +fn run_of(v: &Value) -> Option { + let descriptor = unhex(v["descriptor"].as_str()?)?; + let grants: Vec> = v["grants"].as_array()?.iter().map(|g| g.as_str().and_then(unhex)).collect::>()?; + let chains: Vec>> = v["chains"] + .as_array()? + .iter() + .map(|c| c.as_array().and_then(|rs| rs.iter().map(|r| r.as_str().and_then(unhex)).collect::>>())) + .collect::>()?; + let head = v["key_log_head"].as_str(); + Some(verify_room(&descriptor, &grants, head, &chains)) +} + +/// What a run states, as the corpus writes it: the outcome and what goes with it. +fn outcome_json(run: &RoomRun) -> Map { + let mut o = Map::new(); + match &run.outcome { + RoomOutcome::Refuse { at, reason } => { + o.insert("outcome".into(), json!("refuse")); + o.insert("reason".into(), json!(reason.code())); + o.insert("at".into(), at_json(at)); + } + RoomOutcome::Gap(g) => { + o.insert("outcome".into(), json!("gap")); + o.insert("reason".into(), json!(events::Reason::DeliveryGap.code())); + o.insert("room".into(), json!(hex(&run.room.expect("a room id")))); + o.insert("gaps".into(), gaps_json(g)); + o.insert("order".into(), order_json(run)); + } + RoomOutcome::Accept => { + o.insert("outcome".into(), json!("accept")); + o.insert("room".into(), json!(hex(&run.room.expect("a room id")))); + o.insert("grant_digests".into(), json!(run.grants.iter().map(|h| hex(&h.digest)).collect::>())); + o.insert("order".into(), order_json(run)); + o.insert("state".into(), state_json(run)); + o.insert("tally".into(), tally_json(run.tally.as_ref().expect("an accepted room's tally"))); + o.insert("moqt".into(), moqt_json(run)); + } + } + o +} + +fn vector_json(v: &Vector) -> Value { + let run = verify_room(&v.descriptor, &v.grants, v.head.as_deref(), &v.chains); + match (&v.intent, &run.outcome) { + (Intent::Accept, RoomOutcome::Accept) | (Intent::Gap, RoomOutcome::Gap(_)) => {} + (Intent::Refuse(at, r), RoomOutcome::Refuse { at: a, reason }) if at == a && r == reason => {} + _ => panic!("vector {} does not reach the outcome it was written to have: {:?}", v.name, run.outcome), + } + let mut o = Map::new(); + o.insert("name".into(), json!(v.name)); + o.insert("about".into(), json!(v.about)); + o.insert("descriptor".into(), json!(hex(&v.descriptor))); + o.insert("grants".into(), json!(v.grants.iter().map(|g| hex(g)).collect::>())); + o.insert("key_log_head".into(), v.head.as_ref().map_or(Value::Null, |h| json!(h))); + o.insert("chains".into(), json!(v.chains.iter().map(|c| c.iter().map(|r| hex(r)).collect::>()).collect::>())); + o.extend(outcome_json(&run)); + Value::Object(o) +} + +/// The vectors, in the order the file lists them. +fn vectors() -> Vec { + let mut v = good_vectors(); + v.extend(descriptor_vectors()); + v.extend(key_log_vectors()); + v.extend(grant_vectors()); + v.extend(record_vectors()); + v +} + +/// The corpus file, `vectors.json`. +pub fn generate() -> String { + let doc = json!({ + "corpus": "wai.live.room", + "extension": "extensions/live-rooms.md", + "principals": PRINCIPALS.iter().map(|(n, i)| (n.to_string(), json!(hex(&pk(*i))))).collect::>(), + "registered_profiles": registered_profiles().iter().map(|p| { + let mut b = Vec::new(); + p.encode(&mut b); + json!({"name": p.name, "record": hex(&b)}) + }).collect::>(), + "vectors": vectors().iter().map(vector_json).collect::>(), + }); + serde_json::to_string_pretty(&doc).expect("the corpus serialises") + "\n" +} + +/// Check a corpus file against this module; the failures, one line each. +pub fn verify(doc: &str) -> Vec { + let mut fails = Vec::new(); + let root: Value = match serde_json::from_str(doc) { + Ok(v) => v, + Err(e) => return vec![format!("the corpus does not parse: {e}")], + }; + for p in root["registered_profiles"].as_array().into_iter().flatten() { + let mine = p["name"].as_str().and_then(registered_profile).map(|q| { + let mut b = Vec::new(); + q.encode(&mut b); + hex(&b) + }); + if mine.as_deref() != p["record"].as_str() { + fails.push(format!("registered profile {}: differs", p["name"])); + } + } + for v in root["vectors"].as_array().into_iter().flatten() { + let name = v["name"].as_str().unwrap_or("?"); + let Some(run) = run_of(v) else { + fails.push(format!("{name}: the vector does not read")); + continue; + }; + for (k, want) in outcome_json(&run) { + if v[&k] != want { + fails.push(format!("{name}: {k} is {want}, the corpus states {}", v[&k])); + } + } + } + fails +} diff --git a/wai/wai-rs/src/output_tree.rs b/wai/wai-rs/src/output_tree.rs index 29116519f..76f92cafc 100644 --- a/wai/wai-rs/src/output_tree.rs +++ b/wai/wai-rs/src/output_tree.rs @@ -72,7 +72,10 @@ pub fn leaf(p: &Presentation) -> [u8; 32] { sha256(&b) } -fn node(l: &[u8; 32], r: &[u8; 32]) -> [u8; 32] { +/// The tree's interior node, `SHA-256("wai:out-node\x01" ‖ left ‖ right)`. A tree of +/// another leaf domain built with this node (capture-binding's take tree) is this +/// construction over its own leaves. +pub fn node(l: &[u8; 32], r: &[u8; 32]) -> [u8; 32] { let mut b = Vec::with_capacity(NODE_DOMAIN.len() + 64); b.extend_from_slice(NODE_DOMAIN); b.extend_from_slice(l); @@ -89,6 +92,11 @@ fn split(n: usize) -> usize { k } +/// RFC 6962's Merkle tree hash over leaf hashes `d` (`d` not empty), with [`node`]. +pub fn tree_hash(d: &[[u8; 32]]) -> [u8; 32] { + mth(d) +} + fn mth(d: &[[u8; 32]]) -> [u8; 32] { if d.len() == 1 { return d[0]; @@ -185,6 +193,76 @@ pub fn verify_proof(leaf: [u8; 32], index: u64, path: &[[u8; 32]], c: &OutputCom sn == 0 && r == root } +fn subproof(m: usize, d: &[[u8; 32]], b: bool, out: &mut Vec<[u8; 32]>) { + let n = d.len(); + if m == n { + if !b { + out.push(mth(d)); + } + return; + } + let k = split(n); + if m <= k { + subproof(m, &d[..k], b, out); + out.push(mth(&d[k..])); + } else { + subproof(m - k, &d[k..], false, out); + out.push(mth(&d[..k])); + } +} + +/// The consistency proof (RFC 9162 §2.1.4.1, RFC 6962 §2.1.2's `PROOF(m, D[n])`) that the +/// tree over the first `m` leaf hashes of `d` is a prefix of the tree over all of them: +/// empty when `m` is 0 or `d.len()`. +pub fn consistency_proof(m: usize, d: &[[u8; 32]]) -> Vec<[u8; 32]> { + let mut out = Vec::new(); + if 0 < m && m < d.len() { + subproof(m, d, true, &mut out); + } + out +} + +/// Whether `proof` shows the tree of `first` leaves whose root is `first_root` is a prefix +/// of the tree of `second` leaves whose root is `second_root`, checked as RFC 9162 +/// §2.1.4.2 checks one, with [`node`] for its `HASH(0x01 ‖ …)`. `0 < first < second`; the +/// caller decides the cases RFC 9162 leaves to it (an empty first tree, or equal sizes). +pub fn verify_consistency(first: u64, second: u64, first_root: &[u8; 32], second_root: &[u8; 32], proof: &[[u8; 32]]) -> bool { + if first == 0 || first >= second || proof.is_empty() { + return false; + } + let mut path: Vec<[u8; 32]> = Vec::with_capacity(proof.len() + 1); + if first.is_power_of_two() { + path.push(*first_root); + } + path.extend_from_slice(proof); + let (mut fnn, mut sn) = (first - 1, second - 1); + while fnn & 1 == 1 { + fnn >>= 1; + sn >>= 1; + } + let (mut fr, mut sr) = (path[0], path[0]); + for c in &path[1..] { + if sn == 0 { + return false; + } + if fnn & 1 == 1 || fnn == sn { + fr = node(c, &fr); + sr = node(c, &sr); + if fnn & 1 == 0 { + while fnn & 1 == 0 && fnn != 0 { + fnn >>= 1; + sn >>= 1; + } + } + } else { + sr = node(&sr, c); + } + fnn >>= 1; + sn >>= 1; + } + fr == *first_root && sr == *second_root && sn == 0 +} + #[cfg(test)] mod tests { use super::*; @@ -274,6 +352,38 @@ mod tests { assert!(!verify_proof(leaf(&v[6]), 6, &paths[6], &as8)); } + /// Every prefix of trees of 1 to 33 leaves is proved consistent with the whole, and a + /// flipped bit, a rewritten history or the next tree's root is refused. A proof does + /// not fix the second tree's size, as an audit path does not (Appendix C): the 1-to-3 + /// proof also walks to the 3-leaf root under a stated size of 4, so a commitment states + /// its size and a holder of the leaves recomputes the root under it. + #[test] + fn consistency_proofs_roundtrip() { + let leaves: Vec<[u8; 32]> = (0..34u8).map(|i| sha256(&[b'c', i])).collect(); + let three = tree_hash(&leaves[..3]); + let p13 = consistency_proof(1, &leaves[..3]); + assert!(verify_consistency(1, 4, &leaves[0], &three, &p13), "a proof does not fix the size"); + for n in 2..=33usize { + let d = &leaves[..n]; + let second = tree_hash(d); + let next = tree_hash(&leaves[..n + 1]); + for m in 1..n { + let first = tree_hash(&d[..m]); + let p = consistency_proof(m, d); + assert!(verify_consistency(m as u64, n as u64, &first, &second, &p), "m = {m}, n = {n}"); + assert!(!verify_consistency(m as u64, n as u64 + 1, &first, &next, &p), "m = {m}, n = {n}, next tree"); + let mut bad = p.clone(); + bad[0][7] ^= 0x10; + assert!(!verify_consistency(m as u64, n as u64, &first, &second, &bad), "m = {m}, n = {n}, bit"); + let mut other = d.to_vec(); + other[0][0] ^= 1; + let rewritten = tree_hash(&other); + assert!(!verify_consistency(m as u64, n as u64, &first, &rewritten, &p), "m = {m}, n = {n}, history"); + } + assert!(consistency_proof(0, d).is_empty() && consistency_proof(n, d).is_empty()); + } + } + #[test] fn duplicate_presentation_is_refused() { let mut p = ps(4); diff --git a/wai/wai-rs/tests/capture_take.rs b/wai/wai-rs/tests/capture_take.rs new file mode 100644 index 000000000..5bca6653c --- /dev/null +++ b/wai/wai-rs/tests/capture_take.rs @@ -0,0 +1,77 @@ +//! `wai.capture.take` (extensions/capture-binding.md): the committed corpus +//! `live-conformance/takes/vectors.json` regenerates byte for byte from its fixed seeds, +//! every vector in it gets the outcome it states, every reason the extension adds appears +//! in it, and the extension's §12 lists exactly those reasons. +#![cfg(feature = "capture_take")] + +use std::collections::BTreeSet; +use std::path::PathBuf; +use wai::capture_take::{corpus, Reason, DELIVERY_GAP}; + +fn wai_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} + +fn committed() -> String { + std::fs::read_to_string(wai_dir().join("live-conformance/takes/vectors.json")).expect("the committed corpus") +} + +#[test] +fn the_committed_corpus_regenerates_from_its_seeds() { + assert!(committed() == corpus::generate(), "live-conformance/takes/vectors.json differs from `wai_capture_take_vectors gen`"); +} + +#[test] +fn every_vector_gets_its_stated_outcome() { + let fails = corpus::verify(&committed()); + assert!(fails.is_empty(), "{}", fails.join("\n")); +} + +/// Every reason this extension adds, and `delivery_gap`, is a vector's refusal or one of +/// its verdicts; the three good takes §13 names stand, and `single-take` holds of the +/// missing chunk while `complete` fails. +#[test] +fn the_corpus_covers_every_reason_and_take() { + let doc: serde_json::Value = serde_json::from_str(&committed()).unwrap(); + let vectors = doc["vectors"].as_array().unwrap(); + let mut seen: BTreeSet = BTreeSet::new(); + for v in vectors { + if let Some(r) = v["reason"].as_str() { + seen.insert(r.into()); + } + let verdicts = &v["verdicts"]; + for k in ["single_take", "aligned", "complete"] { + if let Some(r) = verdicts[k].as_str() { + seen.insert(r.into()); + } + } + if let Some(p) = verdicts["publishable"].as_object() { + seen.extend(p.values().filter_map(|r| r.as_str()).map(String::from)); + } + } + for r in Reason::ALL.iter().copied().chain([DELIVERY_GAP]) { + assert!(seen.contains(r.code()), "nothing in the corpus gives {r}"); + } + for name in ["lesson", "resumed_upload", "minor_guardian"] { + let v = vectors.iter().find(|v| v["name"] == name).unwrap_or_else(|| panic!("no vector {name}")); + assert_eq!(v["stands"], true, "{name}"); + } + let missing = vectors.iter().find(|v| v["name"] == "missing_chunk").expect("the missing chunk"); + assert_eq!(missing["verdicts"]["single_take"], "holds"); + assert_eq!(missing["verdicts"]["complete"], "chunk_missing"); +} + +/// §12 of the extension lists exactly the codes `Reason::ALL` has, each once, in order. +#[test] +fn the_extension_lists_the_reasons() { + let text = std::fs::read_to_string(wai_dir().join("extensions/capture-binding.md")).expect("the extension"); + let at = text.find("\n## 12. Reasons").expect("a §12"); + let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e); + let listed: Vec = text[at..end] + .lines() + .filter(|l| l.starts_with("| `")) + .filter_map(|l| l.split('`').nth(1).map(String::from)) + .collect(); + let want: Vec = Reason::ALL.iter().map(|r| r.code().to_string()).collect(); + assert_eq!(listed, want, "§12's table and Reason::ALL differ"); +} diff --git a/wai/wai-rs/tests/int_kernels_vectors.rs b/wai/wai-rs/tests/int_kernels_vectors.rs index 8e3b1a35e..f6f09ea2a 100644 --- a/wai/wai-rs/tests/int_kernels_vectors.rs +++ b/wai/wai-rs/tests/int_kernels_vectors.rs @@ -223,6 +223,7 @@ fn every_decoded_output_states_a_sha256() { ("pin-conformance", "parameter-set pins: every digest there is a SHA-256 of a parameter set"), ("ops-conformance", "integer operators: every operator, stage and graph vector, the lower_* decodes of the sets under sets/ among them, states its output integers in full or its refusal code, never a digest of them; certificates/ states each lowered set's SHA-256 (a parameter-set identity) and holds the lowered graphs as bytes, compared byte for byte; the output digests a capability decoded through its lowering reproduces (integer-operators §14.4) are stated by that capability's own corpus"), ("signer-conformance", "key logs, grants and statuses: signed documents, no decoded output"), + ("live-conformance", "live events, rooms and takes: signed records, commitments and their verdicts, no decoded output"), ("http-conformance", "objects and head proofs for transport: no case decodes a payload, and the component a fetch case picks is stated by its SHA-256"), ("cache-conformance", "cache rules: a driver, its controls and their reports, with no objects of its own"), ("byte-exact-conformance", "goldens over tests/vectors, whose sidecars state the SHA-256"), diff --git a/wai/wai-rs/tests/live_events.rs b/wai/wai-rs/tests/live_events.rs new file mode 100644 index 000000000..aff3f3b1d --- /dev/null +++ b/wai/wai-rs/tests/live_events.rs @@ -0,0 +1,78 @@ +//! `wai.live.events` (extensions/live-events.md): the committed corpus +//! `live-conformance/events/vectors.json` regenerates byte for byte from its fixed seeds, +//! every case in it gets the outcome it states, it covers every kind and every reason, +//! and the extension's §9 lists exactly the reasons the reference reports. +#![cfg(feature = "live_events")] + +use std::collections::BTreeSet; +use std::path::PathBuf; +use wai::live_events::{corpus, kind_name, Reason, KINDS}; + +fn wai_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} + +fn committed() -> String { + std::fs::read_to_string(wai_dir().join("live-conformance/events/vectors.json")).expect("the committed corpus") +} + +#[test] +fn the_committed_corpus_regenerates_from_its_seeds() { + assert!(committed() == corpus::generate(), "live-conformance/events/vectors.json differs from `wai_live_events_vectors gen`"); +} + +#[test] +fn every_case_gets_its_stated_outcome() { + let fails = corpus::verify(&committed()); + assert!(fails.is_empty(), "{}", fails.join("\n")); +} + +/// Every kind has an accepted event, every refusal reason a vector, policy case or binding +/// case refused with it, and the gap outcome a vector. +#[test] +fn the_corpus_covers_every_kind_and_reason() { + let doc: serde_json::Value = serde_json::from_str(&committed()).unwrap(); + let mut kinds = BTreeSet::new(); + let mut reasons = BTreeSet::new(); + for v in doc["vectors"].as_array().unwrap() { + if let Some(r) = v["reason"].as_str() { + reasons.insert(r.to_string()); + } + if v["outcome"] == "accept" { + for e in v["events"].as_array().unwrap() { + let h = e.as_str().unwrap(); + let at = 2 * (4 + 1 + 32 + 32 + 8 + 32 + 8); + let flag = u8::from_str_radix(&h[at..at + 2], 16).unwrap(); + let k = 2 * (4 + 1 + 32 + 32 + 8 + 32 + 8 + 1 + 48 * flag as usize); + kinds.insert(u8::from_str_radix(&h[k..k + 2], 16).unwrap()); + } + } + } + for c in doc["policy_cases"].as_array().unwrap().iter().chain(doc["binding_cases"].as_array().unwrap()) { + if let Some(r) = c["reason"].as_str() { + reasons.insert(r.to_string()); + } + } + for (k, name) in KINDS { + assert!(kinds.contains(&k), "no accepted {name} event"); + } + for r in Reason::ALL { + assert!(reasons.contains(r.code()), "nothing in the corpus is refused with {r}"); + } + assert!(kinds.iter().all(|k| kind_name(*k).is_some())); +} + +/// §9 of the extension lists exactly the codes `Reason` has, each once. +#[test] +fn the_extension_lists_the_reasons() { + let text = std::fs::read_to_string(wai_dir().join("extensions/live-events.md")).expect("the extension"); + let at = text.find("\n## 9. Reasons").expect("a §9"); + let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e); + let listed: Vec = text[at..end] + .lines() + .filter(|l| l.starts_with("| `")) + .filter_map(|l| l.split('`').nth(1).map(String::from)) + .collect(); + let want: Vec = Reason::ALL.iter().map(|r| r.code().to_string()).collect(); + assert_eq!(listed, want, "§9's table and Reason::ALL differ"); +} diff --git a/wai/wai-rs/tests/live_room.rs b/wai/wai-rs/tests/live_room.rs new file mode 100644 index 000000000..07cbdaa25 --- /dev/null +++ b/wai/wai-rs/tests/live_room.rs @@ -0,0 +1,59 @@ +//! `wai.live.room` (extensions/live-rooms.md): the committed corpus +//! `live-conformance/rooms/vectors.json` regenerates byte for byte from its fixed seeds, +//! every vector in it gets the outcome it states, it refuses with every reason the +//! extension adds, and the extension's §11 lists exactly those reasons. +#![cfg(feature = "live_room")] + +use std::collections::BTreeSet; +use std::path::PathBuf; +use wai::live_room::{corpus, Reason}; + +fn wai_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} + +fn committed() -> String { + std::fs::read_to_string(wai_dir().join("live-conformance/rooms/vectors.json")).expect("the committed corpus") +} + +#[test] +fn the_committed_corpus_regenerates_from_its_seeds() { + assert!(committed() == corpus::generate(), "live-conformance/rooms/vectors.json differs from `wai_live_room_vectors gen`"); +} + +#[test] +fn every_vector_gets_its_stated_outcome() { + let fails = corpus::verify(&committed()); + assert!(fails.is_empty(), "{}", fails.join("\n")); +} + +/// Every reason this extension adds has a vector refused with it, and the corpus has the +/// five room shapes §12 names, accepted. +#[test] +fn the_corpus_covers_every_reason_and_room() { + let doc: serde_json::Value = serde_json::from_str(&committed()).unwrap(); + let vectors = doc["vectors"].as_array().unwrap(); + let reasons: BTreeSet<&str> = vectors.iter().filter_map(|v| v["reason"].as_str()).collect(); + for r in Reason::ALL { + assert!(reasons.contains(r.code()), "nothing in the corpus is refused with {r}"); + } + for name in ["lesson", "broadcast", "takeover", "redundant_failover", "promote_viewer"] { + let v = vectors.iter().find(|v| v["name"] == name).unwrap_or_else(|| panic!("no vector {name}")); + assert_eq!(v["outcome"], "accept", "{name}"); + } +} + +/// §11 of the extension lists exactly the codes `Reason::ALL` has, each once, in order. +#[test] +fn the_extension_lists_the_reasons() { + let text = std::fs::read_to_string(wai_dir().join("extensions/live-rooms.md")).expect("the extension"); + let at = text.find("\n## 11. Reasons").expect("a §11"); + let end = text[at + 1..].find("\n## ").map_or(text.len(), |e| at + 1 + e); + let listed: Vec = text[at..end] + .lines() + .filter(|l| l.starts_with("| `")) + .filter_map(|l| l.split('`').nth(1).map(String::from)) + .collect(); + let want: Vec = Reason::ALL.iter().map(|r| r.code().to_string()).collect(); + assert_eq!(listed, want, "§11's table and Reason::ALL differ"); +}