diff --git a/.github/workflows/wai-conformance.yml b/.github/workflows/wai-conformance.yml index f44ff92f7..6b5d3d43b 100644 --- a/.github/workflows/wai-conformance.yml +++ b/.github/workflows/wai-conformance.yml @@ -91,6 +91,10 @@ on: # reports, energy_steering_verify.py reads that table, and the registry's wire # identifiers test reads its sections. - 'wai/extensions/energy-steering.md' + # tests/live_moderation.rs requires this extension's §10 to list the codes the reference + # reports, live_moderation_verify.py reads its §9.5, §9.6 and §10 tables, and the + # registry's wire identifiers test reads its sections. + - 'wai/extensions/live-moderation.md' - 'wai/wai-web/**' # The audio provenance check below reads the corpora above with this tool. - 'wai/tools/wai_audio_provenance_check.py' @@ -758,8 +762,8 @@ jobs: # live-rooms corpus), and capture_take_verify.py (the capture-binding corpus), and # live_compose_verify.py (the live-compose corpus), live_record_verify.py (the # live-recording corpus), timed_text_verify.py (the timed-text corpus), - # live_metering_verify.py (the live-metering corpus), and energy_steering_verify.py (the - # energy-steering corpus). + # live_metering_verify.py (the live-metering corpus), energy_steering_verify.py (the + # energy-steering corpus), and live_moderation_verify.py (the live-moderation 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: @@ -1030,6 +1034,27 @@ jobs: (cd wai-rs && cargo test --no-default-features --features energy_steering --lib energy_steering::) (cd wai-rs && cargo test --no-default-features --features energy_steering --test energy_steering) python3 -I live-conformance/energy_steering_verify.py live-conformance/steering + # wai.live.moderation (extensions/live-moderation.md): the reference module's unit tests + # (policies, statements and notices round-trip and their rules refuse, the export's + # strings and dates, the content types, the states that show an item) and + # tests/live_moderation.rs (every file of the committed corpus, vectors.json and each + # statement-of-reasons export, regenerates byte for byte from its fixed seeds and no + # other file is there, wai-rs gives every room, export and clip its stated outcome, and + # §10 lists exactly the reference's codes, each of which the corpus gives); then the + # corpus's second implementation, live_moderation_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 each clip with live_record_verify.py, writes every export + # byte for byte, reads the extension's category, content-type and reason tables, and + # requires every mutated copy of the corpus to fail; standard library only, run + # isolated (-I). + - name: live moderation · wai-rs and live_moderation_verify.py + working-directory: wai + shell: bash + run: | + set -euo pipefail + (cd wai-rs && cargo test --no-default-features --features live_moderation --lib live_moderation::) + (cd wai-rs && cargo test --no-default-features --features live_moderation --test live_moderation) + python3 -I live-conformance/live_moderation_verify.py live-conformance/moderation # 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 81ec0c096..e72f7db72 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -6,6 +6,55 @@ wire format may change and such changes are recorded here. ## v0.4.0 — current +### `wai.live.moderation`: review policies, signed decisions, and statements of reasons + +- **The extension** ([live-moderation](extensions/live-moderation.md)) registers the record + `wai.live.moderation`. The room authority signs a **review policy**, `WMP1`, chained to the + one it replaces and in effect from a room-clock instant: which event kinds and media are held + for review before delivery (pre) or reviewed after it (post), the reviewers, each one's + deadline and fallback (allow, deny or hold), the trusted flaggers it recognises, the reason + codes with their ground, provision or clause and database category, the territory, and the + redress text. Every policy keeps the room descriptor's review field (live-rooms §3.6). +- **Decisions.** A moderator's verdict is a `decision` event of `wai.live.events`, unchanged, + followed in its chain by a `meta` event carrying the **statement**, `WMS1`: its target (an + event, or a media object such as a recorded chunk named by its leaf), the target's `prev`, + the decision it supersedes, its basis (own initiative, a notice, a complaint, the policy's + fallback), its use of automated means in detection and in the decision, and its ground, + explanation and facts. Decisions on one target form a line by digest; an appeal's outcome + supersedes the decision complained of. The room's clock signs each fallback the policy + applies, at or after the deadline. A decision by a principal without the moderate power is + refused by the room verifier (`kind_not_permitted`). +- **Notices and complaints**, `WMN1`, are signed by whoever submits them: a notice names an + item, its ground and the submitter's statement and contact (Article 16(2)); a complaint + names a decision (Article 20). The contact is never exported. +- **Review and redaction.** Each item's state over time (held, pending, allowed, denied, + redacted, or the fallback at its deadline), what a relay holds and delivers, and what a sink + shows. A restricted item is withheld, never replaced: a gap it leaves in its author's chain + is explained by the moderators' signed statements, walking the chain back through each + withheld event's `prev`; a clip over a redacted chunk keeps its range proof, withholds the + chunk's bytes (`redaction_not_applied` when they are given), and presents the chunk again + once a later decision restores it. A recording package under moderation is specified only. +- **The statement-of-reasons export.** Each restricting decision maps onto one record of the + DSA Transparency Database's statement-of-reasons format (the schema in force from + 1 July 2025, which its documentation calls API v2), written byte for byte: every member, + its source in the WAI records, closed lists and length limits, the sixteen categories, the + content types, and every Article 17 element with WAI's field for it. It carries no + principal key, notice contact or content; `source_identity` is never written. A record that + cannot be written is refused `sor_incomplete`, naming the member. +- **Twenty refusal reasons**, from `policy_malformed` to `redaction_not_applied`. +- **Reference and corpus.** `wai-rs` feature `live_moderation` (`src/live_moderation.rs`); + live-recording's clip verifier gains `verify_clip_exempting`, which `verify_clip` calls + exempting nothing, so its corpus is unchanged. `live-conformance/moderation/`, written from + fixed seeds by `wai_live_moderation_vectors`: a pre-moderated chat room whole and as a + subscriber receives it, a notice and a trusted flagger's notice with their decisions, an + appeal that reverses a decision, live-recording's lesson session with a chunk redacted and + then restored, one refused room per reason, an export refused, and clips of the redacted + take; each export a file of its own. Checked by `tests/live_moderation.rs` and by + `live-conformance/live_moderation_verify.py`, a second implementation that shares no code + with `wai-rs`, verifies each room and clip with its corpora's second implementations, writes + every export itself, and requires every mutated copy of the corpus to fail. The registry + lists the record and the magics `WMP1`, `WMS1` and `WMN1`. + ### wai-quantum-service: every job's energy, signed with its result - **What a result carries.** `energy` holds the CPU energy of the job's worker process, from diff --git a/wai/REGISTRY.md b/wai/REGISTRY.md index a6b6443ef..fc8480310 100644 --- a/wai/REGISTRY.md +++ b/wai/REGISTRY.md @@ -41,7 +41,8 @@ Every registered string has one kind. `wai.asset.provenance`, the quantum-operations receipts, the delivery records `wai.video.manifest` and its siblings; the live records `wai.live.events`, `wai.live.room`, `wai.capture.take`, `wai.live.compose`, `wai.live.recording`, - `wai.live.metering` and `wai.live.steering`; timed text, `wai.text.timed`). + `wai.live.metering`, `wai.live.steering` and `wai.live.moderation`; timed text, + `wai.text.timed`). It names no payload format. A derivation or record string is not a payload capability, so it is not @@ -198,6 +199,7 @@ and a role are fixed once registered. | `wai.live.compose` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.live.events` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.live.metering` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | +| `wai.live.moderation` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.live.recording` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.live.room` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.live.steering` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | @@ -310,7 +312,10 @@ and a role are fixed once registered. | `WHP1` | magic | defined | http-delivery §6.2 | | `WJR1` | magic | defined | jwp-receipts §2.7.3 | | `WMH1` | magic | defined | live-metering §3.1 | +| `WMN1` | magic | defined | live-moderation §5.1 | +| `WMP1` | magic | defined | live-moderation §3.1 | | `WMR1` | magic | defined | live-metering §4.1 | +| `WMS1` | magic | defined | live-moderation §4.2 | | `WRD1` | magic | defined | live-rooms §3.1 | | `WRG1` | magic | defined | live-rooms §4.1 | | `WRM1` | magic | defined | live-recording §4.1 | diff --git a/wai/SPEC.md b/wai/SPEC.md index 98506e639..8fd799a2f 100644 --- a/wai/SPEC.md +++ b/wai/SPEC.md @@ -593,8 +593,8 @@ kind: delivery records `wai.video.manifest`, `wai.video.ssai`, `wai.video.keys`, `wai.video.package` and `wai.video.channel`; and the live records `wai.live.events`, `wai.live.room`, `wai.capture.take`, `wai.live.compose`, `wai.live.recording`, - `wai.live.metering` and `wai.live.steering`, and timed text, `wai.text.timed`), which names - no payload format. + `wai.live.metering`, `wai.live.steering` and `wai.live.moderation`, and timed text, + `wai.text.timed`), 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 @@ -979,6 +979,26 @@ report, its own inputs and the output, which a verifier recomputes. The output i manifest HLS and DASH players already read, written byte for byte, with the decision's URI in one member players ignore: [`extensions/energy-steering.md`](extensions/energy-steering.md). +And for the **moderation** of a room — `wai.live.moderation`: the room authority signs a review +policy, `WMP1`, that keeps the room descriptor's review field and refines it: which event kinds +and media are held for review before delivery or reviewed after it, by which reviewers, each +one's deadline, the fallback at the deadline (allow, deny or hold), the trusted flaggers it +recognises, and the reason codes in use, each with its ground (illegal content, or +incompatible with the terms), the provision or clause it rests on and its category. A +moderator's verdict is a `decision` event of `wai.live.events`, unchanged, followed by a +`WMS1` statement that names its target (an event, or a media object such as a recorded chunk +by its leaf), the decision it supersedes, its basis (own initiative, a notice, a complaint, or +the policy's fallback), its use of automated means, and its ground, explanation and facts. +Decisions on one target form a line by digest, so an appeal's outcome is a decision too; the +room's clock signs each fallback the policy applies. Anyone can sign a notice, `WMN1`, about +an item, and anyone affected a complaint about a decision. A restricted item is withheld, +never replaced: a gap it leaves in its author's chain is explained by the moderators' signed +statements, and a clip over a redacted chunk keeps its range proof and withholds the chunk's +bytes. Each restricting decision maps, byte for byte, onto one statement of reasons in the +format of the database the European Commission keeps under Regulation (EU) 2022/2065 +(Article 24(5)), with no personal data: +[`extensions/live-moderation.md`](extensions/live-moderation.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/live-events.md b/wai/extensions/live-events.md index 1403102d0..177c453ac 100644 --- a/wai/extensions/live-events.md +++ b/wai/extensions/live-events.md @@ -34,7 +34,8 @@ Out of scope: a transport; the room descriptor, which fixes a room's id and its 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. +workflow, which [live-moderation](live-moderation.md) defines; 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 @@ -252,6 +253,8 @@ provenance assertion, takes the label from it. `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. +[Live-moderation](live-moderation.md) defines the statement that follows a decision in its +author's chain, what else a target may name, and how one decision supersedes another. ### 4.12 `take_commit` diff --git a/wai/extensions/live-moderation.md b/wai/extensions/live-moderation.md new file mode 100644 index 000000000..cd4edef41 --- /dev/null +++ b/wai/extensions/live-moderation.md @@ -0,0 +1,842 @@ +# WAI Extension: Live Moderation + +> Status: Draft. Registers the record `wai.live.moderation`: moderation for rooms. The room +> authority signs a **review policy**, `WMP1`: which event kinds and media are held for review +> before delivery or reviewed after it, by whom, the deadline of each, the fallback when no +> decision arrives in time (allow, deny or hold), and the reason codes in use, each with its +> ground. A moderator's verdict is a `decision` event of [live-events](live-events.md) (§4.11 +> there), unchanged, followed by a `meta` event whose payload is this extension's +> **statement**, `WMS1`: what kind of thing the decision targets (an event, or a media object +> such as a recorded chunk), the decision it supersedes, its basis (own initiative, a notice, +> a complaint, or the policy's fallback), whether automated means detected the content or took +> the decision, and its ground, explanation and facts. Decisions on one target form a line by +> digest, so a later decision overrides an earlier one and the outcome of an appeal is a +> decision too. Anyone can submit a signed **notice**, `WMN1`, about an event or an object, and +> anyone affected a **complaint** about a decision. A restricted item is withheld, and where it +> is withheld from a chain, a recording or a clip, its absence is proven by the decisions +> that restrict it. Each restricting decision maps, deterministically, onto one record of the +> statement-of-reasons format of the database the European Commission keeps under Regulation +> (EU) 2022/2065. No new transport. The reference implementation is the `live_moderation` +> module of `wai-rs` (feature `live_moderation`); the corpus is +> [`live-conformance/moderation/`](../live-conformance/moderation/), and its second +> implementation is `live-conformance/live_moderation_verify.py`. +> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174. +> +> Texts read for this revision, each pinned to the version named: +> Regulation (EU) 2022/2065 (OJ L 277, 27.10.2022, p. 1), Articles 16, 17, 20 and 24(5), as the +> Publications Office serves its only consolidated version, 02022R2065-20221027, with no +> amending act recorded and no English corrigendum; the DSA Transparency Database's "API and +> schema" documentation and its explanation of the statement attributes +> (`transparency.dsa.ec.europa.eu`), for the submission schema in force from 1 July 2025, which +> the documentation's changelog calls API v2 and which is still submitted at `/api/v1/statement`, +> as the database's published source has it at revision `fc3b1fd5` (2026-09-23) of the +> documentation and revision `bf0afeb8` (2026-06-09) of the submission's validation rules; and +> Commission Implementing Regulation (EU) 2024/2835, Annex II, whose categories the database +> uses. An article or paragraph number in this text is the Regulation's unless it says +> otherwise. + +## 1. Scope + +In scope: the review policy, its signature, its rules and the policy in effect at each +instant (§3); the decision event as this extension reads it, the statement, who may decide, +lines of decisions and fallback decisions (§4); notices and complaints (§5); the items under +review, their states, and what a relay and a sink do with them (§6); verification, with the +gaps that restricted items leave explained (§7); the effect of a restriction on a stream, a +recording and a clip (§8); and the statement-of-reasons export (§9). + +Out of scope: a transport; how a moderator or a classifier reaches a verdict; how a notice or +a complaint reaches the room authority; the notification of a submitter or an affected +participant (Article 16(5), Article 17(1), Article 20(5)); the submission of a record to the +database, which is an authenticated HTTP request this extension does not define; and the +restriction of accounts, payments or the provision of a service (Article 17(1)(b) to (d)), +which no WAI record expresses. This extension states what the records carry and how they map +onto the database's format. Which decisions a service takes, and which records it submits, is +not its subject. + +Relationship to the core spec: `wai.live.moderation` 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. + +Relationship to [live-events](live-events.md): this extension changes nothing in it. Its +`decision` payload (§4.11 there) holds a verdict, a target digest and a reason code and no +more, so the statement rides in the `meta` kind, which live-events leaves to applications +(§4.2 there), and is bound to its decision by the event chain (§4.2 here), as +[timed-text](timed-text.md)'s annotation is bound to its caption. A decision's target is the +digest of an event, as live-events has it, or, where its statement says so, of a media object +(§4.1). + +Relationship to [live-rooms](live-rooms.md): the room descriptor's `review` field (§3.6 +there) fixes the room's review at its creation; a review policy refines it and never +contradicts it (§3.5). The moderate power (§3.3 there) is the power to decide. + +Relationship to [live-recording](live-recording.md): a restriction changes what a +recording package holds and what a clip presents (§8). A clip's inclusion proof does not +change: it is over the chunks' descriptors, which a restriction leaves in place. + +## 2. Terms + +- **Room**, **room clock**, **principal**, **event**, **chain**, **grant**, **room key**, + **merged order**: as in live-events §2 and live-rooms §2 and §9.2. A room key is the room + authority's key or the clock's. +- **Item**: an event of a decidable kind (§4.1), or a media object (§4.1), that a policy + reviews or a decision targets. +- **Decision**: a `decision` event (live-events §4.11). Its **statement** is the `WMS1` + payload of the `meta` event that follows it in its chain (§4.2). +- **Line** of a target: the decisions on it, the first superseding none and each later one + superseding the one before (§4.5). Its last decision is the **standing** decision. +- **Restricting** verdict: deny or redact. An item whose standing decision restricts it is + **restricted**. +- **Withheld**: not delivered to a subscriber session, not presented by a sink, or, for + redaction, not kept in a recording package (§8). +- **Reviewer**: a principal a policy names to decide on the items it reviews (§3.1). +- **Moderator**: a principal whose grant in effect has the moderate power (live-rooms §3.3), + or a room key. + +Integers are little-endian. A digest is SHA-256 (FIPS 180-4), 32 bytes. Ed25519 is RFC 8032's, +verified strictly (SPEC §7 *Signatures*): a key that fails step 1 or 2 is `bad_key`, and a +signature that fails a later step is `bad_signature`. A *text* field is a u16 length and that +many bytes, which are UTF-8 (RFC 3629): no overlong form, no surrogate, nothing above +U+10FFFF. + +## 3. The review policy + +### 3.1 Layout + +| field | size | meaning | +|---|---|---| +| `magic` | 4 | `WMP1` (ASCII) | +| `version` | 1 | 1 in this revision | +| `room` | 32 | the room id (live-rooms §3.2) | +| `prev` | 32 | the digest of the policy this one replaces (§3.4); 32 zero bytes for the first | +| `effective` | 8 | u64: the room-clock instant from which this policy applies; 0 for the first | +| `reviewers` | 1 + 32 × *n* | a u8 count (0 to 16), then each reviewer's Ed25519 key | +| `flaggers` | 1 + 32 × *n* | a u8 count (0 to 16), then each key the authority recognises as a trusted flagger's (§9.3 `source_type`) | +| `entries` | 1 + 10 × *n* | a u8 count (0 to 32), then each entry: `scope` (u8), `code` (u8), `mode` (u8), `deadline_ms` (u32), `fallback` (u8), `fallback_reason` (u16) | +| `reasons` | 1 + … | a u8 count (1 to 64), then each reason code: `code` (u16), `ground` (u8), `category` (u8), `reference` (text), `url` (text) | +| `territory` | 1 + 2 × *n* | a u8 count (1 to 30), then each state's code (§9.3 `territorial_scope`), two ASCII capitals | +| `redress` | text | how an affected participant can seek redress (§9.4, Article 17(3)(f)) | +| `sig` | 64 | §3.2 | + +An **entry** says how items of one kind are reviewed: + +- `scope` 1: `code` is an event kind (live-events §4), and it must be a decidable kind + (§4.1); `scope` 2: `code` is a media kind (live-rooms §6.1: 1 audio, 2 video, 3 screen), + and the entry reviews every media object of that kind. +- `mode` 1 **pre**: an item is held from delivery until it is decided or its deadline passes; + `mode` 2 **post**: an item is delivered at once and reviewed after. +- `deadline_ms`: how long after the item's `t` a decision is awaited, in milliseconds of + room clock, above 0. +- `fallback`, what applies at the deadline when no decision has come: 1 **allow**, 2 + **deny**, 3 **hold** (the item stays withheld until a decision comes). +- `fallback_reason`: the reason code a fallback that denies or holds applies under; 0 when + `fallback` is allow. + +A **reason code** is one entry of the room's vocabulary: + +- `code`: the value a decision's `reason` (live-events §4.11) carries, above 0; +- `ground`: 1 **illegal content**, 2 **incompatible with the terms** of the service; +- `category`: the database category it maps to, by its number in §9.5; +- `reference`: the legal provision, or the clause of the terms, the code rests on: 1 to 500 + code points; +- `url`: empty, or an `https://` URL where the terms or the provision can be read: `https://` + then bytes of `!` to `~` (0x21–0x7E), at most 500 bytes in all. + +### 3.2 Digest and signature + +The **digest** of a policy is SHA-256 over its record from `magic` through `redress`. The +**signature** is Ed25519 by the room descriptor's `authority` over the 27 bytes +`wai:live-moderation-policy` (ASCII) and 0x01, followed by the bytes the digest covers. + +### 3.3 Reading and rules + +A reader reads exactly the bytes it is given as one policy, 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 `WMP1`: `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 policy to these rules, and refuses one that breaks any of them as +`policy_malformed`: + +- a count is within its range; +- the reviewers are in strictly ascending byte order, and so are the flaggers; +- the entries are in strictly ascending order of (`scope`, `code`), with `scope` 1 or 2, + `code` as `scope` requires, `mode` 1 or 2, `deadline_ms` above 0, `fallback` 1, 2 or 3, + and `fallback_reason` 0 when `fallback` is 1 and a code of `reasons` otherwise; +- the reason codes are in strictly ascending order of `code`, each above 0, with `ground` 1 + or 2, `category` 1 to 16, and `reference` and `url` as §3.1 has them; +- the territory's codes are in strictly ascending order, each one of the thirty of §9.3; +- every text field is UTF-8. + +Then, in the steps of §7.2: its `room` is the room id (`wrong_room`); its signature verifies +(`bad_key`, `bad_signature`); its link (§3.4, `policy_unlinked`); and the room's review field +(§3.5, `policy_conflicts_room`). + +### 3.4 The policy in effect + +A verifier is given a room's policies in a list. The first has `prev` zero and `effective` 0. +Each later one has as `prev` the digest of the one before it in the list, and an `effective` +above that one's. A policy that breaks this is refused `policy_unlinked`. The **policy in +effect** at room-clock instant *t* is the last of the list whose `effective` is at or below +*t*. A room given no policy has none in effect at any instant. + +A policy is replaced, never amended: the authority signs a new one, chained to the old, with +the instant it takes effect. Each item is reviewed under the policy in effect at its `t`, and +each decision is checked against the policy in effect at the decision's `t`. + +### 3.5 The room's review field + +The room descriptor's `review` field (live-rooms §3.6) names the event kinds held for review, +one deadline and one fallback, allow or deny; the room id commits to it, so every principal +that joined the room joined under it. Every policy of the room **MUST** keep it: for each +kind that field names, the policy has an entry of `scope` 1 for that kind, with `mode` 1 +(pre), the field's `deadline_ms` and the field's `fallback`. Otherwise `policy_conflicts_room`. +A policy may add entries for other kinds and for media, and name reviewers, flaggers and the +vocabulary, which the field does not hold. + +## 4. Decisions + +### 4.1 The decision event + +A decision is a `decision` event (live-events §4.11): `verdict` (1 allow, 2 deny, 3 redact), +`target` (32 bytes) and `reason` (u16). Its statement (§4.2) says what `target` names: + +- an **event**: the digest of an event of the room (live-events §3.2), of a **decidable + kind**: `meta` (other than a statement), `cue`, `chat`, `reaction`, `poll_open`, `vote`, + `poll_close`, `marker` or `caption`. A `control`, a `decision`, a `take_commit` and a + lifecycle event are not decided on: an appeal of a decision is a decision that supersedes + it (§4.5), not one that targets it; +- a **media object**: its digest. A chunk of a take is named by its leaf + ([capture-binding](capture-binding.md) §4.2), which binds its index, its capture range, its + length and the digest of its bytes, so the name is the chunk's in its take; any other + object, by the digest its receipt names it with ([jwp-receipts](jwp-receipts.md) §2.1). + +A decision without a statement targets an event, supersedes nothing, and is of the +moderator's own initiative. + +Verdicts: + +- **allow**: the item is shown; +- **deny**: access to the item is disabled: it is withheld from delivery and presentation, + and a recording keeps it, so that a later decision can restore it (§8); +- **redact**: the item is removed: it is withheld as for deny, and a recording does not keep + it (§8.2). + +A restriction lasts until a later decision of its line supersedes it. A restriction for a set +time is a decision and, at the time's end, an allow that supersedes it. + +### 4.2 The statement + +A decision's **statement** is the payload of a `meta` event whose first four bytes are +`WMS1`, by the same principal, at the decision's `seq` + 1 and at the decision's `t`. + +| offset | size | field | meaning | +|---|---|---|---| +| 0 | 4 | `magic` | `WMS1` (ASCII) | +| 4 | 1 | `version` | 1 in this revision | +| 5 | 1 | `target_type` | 1 an event, 2 a media object (§4.1) | +| 6 | 32 | `target_prev` | for an event: the target's `prev` (live-events §3.1), so that a chain withholding it stays linked (§7.3); for an object: 32 zero bytes | +| 38 | 32 | `supersedes` | the digest of the decision event this one supersedes (§4.5); 32 zero bytes for none | +| 70 | 1 | `basis` | 1 the moderator's own initiative, 2 a notice, 3 a complaint, 4 the policy's fallback (§4.6) | +| 71 | 32 | `notice` | for basis 2 and 3: the digest of the notice or complaint it answers (§5); otherwise 32 zero bytes | +| 103 | 1 | `automated` | bit 0: the content was detected or identified by automated means; bits 1 and 2: how far the decision was taken by automated means, 0 not, 1 partially, 2 fully; every other bit 0 | +| 104 | 1 | `ground` | 1 illegal content, 2 incompatible with the terms | +| 105 | text | `ground_ref` | the legal provision or the clause of the terms relied on; empty when the reason code's `reference` is the one | +| … | text | `explanation` | why the item is considered illegal, or incompatible, on that ground | +| … | text | `facts` | the facts and circumstances relied on in taking the decision | + +### 4.3 Reading a statement + +A statement is refused `statement_malformed` when: it ends before a field or holds bytes +after `facts`; its version is not 1; `target_type` is not 1 or 2; `target_type` is 2 and +`target_prev` is not zero; `basis` is not 1 to 4; `notice` is zero for basis 2 or 3, or not +zero for basis 1 or 4; `automated` sets a bit above bit 2, or bits 1 and 2 read 3; `basis` is 4 +and `automated`'s bits 1 and 2 do not read 2, or `supersedes` is not zero; `ground` is not 1 +or 2; or a text field is not UTF-8. + +The `meta` payload is bounded by the principal's policy (live-events §5, `max_payload`), +1024 bytes by default, which bounds the three texts together. + +### 4.4 Who decides + +A decision is the event of a moderator. The room verifier already holds every decision to +it: a grant whose policy permits `decision` has the moderate power (live-rooms §3.3, §4.3 step +5), and a participant's event is verified under its grant in effect at its `t` (live-rooms +§9.2 step 4). A decision by a principal without the moderate power is therefore refused by the +room, `kind_not_permitted`, before this extension reads it. A room key decides as the +authority, without a grant. + +Where the target is an item a policy reviews (§6.1) and the policy in effect at the decision's +`t` names reviewers, the decider is one of them or a room key: otherwise `not_reviewer`. + +### 4.5 Lines: superseding by digest + +The decisions on one target form one line. The first supersedes none; each later decision +names in `supersedes` the line's last decision before it, so that it overrides it from its own +`t`. A verifier checks each decision, in the merged order, against the line as it stands: + +- `supersedes` zero while the target already has a decision: `supersede_gap`; +- `supersedes` naming a decision the verifier does not hold: `supersede_unknown`; +- naming a decision on another target: `supersede_mismatch`; +- naming a decision of this target that is not the line's last (one another decision already + supersedes): `supersede_gap`. + +An **appeal** is a complaint (§5) against a decision, and its outcome is a decision of basis +3 that supersedes the decision complained of and names the complaint. It may reverse that +decision (allow after deny) or confirm it. + +### 4.6 Fallback decisions + +At an item's deadline with no decision, its entry's fallback applies (§6.2) whether or not +any record says so. A room key **SHOULD** sign it, as a **fallback decision** at or after the +deadline: basis 4, `automated` fully, `supersedes` zero, the entry's fallback as its verdict +(1 allow, 2 deny) and the entry's `fallback_reason` as its `reason`. A fallback decision lets a +subscriber that never received the item explain its absence (§7.3), and gives the restriction +a signed record to export (§9). A fallback of hold has no decision: the item waits. + +A fallback decision is refused `fallback_not_in_policy` when: its author is not a room key; +its target is not an item reviewed under an entry whose fallback is allow or deny; or its +verdict is not that fallback, or its `reason` not the entry's `fallback_reason`. It is refused +`fallback_early` when its `t` is before the item's deadline. It supersedes nothing (§4.3), so a +target that already has a decision refuses it by its line (§4.5, `supersede_gap`): a decision +by the deadline forestalls the fallback. + +## 5. Notices and complaints + +### 5.1 Layout + +A **notice** (Article 16) says that an item is illegal content, or incompatible with the +terms; a **complaint** (Article 20) contests a decision. Anyone can sign one with a key of +their own; neither needs a grant of the room. + +| field | size | meaning | +|---|---|---| +| `magic` | 4 | `WMN1` (ASCII) | +| `version` | 1 | 1 in this revision | +| `room` | 32 | the room id | +| `type` | 1 | 1 a notice, 2 a complaint | +| `target_type` | 1 | a notice: 1 an event, 2 a media object (§4.1); a complaint: 1, the decision event complained of | +| `target` | 32 | the target's digest: the exact location of the information (Article 16(2)(b)) | +| `t` | 8 | u64: the room-clock instant at which it was submitted | +| `ground` | 1 | a notice: 1 illegal content, 2 incompatible with the terms; a complaint: 0 | +| `good_faith` | 1 | 1: the submitter confirms its bona fide belief that what it states is accurate and complete (Article 16(2)(d)); 0: it does not | +| `ground_ref` | text | the provision or clause the submitter cites; may be empty | +| `statement` | text | the submitter's explanation of its reasons (Article 16(2)(a)), or of its complaint | +| `contact` | text | the submitter's name and email address (Article 16(2)(c)); may be empty | +| `submitter` | 32 | the Ed25519 key that signs it | +| `sig` | 64 | §5.2 | + +### 5.2 Digest, signature and rules + +The **digest** is SHA-256 over the record from `magic` through `submitter`. The **signature** +is Ed25519 by `submitter` over the 27 bytes `wai:live-moderation-notice` (ASCII) and 0x01, +followed by the bytes the digest covers. + +A reader reads it as §3.3 steps 1 to 3 read a policy, with `WMN1` for `WMP1`, and refuses as +`notice_malformed` one in which: `type` is not 1 or 2; a notice's `target_type` is not 1 or 2, +or its `ground` not 1 or 2; a complaint's `target_type` is not 1 or its `ground` not 0; +`good_faith` is not 0 or 1; a text field is not UTF-8; or whose digest is an earlier notice's +in the list. Then its `room` is the room id (`wrong_room`), and its signature verifies +(`bad_key`, `bad_signature`). + +A decision of basis 2 names a notice (`type` 1) and one of basis 3 a complaint (`type` 2) that +the verifier is given, otherwise `notice_unknown`. A notice's `target` is the decision's +target, and its `target_type` the statement's; a complaint's `target` is the decision the +answering decision supersedes; and its `t` is at or before the decision's `t`. Otherwise +`notice_mismatch`. A complaint may be submitted by anyone the decision affects, the +participant whose item it restricts or the submitter of the notice it answers among them; this +extension does not check who. + +`contact` is personal data. No export carries it (§9.7). + +## 6. Review + +### 6.1 Items + +An **item under review** is: + +- an event the verifier holds, of a decidable kind (§4.1), whose kind an entry of `scope` 1 + of the policy in effect at its `t` names, and whose author is neither a room key nor a + principal whose grant in effect at its `t` has the moderate power; or +- a media object the verifier is given (§7.1), whose media kind an entry of `scope` 2 of the + policy in effect at its `t` names. + +Its entry gives its `mode`, its **deadline**, `t` + `deadline_ms` × 1000, and its fallback. An +item that is not under review but that a decision targets is an item too, with no entry. + +### 6.2 States + +An item's **state** at room-clock instant *x*, from its `t` on, is: + +1. when a decision on it has its `t` at or below *x*: the verdict of the last such decision of + its line, **allowed**, **denied** or **redacted**; +2. otherwise, an item with no entry: **shown**; +3. otherwise, before its deadline: **held** in mode pre, **pending** in mode post; +4. otherwise (at or after the deadline, with no decision): **fallback_allow**, + **fallback_deny** or **fallback_hold**, by its entry's fallback. + +The fallback applies at the deadline unless a decision other than a fallback decision (§4.6) +has its `t` at or below the deadline; a fallback decision records the fallback, and does not +forestall it. + +An item is **visible** in the states shown, pending, allowed and fallback_allow, and withheld +in every other. A decision decides an item from its own `t` whatever came before it, so a +moderator's decision after a fallback overrides the fallback, and an appeal's outcome +overrides the decision it supersedes. A moderator's decision at the deadline itself is a +decision by the deadline, and no fallback applies. + +An item's **timeline** is the sequence of its states from its `t`: one entry at its `t`, one +at its deadline when the fallback applies, and one at each decision on it in the merged order. +The entries are in the order of their instants and, at one instant, in that order (the item's, +the fallback's, the decisions'). Each entry is the instant, the state, the decision's digest +where a decision made it, and whether the state is visible. The item's state at an instant is +that of its last entry at or before it. + +### 6.3 What a relay does + +A relay that delivers a room's tracks under a policy applies it to each subscriber session: + +- An item in state **held** is delivered at once to the reviewers (or, with none named, to + every present principal whose grant in effect has the moderate power) and to the room keys, + and is withheld from every other subscriber session. The relay keeps it until its state + becomes visible, when it delivers it to the sessions it withheld it from, or until a + decision denies or redacts it. The deadline is the longest it waits for a decision before + the fallback applies: at the deadline, under allow it delivers the item; under deny it + withholds it for good unless a later decision allows it; under hold it keeps it until a + decision comes, for as long as the session lasts. +- An item in state **pending** is delivered at once. At the deadline with no decision, under + deny or hold the relay stops delivering it, to a session that joins later or fetches it + again. +- A restricted item is withheld from every session but the reviewers' and the room keys', + and a relay **MUST NOT** deliver an event or object in a withheld state to any other + session, live, in a join set (live-events §8.2) or in answer to a FETCH. +- A relay that withholds an event goes on delivering the events after it in its chain, so a + session sees a gap (live-events §6.2). When the event is delivered later, the session fills + the gap as live-events §6.2 has a receiver fill one: by verifying the chain again from its + start. A withheld event that stays restricted leaves a gap, which the decisions that + restrict it explain (§7.3). +- An event a relay withholds from a session is not delivered to it, and its per-hop record + ([live-metering](live-metering.md) §3.3) does not count it as delivered there. + +A relay that signs fallback decisions (§4.6) does so as the room's clock. + +### 6.4 What a sink shows + +A sink shows an item at instant *x* only when its state at *x* is visible, by the decisions it +holds. Holding a decision's event and statement, it **SHOULD NOT** show what the decision +restricts (live-events §4.11). A sink that holds a decision but not its target shows nothing +of the target, and states the decision's verdict and reason in its place where it shows the +chain. A sink that labels a restriction for a viewer takes the label from the statement and +the reason code's vocabulary entry, never from the target's content. + +## 7. Verification + +### 7.1 Inputs + +A moderation verifier is given what a room verifier is given (live-rooms §9.1: a descriptor, +grants, a key-log head or none, and the chains), and: + +- **policies**: the room's review policies, in a list (§3.4); +- **notices**: notices and complaints, in a list (§5); +- **objects**: the media objects under moderation, each its digest, its media kind (1 audio, 2 + video, 3 screen) and its `t`, the room-clock instant it reached the relay. For a take's + chunks, the digest is the chunk's leaf and the `t` that of the commitment that adds it + (capture-binding §5). The objects are the caller's statement, as the policies a + live-events verifier is given are; no two have one digest. + +### 7.2 Steps + +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 moderation verifier's, at `room` with the + room verifier's own place. A gap is not a refusal: the steps go on, and §7.3 says which + gaps decisions explain. +2. **The policies**, in the list's order (§3.3, §3.4, §3.5): the refusal, at the policy's + index. +3. **The notices**, in the list's order (§5.2): the refusal, at the notice's index. +4. **The statements.** For each `meta` event the room accepted whose payload begins with + `WMS1`, in the merged order: when its `seq` is 0, `statement_misplaced`; when the verifier + holds its principal's event at `seq` − 1, that is a decision at the same `t`, otherwise + `statement_misplaced`; when the verifier does not, the statement is an orphan of a delivery + gap, and is read no further. A statement in place reads (§4.3), otherwise + `statement_malformed`. At the statement's record. +5. **The gaps** (§7.3): which gaps restricted items explain. No refusal. +6. **The decisions**, in the merged order, each by §7.4: the refusal, at the decision's + record. +7. **The outcome** (§7.5). + +A **gap remains** when the room has a gap that §7.3 does not explain. With a gap remaining, a +check of §7.4 that fails because the verifier does not hold a decision, an event or a +statement is **unresolved**, which is not a refusal; with none, it is the refusal the check +names. + +### 7.3 Explained gaps + +A gap of principal *P*, seqs *a* to *b* (live-events §6.2), is **explained** when the +verifier holds *P*'s event at *b* + 1, and walking back from it reaches *P*'s event at *a* − 1 +(or the start of the chain, when *a* is 0) through restricted events only: + +1. *D* is the `prev` of the event at *b* + 1. +2. For each *s* from *b* down to *a*: of the decisions the room accepted whose target is *D*, + the last in the merged order has a statement of `target_type` 1 and a restricting verdict, + otherwise the gap is not explained; seq *s* is withheld by that decision, and *D* becomes + its statement's `target_prev`. +3. *D* is then the digest of the event at *a* − 1, or 32 zero bytes when *a* is 0; otherwise + the gap is not explained. + +Each step is checked from what the verifier holds: the link from the gap to the event after +it is the event's own `prev`, and each link inside the gap is a moderator's signed statement +about an event it decided on, so no event is passed off as withheld that its chain does not +hold at that place. An explained gap is not a delivery gap. A gap that is not explained stays +one, with live-events' code `delivery_gap`. + +The events an explained gap withholds are **withheld targets**: the verifier knows their +digests and their places, not their kinds or their times. + +### 7.4 Each decision + +For a decision *E* of principal *P*, with target *X*, in the merged order, its statement being +*P*'s event at `seq` + 1 when that is a statement in place (step 4), **unknown** when the +verifier does not hold that seq because a gap remains there, and **none** otherwise: + +1. **The reason.** A policy is in effect at *E*'s `t`, its vocabulary has *E*'s `reason`, and + a known statement's `ground` is that code's: otherwise `reason_not_in_policy`. +2. **The target.** + - Of type 2: an object the verifier is given has digest *X* and a `t` at or below *E*'s: + otherwise `target_unknown`. + - Of type 1 (or with no statement): when *X* is the digest of an event the room accepted, + that event comes before *E* in the merged order, otherwise `target_unknown`; it is of a + decidable kind, otherwise `target_not_decidable`; and a known statement's `target_prev` + is its `prev`, otherwise `target_prev_mismatch`. When *X* is a withheld target (§7.3), + these hold. Otherwise `target_unknown`, unresolved while a gap remains. +3. **The reviewer** (§4.4): `not_reviewer`. Not made for a withheld target. +4. **The line** (§4.5): `supersede_gap`, `supersede_unknown` (unresolved while a gap remains) + or `supersede_mismatch`. Not made for an unknown statement; with none, `supersedes` is + zero. +5. **The basis**, for a known statement: of basis 2 or 3, §5.2 (`notice_unknown`, + `notice_mismatch`); of basis 4, §4.6 (`fallback_not_in_policy`, `fallback_early`), its + entry's checks not made for a withheld target. + +*E* then becomes the last decision of *X*'s line. + +### 7.5 Outcomes and what a verification states + +- **refuse**: the reason and where (§7.2). +- **gap**: no refusal, and a gap remains: the gaps that remain, under the code `delivery_gap`, + and what **accept** states, computed from what the verifier holds. +- **accept**: no refusal and no gap remaining. + +With accept or gap, the verifier states: + +- the room's own outcome (live-rooms §9.4), accept or gap; +- each explained gap: its principal, its seqs, and the decision withholding each seq; +- each decision, in the merged order: its digest, its decider, its `t`, its target and target + type, its verdict, reason and basis (none for an unknown statement), what it supersedes, the + notice it answers, whether its statement is known, none or unknown, and whether it stands at + the end; +- each item, events in the merged order and then objects in the order given: its digest, its + kind or media, its `t`, its entry (mode, deadline, fallback) or none, and its timeline + (§6.2); +- each decision's export (§9): the record, none for an allow, or the refusal. + +## 8. Redaction in streams, recordings and clips + +A restricted item is **withheld**, never replaced, and its absence is **proven**: whatever +held it shows where it was, and the decision that restricts it shows why. A WAI chain, a take +tree and a clip all bind their contents by digest, so an item cannot be swapped for a +stand-in without breaking them; withholding keeps them whole, because each of them names the +item without holding it. + +### 8.1 Streams + +An event withheld from a subscriber session leaves a gap in its author's chain, and the +decisions that restrict it explain the gap (§7.3): the session knows the event existed, where, +under which decision and why, and holds nothing of it. A media object withheld from a session +is an object the relay does not forward. A restricted object's receipts, which name it by its +digest, stay where they are. + +### 8.2 A recording package + +A recording sealed after a decision applies it to what it keeps: + +- A **redacted** chunk's file is left out of its take component, and a redacted event's + record out of its principal's chain file. The take's manifest still lists the chunk's + descriptor, and the next event of the chain still names the redacted one in its `prev`. +- A **denied** item is kept, so that a later decision can allow it; every presentation of + the recording (a clip, a playlist, a sink) withholds it. + +The recording verifier ([live-recording](live-recording.md) §4.4) then finds the take's chunk +missing and the chain's gap, and fails `complete` with `chunk_missing` or `delivery_gap`. A +moderation verifier explains them: a chunk the manifest lists, with no file, whose leaf a +standing redaction names, and a gap §7.3 explains with redactions alone. Where every missing +chunk and every gap is so explained, the recording is complete but for what was redacted. + +What this revision implements of this section: nothing beyond §7.3 and §8.3. The reference +explains gaps in a room's chains and verifies clips; it does not verify a package under +moderation, and the corpus has no package vector. + +### 8.3 Clips + +A clip's chunks are proved against a commitment the device made while it captured, by a range +proof over their descriptors (live-recording §5.3). A restriction leaves the descriptors in +place, so the proof still verifies over every chunk the clip covers; what changes is which +chunks' bytes the clip presents. A chunk is **restricted** when its leaf is the target of a +standing decision that restricts it. + +A **clip under moderation** is verified by live-recording §5.4 with two changes: + +1. In step (k), a restricted chunk is passed over: its bytes are neither required nor checked, + and bytes given for it are not presented. The part presents the bytes of its other chunks, + in order, less `trim_in` when its first chunk is not restricted and `trim_out` when its last + is not. +2. Then, after every part: a restricted chunk whose bytes are given is + `redaction_not_applied`, at the first such chunk. + +A clip that passes is accepted, and states what live-recording §5.4 states, and for each part +the indexes of its restricted chunks, each with the decision that restricts it. A clip whose +restricted chunk is restored by a later allow presents it again, and is refused +`clip_chunk_missing` when its bytes are not given. A clip's inclusion proof thus verifies in +every case, and a clip fails only with a stated reason: one of live-recording §9's, or +`redaction_not_applied`. + +## 9. The statement-of-reasons export + +### 9.1 The format and its version + +A restricting decision maps onto one **statement of reasons** in the form the DSA Transparency +Database accepts at its single-statement endpoint (`POST /api/v1/statement`): the submission +schema in force from 1 July 2025, which the database's documentation calls API v2, read at the +revisions named at the head of this text. The export is the request body. An allow restricts +nothing, and has no export. + +### 9.2 The record + +The record is one JSON object (RFC 8259) whose members are those of §9.3 that apply, in the +order of §9.3, written with no whitespace. Each string is UTF-8, written with `"` as `\"`, +`\` as `\\`, U+0008, U+0009, U+000A, U+000C and U+000D as `\b`, `\t`, `\n`, `\f` and `\r`, any +other code point below U+0020 as `\u` and four lowercase hexadecimal digits, and every other +code point as itself. There is no byte after the closing brace. A date is `YYYY-MM-DD`, the UTC +date of the instant `t0` + `t` of the room clock, `t0` the descriptor's. + +### 9.3 Members and their sources + +"Closed" marks a member whose value is one of a list the database fixes; "free" a text the +database accepts up to the length given, in characters (code points). + +| member | value | source | form | +|---|---|---|---| +| `decision_visibility` | `["DECISION_VISIBILITY_CONTENT_DISABLED"]` for deny, `["DECISION_VISIBILITY_CONTENT_REMOVED"]` for redact | the decision's `verdict` | closed, an array | +| `decision_facts` | the statement's `facts` | statement | free, 1 to 5000 | +| `decision_ground` | `DECISION_GROUND_ILLEGAL_CONTENT` (1) or `DECISION_GROUND_INCOMPATIBLE_CONTENT` (2) | statement `ground` | closed | +| `decision_ground_reference_url` | the reason code's `url`, only when it is not empty | policy | a URL, up to 500 | +| `illegal_content_legal_ground` | ground 1 only: the statement's `ground_ref`, or the reason code's `reference` when that is empty | statement, policy | free, 1 to 500 | +| `illegal_content_explanation` | ground 1 only: the statement's `explanation` | statement | free, 1 to 2000 | +| `incompatible_content_ground` | ground 2 only: as `illegal_content_legal_ground` | statement, policy | free, 1 to 500 | +| `incompatible_content_explanation` | ground 2 only: as `illegal_content_explanation` | statement | free, 1 to 2000 | +| `content_type` | a one-element array, by the target (§9.6) | the target's kind or media | closed, an array | +| `content_type_other` | only with `CONTENT_TYPE_OTHER`: §9.6's text | the target's kind | free, up to 500 | +| `category` | the reason code's `category`, by §9.5 | policy | closed | +| `territorial_scope` | the policy's `territory`, in its order | policy | closed, an array of the thirty codes `AT`, `BE`, `BG`, `CY`, `CZ`, `DE`, `DK`, `EE`, `ES`, `FI`, `FR`, `GR`, `HR`, `HU`, `IE`, `IS`, `IT`, `LI`, `LT`, `LU`, `LV`, `MT`, `NL`, `NO`, `PL`, `PT`, `RO`, `SE`, `SI`, `SK` | +| `content_date` | the date of the target's `t` (an event's, or an object's as given), from 2000-01-01 to 2038-01-01 | the target | a date | +| `application_date` | the date of the decision's `t`, from 2020-01-01 to 2038-01-01 | the decision | a date | +| `source_type` | basis 1 and 4: `SOURCE_VOLUNTARY`; basis 2: `SOURCE_TRUSTED_FLAGGER` when the notice's ground is 1 and its submitter is one of the policy's `flaggers`, `SOURCE_ARTICLE_16` when its ground is 1 and it is not, `SOURCE_TYPE_OTHER_NOTIFICATION` when its ground is 2; basis 3: the `source_type` of the decision it supersedes | statement, notice, policy | closed | +| `automated_detection` | `Yes` when `automated` bit 0 is set, `No` otherwise | statement | closed | +| `automated_decision` | `AUTOMATED_DECISION_NOT_AUTOMATED` (0), `AUTOMATED_DECISION_PARTIALLY` (1) or `AUTOMATED_DECISION_FULLY` (2), by `automated` bits 1 and 2 | statement | closed | +| `puid` | the decision's digest, 64 lowercase hexadecimal digits | the decision | `[a-zA-Z0-9-_]`, up to 500, unique | + +The policy is the one in effect at the decision's `t`. A notice of ground 2 is not a notice +under Article 16, and the database's documentation names `SOURCE_TYPE_OTHER_NOTIFICATION` for +it. A decision on a complaint keeps the source of the restriction it answers. The database's +other members are not written: `decision_monetary`, `decision_provision` and +`decision_account` (no WAI decision restricts payments, the service or an account), their +`_other` texts, `decision_visibility_other`, `account_type`, +`incompatible_content_illegal`, `category_addition`, `category_specification` and +`category_specification_other`, `content_id` (a product number), `content_language`, every +`end_date_*` (a restriction lasts until a decision supersedes it, which the database reads as +indefinite when the date is left out), and `source_identity` (§9.7). + +### 9.4 Article 17, element by element + +| Article 17 | what it asks for | WAI's field | the member | +|---|---|---|---| +| (1)(a) | a restriction of the visibility of specific items | `verdict` deny or redact | `decision_visibility` | +| (1)(b)–(d) | payments, the service, the account | none | not written | +| (3)(a) | removal, disabling, demotion or restriction; territorial scope; duration | `verdict`; policy `territory`; the line (a restriction lasts until superseded) | `decision_visibility`; `territorial_scope`; no end date | +| (3)(b) | facts and circumstances; whether on a notice or on own initiative; the notifier's identity where strictly necessary | statement `facts`; `basis` and the notice; none | `decision_facts`; `source_type`; not written | +| (3)(c) | use of automated means, in the decision and in detection | statement `automated` | `automated_decision`, `automated_detection` | +| (3)(d) | for illegal content: the legal ground and why the item is illegal on it | statement `ground` 1, `ground_ref` or the code's `reference`, `explanation` | `decision_ground`, `illegal_content_legal_ground`, `illegal_content_explanation` | +| (3)(e) | for incompatibility: the contractual ground and why the item is incompatible with it | statement `ground` 2, `ground_ref` or the code's `reference`, `explanation`; the code's `url` | `decision_ground`, `incompatible_content_ground`, `incompatible_content_explanation`, `decision_ground_reference_url` | +| (3)(f) | the possibilities for redress | policy `redress`; a complaint (§5) and its decision (§4.5) | none: the database has no member for it; it is the statement to the affected participant's | +| the category of the decision | (the database's, from Implementing Regulation (EU) 2024/2835 Annex II) | the reason code's `category` | `category` | +| the item's kind and date | (the database's) | the target | `content_type`, `content_date` | +| the decision's date and identifier | (the database's) | the decision's `t` and digest | `application_date`, `puid` | + +### 9.5 Categories + +| number | `category` | +|---|---| +| 1 | `STATEMENT_CATEGORY_ANIMAL_WELFARE` | +| 2 | `STATEMENT_CATEGORY_CONSUMER_INFORMATION` | +| 3 | `STATEMENT_CATEGORY_CYBER_VIOLENCE` | +| 4 | `STATEMENT_CATEGORY_CYBER_VIOLENCE_AGAINST_WOMEN` | +| 5 | `STATEMENT_CATEGORY_DATA_PROTECTION_AND_PRIVACY_VIOLATIONS` | +| 6 | `STATEMENT_CATEGORY_ILLEGAL_OR_HARMFUL_SPEECH` | +| 7 | `STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS` | +| 8 | `STATEMENT_CATEGORY_NEGATIVE_EFFECTS_ON_CIVIC_DISCOURSE_OR_ELECTIONS` | +| 9 | `STATEMENT_CATEGORY_NOT_SPECIFIED_NOTICE` | +| 10 | `STATEMENT_CATEGORY_OTHER_VIOLATION_TC` | +| 11 | `STATEMENT_CATEGORY_PROTECTION_OF_MINORS` | +| 12 | `STATEMENT_CATEGORY_RISK_FOR_PUBLIC_SECURITY` | +| 13 | `STATEMENT_CATEGORY_SCAMS_AND_FRAUD` | +| 14 | `STATEMENT_CATEGORY_SELF_HARM` | +| 15 | `STATEMENT_CATEGORY_UNSAFE_AND_PROHIBITED_PRODUCTS` | +| 16 | `STATEMENT_CATEGORY_VIOLENCE` | + +These are the sixteen values the database accepts in this version, in its order. Category 9 +is for a notice that does not specify the kind of illegal content (Implementing Regulation +(EU) 2024/2835, Annex II). + +### 9.6 Content types + +| target | `content_type` | `content_type_other` | +|---|---|---| +| `chat`, `caption`, `poll_open`, `marker` | `CONTENT_TYPE_TEXT` | | +| `reaction` | `CONTENT_TYPE_OTHER` | `reaction` | +| `vote` | `CONTENT_TYPE_OTHER` | `poll vote` | +| `poll_close` | `CONTENT_TYPE_OTHER` | `poll tally` | +| `meta` | `CONTENT_TYPE_OTHER` | `timed metadata` | +| `cue` | `CONTENT_TYPE_OTHER` | `cue` | +| an object of media 1 (audio) | `CONTENT_TYPE_AUDIO` | | +| an object of media 2 (video) or 3 (screen) | `CONTENT_TYPE_VIDEO` | | + +### 9.7 Personal data + +Article 24(5) has the information submitted to the database contain no personal data. The +export writes nothing from a principal's key, a notice's or a complaint's `contact`, +`statement` or `submitter`, or the content of the item: its members come from the decision's +verdict, `t` and digest, the target's kind and `t`, the policy's vocabulary and territory, and +the statement's three texts. It never writes `source_identity`, which the database +documentation reserves for the notifier's identity where strictly necessary. The statement's +texts are copied as their author wrote them; whether they hold personal data is a question +about their content that no verifier can answer, and they are written knowing that they are +published. + +### 9.8 When no record can be written + +The record is written from the members in the order of §9.3. The first member that cannot be +written as §9.3 has it names the refusal, `sor_incomplete`, stated with that member's name: + +- the decision has no statement, or an unknown one: `decision_facts` (and every member drawn + from the statement after it); +- a text that is empty, or longer than the member allows: that member; +- the target is a withheld target or an unresolved one, so its kind and `t` are not held: + `content_type`; +- a date outside the range the member allows: that member; +- a decision of basis 3 whose superseded decision's source cannot be written: `source_type`. + +## 10. Reasons + +The codes this extension adds, each with where it is raised: + +| reason | raised at | +|---|---| +| `policy_malformed` | §3.3 | +| `policy_unlinked` | §3.4 | +| `policy_conflicts_room` | §3.5 | +| `notice_malformed` | §5.2 | +| `statement_misplaced` | §7.2 step 4 | +| `statement_malformed` | §4.3, §7.2 step 4 | +| `reason_not_in_policy` | §7.4 step 1 | +| `target_unknown` | §7.4 step 2 | +| `target_not_decidable` | §4.1, §7.4 step 2 | +| `target_prev_mismatch` | §7.4 step 2 | +| `not_reviewer` | §4.4, §7.4 step 3 | +| `supersede_gap` | §4.5, §7.4 step 4 | +| `supersede_unknown` | §4.5, §7.4 step 4 | +| `supersede_mismatch` | §4.5, §7.4 step 4 | +| `notice_unknown` | §5.2, §7.4 step 5 | +| `notice_mismatch` | §5.2, §7.4 step 5 | +| `fallback_not_in_policy` | §4.6, §7.4 step 5 | +| `fallback_early` | §4.6, §7.4 step 5 | +| `sor_incomplete` | §9.8, with the member | +| `redaction_not_applied` | §8.3 | + +A moderation verifier also raises every code a room verifier raises (live-rooms §11 and the +live-events codes it lists), at the room: `kind_not_permitted` among them for a decision by a +principal without the moderate power (§4.4); `truncated`, `malformed` and `unknown_version` +for a policy or a notice that does not read; `wrong_room`, `bad_key` and `bad_signature` for a +policy or a notice of another room or whose signature fails; and `delivery_gap` for a gap that +remains, which is not a refusal. A clip under moderation raises every code a clip verifier +raises (live-recording §9), and `redaction_not_applied`. + +## 11. Conformance + +[`live-conformance/moderation/`](../live-conformance/moderation/) holds the corpus, written +from fixed seeds by `wai_live_moderation_vectors gen`: `vectors.json`, and each export as a +file of its own, `NAME.dK.sor.json`, *K* the decision's position among the vector's +decisions. It has: + +- **Rooms**, each a room (descriptor, grants, key-log head or none, chains), its policies, + notices and objects, and the outcome §7.5 gives them with everything it states: + - a chat room under a pre-moderation policy, replaced partway by a second policy that also + reviews reactions after delivery: one message allowed before its deadline, one denied, one + past its deadline taking the fallback, which the clock signs; a reaction reviewed after + delivery whose fallback holds it; + - the same room as a subscriber that is not a reviewer receives it, the denied message and + the fallback's withheld, the gap they leave explained by the decisions; + - a notice and its decision, and a trusted flagger's notice and its redaction; + - an appeal: a complaint against a decision taken with automated means, and the decision + that reverses it; + - a room whose recorded take has a chunk redacted, and the same room after an appeal + restores it; + - one refused room for each reason of §10 a room raises, each a control of one defect, and a + decision by a principal without the moderate power, which the room refuses + `kind_not_permitted`; + - a room with a gap that no decision explains. +- **Exports**: every decision's record, byte for byte, none for an allow, and one refused + `sor_incomplete`. +- **Clips** under moderation over the redacted take: one that withholds the redacted chunk, + one cut by bytes whose first chunk is the redacted one, one that presents the redacted + chunk's bytes (`redaction_not_applied`), and, after the appeal, one that leaves the restored + chunk out (`clip_chunk_missing`) and one that presents it. + +A conforming verifier gives every room, export and clip the outcome, the reason, the place and +everything else the corpus states. `wai_live_moderation_vectors verify` and the test +`tests/live_moderation.rs` check that every file regenerates byte for byte, that `wai-rs` gives +every case its outcome, that every reason of §10 appears, and that §10 lists exactly the +reference's codes. `live-conformance/live_moderation_verify.py` is the second implementation, +written from this text: it shares no code with `wai-rs`; it verifies each room with the +live-rooms corpus's second implementation (`live_rooms_verify.py`), each clip with the +live-recording corpus's (`live_record_verify.py`), and every signature with WAI's strict rule +(`claim-conformance/_ed25519.py`); it writes every export from §9 and requires its bytes; and +it mutates copies of the corpus and requires every copy to fail. + +## 12. Security and privacy considerations + +- Every decision is signed by its moderator, every statement rides in the moderator's chain, + every policy is signed by the room authority, and every notice by its submitter. A relay can + withhold any of them but alter none, and a withheld decision is a gap in its moderator's + chain. +- A relay holds the power to withhold. A subscriber checks it: an event withheld with no + restricting decision behind it is a delivery gap that §7.3 does not explain, which the + subscriber sees and can report. A relay that delivers a restricted item to a session is + caught by the decision the session also holds. +- Explaining a gap needs each restricted event's `prev`, which its moderator states. A + moderator that states a false one makes the gap unexplained, never a forged event accepted: + the chain still has to reach the event before the gap. +- Withholding is not erasure. A denied item stays in the recording, and a redacted one stays + wherever a copy was delivered before the decision; a redaction stops what WAI's relays, + recordings and clips deliver from then on. +- A decision names its target by digest only, and its statement holds no content. A notice + holds its submitter's contact, which is personal data: a verifier is given notices to check + decisions against them, and no export or derived record carries a notice's texts or its key. +- The statement's texts are published with the decision and with its export. Whoever writes + them writes them for a public record. +- Fallback decisions are signed by the room's clock key, which is the relay's; a policy limits + them to the fallback it names, at or after the deadline it names, so a relay cannot restrict + an item for a reason the policy does not hold. +- The `automated` field is its moderator's statement. Nothing in a record shows how a verdict + was reached; the field states it, and an export carries it. diff --git a/wai/extensions/live-recording.md b/wai/extensions/live-recording.md index 8932d8f48..b9a892b53 100644 --- a/wai/extensions/live-recording.md +++ b/wai/extensions/live-recording.md @@ -475,6 +475,9 @@ take's offset *o*, its span, the window on its device's clock (§6.1), the lengt of the bytes it presents, and its FETCH address (§8). Where the take's `single-take` holds, an accepted clip's descriptors are its manifest's at those indexes, since rule 5 binds the manifest's chunks to every commitment's root; the clip verifier does not need the manifest. +A clip over chunks a moderation decision restricts is verified as +[live-moderation](live-moderation.md) §8.3 has it: step (k) passes over the restricted +chunks, whose descriptors the proof still covers. ### 5.5 Cutting a clip diff --git a/wai/extensions/live-rooms.md b/wai/extensions/live-rooms.md index cbf12b2ab..1c5244afa 100644 --- a/wai/extensions/live-rooms.md +++ b/wai/extensions/live-rooms.md @@ -34,7 +34,8 @@ of possession every binding requires (§10). Out of scope: a transport; how a principal obtains a grant; composition, which reads the grant's attributes ([live-compose](live-compose.md)); the review workflow, of which this extension -fixes only the policy's fields and their meaning (§3.6); and what a recording holds, +fixes only the policy's fields and their meaning (§3.6), and which +[live-moderation](live-moderation.md) defines; 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. @@ -165,8 +166,8 @@ a `decision` on it (live-events §4.11), or once `deadline_ms` milliseconds of r 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. +policy's fields and their meaning; the review workflow and its verification are +[live-moderation](live-moderation.md)'s, whose review policy keeps this field (§3.5 there). ### 3.7 The recording policy diff --git a/wai/live-conformance/README.md b/wai/live-conformance/README.md index b9d82f77b..5945c4943 100644 --- a/wai/live-conformance/README.md +++ b/wai/live-conformance/README.md @@ -13,15 +13,17 @@ and the independent verifier of each, beside it. | [`captions/`](captions/) | [timed-text](../extensions/timed-text.md) (`wai.text.timed`) | `timed_text_verify.py` | | [`metering/`](metering/) | [live-metering](../extensions/live-metering.md) (`wai.live.metering`) | `live_metering_verify.py` | | [`steering/`](steering/) | [energy-steering](../extensions/energy-steering.md) (`wai.live.steering`) | `energy_steering_verify.py` | +| [`moderation/`](moderation/) | [live-moderation](../extensions/live-moderation.md) (`wai.live.moderation`) | `live_moderation_verify.py` | **Provenance.** Generated here: `wai_live_events_vectors gen` writes `events/`, `wai_live_room_vectors gen` writes `rooms/`, `wai_capture_take_vectors gen` writes `takes/`, `wai_live_compose_vectors gen` writes `compose/`, `wai_live_record_vectors gen` writes `recordings/`, `wai_timed_text_vectors gen` writes `captions/` and -`wai_live_metering_vectors gen` writes `metering/` and `wai_energy_steering_vectors gen` writes -`steering/`, each from records authored in code, from fixed seeds (`events/README.md`, -`rooms/README.md`, `takes/README.md`, `compose/README.md`, `recordings/README.md`, -`captions/README.md`, `metering/README.md`, `steering/README.md`). One recorded record: +`wai_live_metering_vectors gen` writes `metering/`, `wai_energy_steering_vectors gen` writes +`steering/` and `wai_live_moderation_vectors gen` writes `moderation/`, each from records +authored in code, from fixed seeds (`events/README.md`, `rooms/README.md`, `takes/README.md`, +`compose/README.md`, `recordings/README.md`, `captions/README.md`, `metering/README.md`, +`steering/README.md`, `moderation/README.md`). One recorded record: `metering/relay-record.wmh` and its ledger, which the reference relay signed in its test. Each verifier is written from its extension's text, shares no code with `wai-rs`, and is @@ -36,4 +38,5 @@ python3 live_record_verify.py recordings python3 timed_text_verify.py captions python3 live_metering_verify.py metering python3 energy_steering_verify.py steering +python3 live_moderation_verify.py moderation ``` diff --git a/wai/live-conformance/live_moderation_verify.py b/wai/live-conformance/live_moderation_verify.py new file mode 100644 index 000000000..68938cd9a --- /dev/null +++ b/wai/live-conformance/live_moderation_verify.py @@ -0,0 +1,810 @@ +#!/usr/bin/env python3 +"""Independent verifier of the live-moderation corpus (extensions/live-moderation.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. Each room +is verified by the live-rooms corpus's own second implementation, live_rooms_verify.py +(live-rooms §9), and each clip by the live-recording corpus's, live_record_verify.py +(live-recording §5.4), each written from its text alone. Everything else is here: + +- the review policy (§3): its layout, rules, signature, chain and the room's review field; +- the statement (§4.2, §4.3), lines of decisions (§4.5) and fallback decisions (§4.6); +- notices and complaints (§5); +- items under review and their timelines (§6); +- verification, with the gaps restricted events leave explained (§7); +- clips under moderation (§8.3); +- the statement-of-reasons export (§9), written byte for byte from §9.2 and §9.3, with the + categories and content types of §9.5 and §9.6 read from the extension's own tables. + +For every room it requires the outcome, reason and place, and everything else the corpus +states; every export file, byte for byte; for every clip, its outcome; of the corpus, that +every reason of §10 appears in it and that no other file is there. Then it mutates copies of the +corpus, one defect each, and requires every copy to fail. + + python3 live_moderation_verify.py + +Exit status 0 only if every case verifies and every mutated copy fails. Python 3.8 or later; +standard library only. +""" + +import copy +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, 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 live_record_verify as LREC # noqa: E402 +import _ed25519 as ED # noqa: E402 + +Refuse = LEV.Refuse +EXTENSION = os.path.join(HERE, "..", "extensions", "live-moderation.md") + +POLICY_MAGIC, STATEMENT_MAGIC, NOTICE_MAGIC = b"WMP1", b"WMS1", b"WMN1" +POLICY_DOMAIN = b"wai:live-moderation-policy\x01" +NOTICE_DOMAIN = b"wai:live-moderation-notice\x01" +ZERO = bytes(32) +META, CUE, CHAT, REACTION, POLL_OPEN, VOTE, POLL_CLOSE, MARKER, CAPTION, DECISION = 1, 2, 3, 4, 5, 6, 7, 8, 0x0A, 0x0B +DECIDABLE = {META, CUE, CHAT, REACTION, POLL_OPEN, VOTE, POLL_CLOSE, MARKER, CAPTION} # §4.1 +MODERATE = 1 # live-rooms §3.3 +ALLOW, DENY, REDACT = 1, 2, 3 +EVENT, OBJECT = 1, 2 +OWN, NOTICE, COMPLAINT, FALLBACK = 1, 2, 3, 4 +ILLEGAL, INCOMPATIBLE = 1, 2 +PRE, POST = 1, 2 +F_ALLOW, F_DENY, F_HOLD = 1, 2, 3 +VERDICTS = {1: "allow", 2: "deny", 3: "redact"} +BASES = {1: "own", 2: "notice", 3: "complaint", 4: "fallback"} +MEDIA = {1: "audio", 2: "video", 3: "screen"} +TERRITORY = ["AT", "BE", "BG", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR", "GR", "HR", "HU", "IE", "IS", "IT", "LI", + "LT", "LU", "LV", "MT", "NL", "NO", "PL", "PT", "RO", "SE", "SI", "SK"] # §9.3 +VISIBLE = {"shown", "pending", "allowed", "fallback_allow"} # §6.2 + + +class Stop(Exception): + def __init__(self, reason, at): + super().__init__(reason) + self.reason, self.at = reason, at + + +def sha(*parts): + h = hashlib.sha256() + for p in parts: + h.update(p) + return h.digest() + + +# ---------------------------------------------------------------- the extension's own tables + +def section(text, heading): + at = text.index("\n" + heading) + end = text.find("\n## ", at + 1) + end2 = text.find("\n### ", at + 1) + ends = [e for e in (end, end2) if e != -1] + return text[at:min(ends) if ends else len(text)] + + +def table_rows(sec): + return [[c.strip() for c in line.strip().strip("|").split("|")] for line in sec.splitlines() + if line.startswith("| ") and not line.startswith("|---")][1:] + + +def tables(): + """§9.5's categories, §9.6's content types and §10's reasons, from the text.""" + with open(EXTENSION, encoding="utf-8") as f: + text = f.read() + categories = [row[1].strip("`") for row in table_rows(section(text, "### 9.5 Categories"))] + types = {} + for target, ctype, other in table_rows(section(text, "### 9.6 Content types")): + ctype, other = ctype.strip("`"), other.strip("`") or None + if target.startswith("an object of media 1"): + types[(OBJECT, 1)] = (ctype, other) + elif target.startswith("an object of media 2"): + types[(OBJECT, 2)] = types[(OBJECT, 3)] = (ctype, other) + else: + names = {v: k for k, v in LEV.KINDS.items()} + for name in re.findall(r"`([a-z_]+)`", target): + types[(EVENT, names[name])] = (ctype, other) + reasons = [row[0].strip("`") for row in table_rows(section(text, "## 10. Reasons"))] + return categories, types, reasons + + +CATEGORIES, CONTENT_TYPES, REASONS = tables() + + +# ---------------------------------------------------------------- reading + +class Reader(LEV.Reader): + def text(self): + return self.take(self.u16()) + + +def read_head(b, magic): + """§3.3 step 1.""" + 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 utf8(b): + try: + return b.decode("utf-8") + except UnicodeDecodeError: + return None + + +def read_policy(b): + """§3.1, §3.3: the policy, or Refuse.""" + read_head(b, POLICY_MAGIC) + r = Reader(b, "truncated") + r.take(5) + p = {"room": r.take(32), "prev": r.take(32), "effective": r.u64()} + p["reviewers"] = [r.take(32) for _ in range(r.u8())] + p["flaggers"] = [r.take(32) for _ in range(r.u8())] + p["entries"] = [] + for _ in range(r.u8()): + p["entries"].append({"scope": r.u8(), "code": r.u8(), "mode": r.u8(), "deadline_ms": r.u32(), "fallback": r.u8(), + "fallback_reason": r.u16()}) + p["reasons"] = [] + for _ in range(r.u8()): + p["reasons"].append({"code": r.u16(), "ground": r.u8(), "category": r.u8(), "reference": r.text(), "url": r.text()}) + p["territory"] = [r.take(2) for _ in range(r.u8())] + p["redress"] = r.text() + body_len = r.p + p["sig"] = r.take(64) + if not r.done(): + raise Refuse("malformed") + p["body"] = b[:body_len] + p["digest"] = sha(p["body"]) + bad = Refuse("policy_malformed") + counts_ok = (len(p["reviewers"]) <= 16 and len(p["flaggers"]) <= 16 and len(p["entries"]) <= 32 + and 1 <= len(p["reasons"]) <= 64 and 1 <= len(p["territory"]) <= 30) + if not counts_ok: + raise bad + asc = lambda xs: all(a < b for a, b in zip(xs, xs[1:])) # noqa: E731 + if not asc(p["reviewers"]) or not asc(p["flaggers"]): + raise bad + if not asc([(e["scope"], e["code"]) for e in p["entries"]]) or not asc([c["code"] for c in p["reasons"]]): + raise bad + codes = {c["code"] for c in p["reasons"]} + for e in p["entries"]: + code_ok = (e["scope"] == 1 and e["code"] in DECIDABLE) or (e["scope"] == 2 and e["code"] in (1, 2, 3)) + reason_ok = e["fallback_reason"] == 0 if e["fallback"] == F_ALLOW else e["fallback_reason"] in codes + if not (code_ok and e["mode"] in (PRE, POST) and e["deadline_ms"] > 0 and e["fallback"] in (1, 2, 3) and reason_ok): + raise bad + for c in p["reasons"]: + ref, url = utf8(c["reference"]), utf8(c["url"]) + if ref is None or url is None: + raise bad + url_ok = url == "" or (len(c["url"]) <= 500 and url.startswith("https://") and all(0x21 <= x <= 0x7E for x in c["url"])) + if not (c["code"] > 0 and c["ground"] in (1, 2) and 1 <= c["category"] <= 16 and 1 <= len(ref) <= 500 and url_ok): + raise bad + c["reference"], c["url"] = ref, url + terr = [t.decode("latin-1") for t in p["territory"]] + if not asc(terr) or any(t not in TERRITORY for t in terr): + raise bad + p["territory"] = terr + if utf8(p["redress"]) is None: + raise bad + return p + + +def read_statement(b): + """§4.2, §4.3: the statement, or Refuse("statement_malformed").""" + try: + r = Reader(b, "statement_malformed") + if r.take(4) != STATEMENT_MAGIC or r.u8() != 1: + raise Refuse("statement_malformed") + s = {"target_type": r.u8(), "target_prev": r.take(32), "supersedes": r.take(32), "basis": r.u8(), + "notice": r.take(32), "automated": r.u8(), "ground": r.u8()} + texts = [utf8(r.text()) for _ in range(3)] + if not r.done(): + raise Refuse("statement_malformed") + except Refuse: + raise Refuse("statement_malformed") + s["ground_ref"], s["explanation"], s["facts"] = texts + decided = (s["automated"] >> 1) & 3 + ok = (s["target_type"] in (EVENT, OBJECT) and (s["target_type"] == EVENT or s["target_prev"] == ZERO) + and s["basis"] in (1, 2, 3, 4) and ((s["basis"] in (NOTICE, COMPLAINT)) == (s["notice"] != ZERO)) + and s["automated"] & ~0b111 == 0 and decided != 3 + and (s["basis"] != FALLBACK or (decided == 2 and s["supersedes"] == ZERO)) + and s["ground"] in (1, 2) and None not in texts) + if not ok: + raise Refuse("statement_malformed") + return s + + +def read_notice(b): + """§5.1, §5.2 (all but the list's rule): the notice, or Refuse.""" + read_head(b, NOTICE_MAGIC) + r = Reader(b, "truncated") + r.take(5) + n = {"room": r.take(32), "type": r.u8(), "target_type": r.u8(), "target": r.take(32), "t": r.u64(), "ground": r.u8(), + "good_faith": r.u8(), "ground_ref": r.text(), "statement": r.text(), "contact": r.text(), "submitter": r.take(32)} + body_len = r.p + n["sig"] = r.take(64) + if not r.done(): + raise Refuse("malformed") + n["body"] = b[:body_len] + n["digest"] = sha(n["body"]) + if n["type"] == 1: + ok = n["target_type"] in (1, 2) and n["ground"] in (1, 2) + elif n["type"] == 2: + ok = n["target_type"] == 1 and n["ground"] == 0 + else: + ok = False + if not ok or n["good_faith"] > 1 or any(utf8(n[k]) is None for k in ("ground_ref", "statement", "contact")): + raise Refuse("notice_malformed") + return n + + +# ---------------------------------------------------------------- §7 verification + +def policy_at(policies, t): + """§3.4.""" + for p in reversed(policies): + if p["effective"] <= t: + return p + return None + + +def entry_of(p, scope, code): + return next((e for e in p["entries"] if e["scope"] == scope and e["code"] == code), None) if p else None + + +def reason_of(p, code): + return next((c for c in p["reasons"] if c["code"] == code), None) + + +def has_kind(bm, k): + return bm[k // 8] >> (k % 8) & 1 == 1 + + +def moderate(v): + """§7: a dict of what the corpus states for room vector v.""" + descriptor = bytes.fromhex(v["descriptor"]) + grants = [bytes.fromhex(g) for g in v["grants"]] + chains = [[bytes.fromhex(h) for h in c] for c in v["chains"]] + room = LRV.verify_room(descriptor, grants, v["key_log"], chains) # step 1 + if room["outcome"] == "refuse": + return {"outcome": "refuse", "reason": room["reason"], "at": ["room"] + room["at"]}, None + d = LRV.read_descriptor(descriptor) + held_grants, _ = LRV.check_grants(d, grants) + powers = {g["digest"]: g["powers"] for g in held_grants} + room_gaps = [(bytes.fromhex(g["principal"]), g["first"], g["last"]) for g in room.get("gaps", [])] + policies = [] + for i, h in enumerate(v["policies"]): # step 2 + try: + p = read_policy(bytes.fromhex(h)) + if p["room"] != d["room"]: + raise Refuse("wrong_room") + bad = ED.verify(d["authority"], POLICY_DOMAIN + p["body"], p["sig"]) + if bad: + raise Refuse(bad) + q = policies[-1] if policies else None + if not ((q is None and p["prev"] == ZERO and p["effective"] == 0) + or (q is not None and p["prev"] == q["digest"] and p["effective"] > q["effective"])): + raise Refuse("policy_unlinked") + kinds, deadline, fb = d["review"] + for k in range(256): # §3.5 + if has_kind(kinds, k): + e = entry_of(p, 1, k) + if e is None or e["mode"] != PRE or e["deadline_ms"] != deadline or e["fallback"] != fb: + raise Refuse("policy_conflicts_room") + except Refuse as e: + return {"outcome": "refuse", "reason": e.reason, "at": ["policy", i]}, None + policies.append(p) + notices = [] + for i, h in enumerate(v["notices"]): # step 3 + try: + n = read_notice(bytes.fromhex(h)) + if any(m["digest"] == n["digest"] for m in notices): + raise Refuse("notice_malformed") + if n["room"] != d["room"]: + raise Refuse("wrong_room") + bad = ED.verify(n["submitter"], NOTICE_DOMAIN + n["body"], n["sig"]) + if bad: + raise Refuse(bad) + except Refuse as e: + return {"outcome": "refuse", "reason": e.reason, "at": ["notice", i]}, None + notices.append(n) + objects = [{"digest": bytes.fromhex(o["digest"]), "media": o["media"], "t": o["t"]} for o in v["objects"]] + # The events the room accepted, once each, in the merged order. + held, seen = [], set() + for c, i, under in room["order"]: + ev = LEV.read_record(chains[c][i]) + if ev["digest"] in seen: + continue + seen.add(ev["digest"]) + ev["payload_read"] = LEV.read_payload(ev["kind"], ev["payload"], 1 << 20) + ev["chain"], ev["record"], ev["under"] = c, i, bytes.fromhex(under) if under else None + held.append(ev) + by_seq = {(e["principal"], e["seq"]): k for k, e in enumerate(held)} + by_digest = {e["digest"]: k for k, e in enumerate(held)} + + def room_key(p): + return p in (d["authority"], d["clock"]) + + def is_statement(e): + return e["kind"] == META and e["payload"][:4] == STATEMENT_MAGIC + + statements = {} + for e in held: # step 4 + if not is_statement(e): + continue + at = ["record", e["chain"], e["record"]] + if e["seq"] == 0: + return {"outcome": "refuse", "reason": "statement_misplaced", "at": at}, None + b = by_seq.get((e["principal"], e["seq"] - 1)) + if b is None: + continue + if held[b]["kind"] != DECISION or held[b]["t"] != e["t"]: + return {"outcome": "refuse", "reason": "statement_misplaced", "at": at}, None + try: + statements[b] = read_statement(e["payload"]) + except Refuse as x: + return {"outcome": "refuse", "reason": x.reason, "at": at}, None + last_on = {} + for k, e in enumerate(held): + if e["kind"] == DECISION: + last_on[e["payload_read"]["target"]] = k + explained, remaining, withheld = [], [], set() # step 5, §7.3 + for g in room_gaps: + ex = explain(g, held, by_seq, statements, last_on) + if ex is None: + remaining.append(g) + else: + explained.append(ex[0]) + withheld |= ex[1] + gap_remains = bool(remaining) + + def event_entry(e): + """§6.1.""" + if e["kind"] not in DECIDABLE or is_statement(e) or room_key(e["principal"]) or powers.get(e["under"], 0) & MODERATE: + return None + return entry_of(policy_at(policies, e["t"]), 1, e["kind"]) + + def object_entry(o): + return entry_of(policy_at(policies, o["t"]), 2, o["media"]) + + decisions, line, decided = [], {}, {} + for k, e in enumerate(held): # step 6, §7.4 + if e["kind"] != DECISION: + continue + at = ["record", e["chain"], e["record"]] + p, pl = e["principal"], e["payload_read"] + v_, x, code = pl["verdict"], pl["target"], pl["reason"] + if k in statements: + said = "known" + elif (p, e["seq"] + 1) in by_seq: + said = "none" + elif any(q == p and a <= e["seq"] + 1 <= z for q, a, z in remaining): + said = "unknown" + else: + said = "none" + st = statements.get(k) + tt = st["target_type"] if st else EVENT + try: + pol = policy_at(policies, e["t"]) # 1 + rc = reason_of(pol, code) if pol else None + if rc is None or (st is not None and st["ground"] != rc["ground"]): + raise Refuse("reason_not_in_policy") + target, entry = None, None # 2 + if tt == OBJECT: + o = next((o for o in objects if o["digest"] == x and o["t"] <= e["t"]), None) + if o is None: + raise Refuse("target_unknown") + target, entry = (OBJECT, o["media"], o["t"]), object_entry(o) + elif x in by_digest: + ti = by_digest[x] + te = held[ti] + if ti >= k: + raise Refuse("target_unknown") + if te["kind"] not in DECIDABLE or is_statement(te): + raise Refuse("target_not_decidable") + if st is not None and st["target_prev"] != te["prev"]: + raise Refuse("target_prev_mismatch") + target, entry = (EVENT, te["kind"], te["t"]), event_entry(te) + elif x not in withheld and not gap_remains: + raise Refuse("target_unknown") + if entry is not None and pol["reviewers"] and not room_key(p) and p not in pol["reviewers"]: # 3 + raise Refuse("not_reviewer") + if said != "unknown": # 4 + sup = st["supersedes"] if st else ZERO + head = line.get(x) + if sup == ZERO: + if head is not None: + raise Refuse("supersede_gap") + elif sup in decided: + if decisions[decided[sup]]["target"] != x: + raise Refuse("supersede_mismatch") + if head != sup: + raise Refuse("supersede_gap") + elif not gap_remains: + raise Refuse("supersede_unknown") + if st is not None and st["basis"] in (NOTICE, COMPLAINT): # 5 + want = 1 if st["basis"] == NOTICE else 2 + n = next((n for n in notices if n["digest"] == st["notice"] and n["type"] == want), None) + if n is None: + raise Refuse("notice_unknown") + aims = (n["target"] == x and n["target_type"] == tt) if st["basis"] == NOTICE else n["target"] == st["supersedes"] + if not aims or n["t"] > e["t"]: + raise Refuse("notice_mismatch") + if st is not None and st["basis"] == FALLBACK: + if not room_key(p): + raise Refuse("fallback_not_in_policy") + if target is not None: + if entry is None or entry["fallback"] == F_HOLD or v_ != entry["fallback"] or code != entry["fallback_reason"]: + raise Refuse("fallback_not_in_policy") + if e["t"] < target[2] + entry["deadline_ms"] * 1000: + raise Refuse("fallback_early") + except Refuse as r: + return {"outcome": "refuse", "reason": r.reason, "at": at}, None + line[x] = e["digest"] + decided[e["digest"]] = len(decisions) + decisions.append({"digest": e["digest"], "decider": p, "t": e["t"], "target": x, "target_type": tt, "verdict": v_, + "reason": code, "said": said, "st": st, "target_of": target}) + for x in decisions: + x["standing"] = line[x["target"]] == x["digest"] + # Step 7 and what a verification states (§7.5). + out = {"outcome": "gap" if gap_remains else "accept", "room_outcome": room["outcome"], + "gaps": [{"principal": p.hex(), "first": a, "last": z} for p, a, z in remaining], + "explained": [{"principal": p.hex(), "first": a, "last": z, "decisions": [h.hex() for h in ds]} for p, a, z, ds in explained]} + out["decisions"] = [{ + "digest": x["digest"].hex(), "decider": x["decider"].hex(), "t": x["t"], "target": x["target"].hex(), + "target_type": "event" if x["target_type"] == EVENT else "object", "verdict": VERDICTS[x["verdict"]], "reason": x["reason"], + "statement": x["said"], "basis": None if x["said"] == "unknown" else BASES[x["st"]["basis"] if x["st"] else OWN], + "supersedes": x["st"]["supersedes"].hex() if x["st"] and x["st"]["supersedes"] != ZERO else None, + "notice": x["st"]["notice"].hex() if x["st"] and x["st"]["notice"] != ZERO else None, + "standing": x["standing"]} for x in decisions] + items = [] + for e in held: + ds = [x for x in decisions if x["target"] == e["digest"] and x["target_type"] == EVENT] + en = event_entry(e) + if en is not None or ds: + items.append(item(e["digest"], "event", LEV.KINDS[e["kind"]], e["t"], en, ds)) + for o in objects: + ds = [x for x in decisions if x["target"] == o["digest"] and x["target_type"] == OBJECT] + en = object_entry(o) + if en is not None or ds: + items.append(item(o["digest"], "object", MEDIA[o["media"]], o["t"], en, ds)) + out["items"] = items + ctx = {"t0": d["t0"], "policies": policies, "notices": notices, "decisions": decisions} + exports, files = [], {} + for k, x in enumerate(decisions): + rec = export(ctx, k) + if rec is None: + exports.append({"decision": x["digest"].hex(), "file": None}) + elif isinstance(rec, str): + exports.append({"decision": x["digest"].hex(), "file": None, "refuse": "sor_incomplete", "member": rec}) + else: + name = "%s.d%d.sor.json" % (v["name"], k) + files[name] = rec + exports.append({"decision": x["digest"].hex(), "file": name}) + out["exports"] = exports + restricted = {x["target"]: x["digest"] for x in decisions + if x["standing"] and x["target_type"] == OBJECT and x["verdict"] != ALLOW} + return out, {"files": files, "restricted": restricted} + + +def explain(g, held, by_seq, statements, last_on): + """§7.3: (explained gap, withheld digests), or None.""" + p, a, z = g + after = by_seq.get((p, z + 1)) + if after is None: + return None + dg, ds, digests = held[after]["prev"], [], set() + for _ in range(a, z + 1): + k = last_on.get(dg) + if k is None or k not in statements: + return None + s = statements[k] + if s["target_type"] != EVENT or held[k]["payload_read"]["verdict"] == ALLOW: + return None + ds.append(held[k]["digest"]) + digests.add(dg) + dg = s["target_prev"] + if a == 0: + start = ZERO + else: + b = by_seq.get((p, a - 1)) + if b is None: + return None + start = held[b]["digest"] + if dg != start: + return None + return (p, a, z, list(reversed(ds))), digests + + +def item(digest, tt, what, t, entry, ds): + """§6.2: the item and its timeline.""" + first = "shown" if entry is None else ("held" if entry["mode"] == PRE else "pending") + tl = [(t, first, None)] + if entry is not None: + due = t + entry["deadline_ms"] * 1000 + if not any(x["t"] <= due and not (x["st"] and x["st"]["basis"] == FALLBACK) for x in ds): + tl.append((due, {F_ALLOW: "fallback_allow", F_DENY: "fallback_deny", F_HOLD: "fallback_hold"}[entry["fallback"]], None)) + for x in ds: + tl.append((x["t"], {ALLOW: "allowed", DENY: "denied", REDACT: "redacted"}[x["verdict"]], x["digest"])) + return {"digest": digest.hex(), "target_type": tt, "kind": what, "t": t, + "entry": None if entry is None else {"mode": "pre" if entry["mode"] == PRE else "post", + "deadline_ms": entry["deadline_ms"], + "fallback": {1: "allow", 2: "deny", 3: "hold"}[entry["fallback"]]}, + "timeline": [{"t": a, "state": s, "decision": h.hex() if h else None, "visible": s in VISIBLE} for a, s, h in tl]} + + +# ---------------------------------------------------------------- §9 the export + +def js(s): + """§9.2's string.""" + out = ['"'] + for c in s: + o = ord(c) + if c == '"': + out.append('\\"') + elif c == "\\": + out.append("\\\\") + elif o in (8, 9, 10, 12, 13): + out.append({8: "\\b", 9: "\\t", 10: "\\n", 12: "\\f", 13: "\\r"}[o]) + elif o < 0x20: + out.append("\\u%04x" % o) + else: + out.append(c) + out.append('"') + return "".join(out) + + +def utc_date(t0, t): + try: + return (datetime.datetime(1970, 1, 1) + datetime.timedelta(microseconds=t0 + t)).date().isoformat() + except OverflowError: + return None + + +def source(ctx, k): + """§9.3 source_type, or None.""" + x = ctx["decisions"][k] + if x["said"] == "unknown": + return None + st = x["st"] + if st is None or st["basis"] in (OWN, FALLBACK): + return "SOURCE_VOLUNTARY" + if st["basis"] == NOTICE: + n = next((n for n in ctx["notices"] if n["digest"] == st["notice"]), None) + if n is None: + return None + if n["ground"] != ILLEGAL: + return "SOURCE_TYPE_OTHER_NOTIFICATION" + pol = policy_at(ctx["policies"], x["t"]) + return "SOURCE_TRUSTED_FLAGGER" if n["submitter"] in pol["flaggers"] else "SOURCE_ARTICLE_16" + y = next((j for j in range(k) if ctx["decisions"][j]["digest"] == st["supersedes"]), None) + return None if y is None else source(ctx, y) + + +def export(ctx, k): + """§9: None for an allow, the member's name when §9.8 refuses, or the record's bytes.""" + x = ctx["decisions"][k] + if x["verdict"] == ALLOW: + return None + st = x["st"] + if st is None or not 1 <= len(st["facts"]) <= 5000: + return "decision_facts" + pol = policy_at(ctx["policies"], x["t"]) + rc = reason_of(pol, x["reason"]) + illegal = st["ground"] == ILLEGAL + gname = "illegal_content_legal_ground" if illegal else "incompatible_content_ground" + ename = "illegal_content_explanation" if illegal else "incompatible_content_explanation" + gref = st["ground_ref"] or rc["reference"] + if not 1 <= len(gref) <= 500: + return gname + if not 1 <= len(st["explanation"]) <= 2000: + return ename + if x["target_of"] is None: + return "content_type" + tt, code, target_t = x["target_of"] + ctype, other = CONTENT_TYPES[(tt, code)] + cdate = utc_date(ctx["t0"], target_t) + if cdate is None or not "2000-01-01" <= cdate <= "2038-01-01": + return "content_date" + adate = utc_date(ctx["t0"], x["t"]) + if adate is None or not "2020-01-01" <= adate <= "2038-01-01": + return "application_date" + src = source(ctx, k) + if src is None: + return "source_type" + m = [("decision_visibility", "[%s]" % js("DECISION_VISIBILITY_CONTENT_DISABLED" if x["verdict"] == DENY else "DECISION_VISIBILITY_CONTENT_REMOVED")), + ("decision_facts", js(st["facts"])), + ("decision_ground", js("DECISION_GROUND_ILLEGAL_CONTENT" if illegal else "DECISION_GROUND_INCOMPATIBLE_CONTENT"))] + if rc["url"]: + m.append(("decision_ground_reference_url", js(rc["url"]))) + m += [(gname, js(gref)), (ename, js(st["explanation"])), ("content_type", "[%s]" % js(ctype))] + if other: + m.append(("content_type_other", js(other))) + m += [("category", js(CATEGORIES[rc["category"] - 1])), + ("territorial_scope", "[%s]" % ",".join(js(t) for t in pol["territory"])), + ("content_date", js(cdate)), ("application_date", js(adate)), ("source_type", js(src)), + ("automated_detection", js("Yes" if st["automated"] & 1 else "No")), + ("automated_decision", js(["AUTOMATED_DECISION_NOT_AUTOMATED", "AUTOMATED_DECISION_PARTIALLY", + "AUTOMATED_DECISION_FULLY"][(st["automated"] >> 1) & 3])), + ("puid", js(x["digest"].hex()))] + return ("{" + ",".join("%s:%s" % (js(a), b) for a, b in m) + "}").encode("utf-8") + + +# ---------------------------------------------------------------- §8.3 clips + +def clip_outcome(c, restricted): + """§8.3: a dict of what the corpus states for clip c.""" + exempt = frozenset(restricted) + got = LREC.verify_clip(c, exempt=exempt) + if got["outcome"] == "refuse": + return got + clip = LREC.read_clip(bytes.fromhex(c["record"])) + withheld = [] + for k, (p, g) in enumerate(zip(clip["parts"], c["parts"])): + w = [] + for j, x in enumerate(p["chunks"]): + leaf = LREC.leaf(x["desc"]) + if leaf in restricted: + if j < len(g["bytes"]) and g["bytes"][j] is not None: + return {"outcome": "refuse", "reason": "redaction_not_applied", "at": ["chunk", k, j]} + w.append({"index": x["index"], "decision": restricted[leaf].hex()}) + withheld.append(w) + facts = [] + for f, w in zip(got["facts"], withheld): + f = {k: f[k] for k in ("take", "first", "count", "offset", "span", "device_window", "bytes", "sha256")} + f["withheld"] = w + facts.append(f) + got["facts"] = facts + return got + + +# ---------------------------------------------------------------- the corpus + +def check(doc, files, quiet=False): + """Every room and clip against its statement, and every export file: the failures.""" + fails, runs, written = [], {}, {} + for v in doc.get("vectors", []): + try: + got, extra = moderate(v) + except Exception as e: # a crash on a mutated copy is a failure to read it + got, extra = None, None + bad = ["the vector does not verify: %s: %s" % (type(e).__name__, e)] + else: + bad = [k for k in got if v.get(k) != got[k]] + [k for k in ("outcome", "reason", "at") if k in v and k not in got] + if extra: + runs[v["name"]] = extra + for name, b in extra["files"].items(): + written[name] = b + if files.get(name) != b: + bad.append("its export %s" % name) + if not quiet: + what = "?" if got is None else got["outcome"] + (" " + got["reason"] if got["outcome"] == "refuse" else "") + print(("PASS" if not bad else "FAIL") + " room %s: %s" % (v["name"], what)) + fails += ["room %s: %s differs from the corpus" % (v["name"], k) for k in bad] + for c in doc.get("clips", []): + run = runs.get(c.get("room")) + try: + got = clip_outcome(c, run["restricted"] if run else {}) + except Exception as e: + got, bad = None, ["the clip does not verify: %s: %s" % (type(e).__name__, e)] + else: + bad = [k for k in got if c.get(k) != got[k]] + [k for k in ("outcome", "reason", "at") if k in c and k not in got] + if not quiet: + what = "?" if got is None else got["outcome"] + (" " + got["reason"] if got["outcome"] == "refuse" else "") + print(("PASS" if not bad else "FAIL") + " clip %s: %s" % (c["name"], what)) + fails += ["clip %s: %s differs from the corpus" % (c["name"], k) for k in bad] + return fails, written + + +def flip(h, at): + b = bytearray(bytes.fromhex(h)) + b[at] ^= 0x01 + return b.hex() + + +def mutations(doc, files): + """Copies of the corpus, each with one defect a conforming verifier must catch.""" + vn = {v["name"]: k for k, v in enumerate(doc["vectors"])} + cn = {c["name"]: k for k, c in enumerate(doc["clips"])} + + def mutate(label, f): + d, fs = copy.deepcopy(doc), dict(files) + f(d["vectors"], d["clips"], fs) + return label, d, fs + + pre, sub, notice, appeal, red = vn["premoderated_chat"], vn["subscriber_view"], vn["notice_and_decision"], vn["appeal_reverses"], vn["redacted_segment"] + + def drop_statement(vs, cs, fs): + """The moderator's first statement taken out of its chain.""" + ch = vs[pre]["chains"] + for c in ch: + for i, h in enumerate(c): + if bytes.fromhex(h)[4 + 1 + 32 + 32 + 8 + 32 + 8 + 1 + 1 + 2:][:4] == STATEMENT_MAGIC: + del c[i] + return + + def first_export(fs, name): + return next(k for k in sorted(fs) if k.startswith(name + ".")) + + return [ + mutate("a byte of the first policy's signature", lambda vs, cs, fs: vs[pre]["policies"].__setitem__(0, flip(vs[pre]["policies"][0], -3))), + mutate("the policies given in each other's place", lambda vs, cs, fs: vs[pre]["policies"].reverse()), + mutate("the moderator's first statement dropped", drop_statement), + mutate("the denied message stated allowed", lambda vs, cs, fs: vs[pre]["decisions"][1].update(verdict="allow")), + mutate("a fallback stated at the wrong instant", lambda vs, cs, fs: vs[pre]["items"][3]["timeline"][1].update(t=34000000)), + mutate("the held reaction stated visible", lambda vs, cs, fs: vs[pre]["items"][3]["timeline"][1].update(visible=True)), + mutate("a byte of an export file", lambda vs, cs, fs: fs.update({first_export(fs, "premoderated_chat"): fs[first_export(fs, "premoderated_chat")].replace(b"Yes", b"No ")})), + mutate("the subscriber's explained gap stated with its decisions swapped", + lambda vs, cs, fs: vs[sub]["explained"][0]["decisions"].reverse()), + mutate("the subscriber's view stated without its gap explained", lambda vs, cs, fs: vs[sub].update(explained=[])), + mutate("a byte of the notice's cited provision", lambda vs, cs, fs: vs[notice]["notices"].__setitem__(0, flip(vs[notice]["notices"][0], 120))), + mutate("the notice's decision stated answering the flagger's notice", lambda vs, cs, fs: vs[notice]["decisions"][1].update(notice=vs[notice]["decisions"][3]["notice"])), + mutate("the trusted flagger's redaction stated from an Article 16 notice", + lambda vs, cs, fs: fs.update({"notice_and_decision.d3.sor.json": fs["notice_and_decision.d3.sor.json"].replace(b"SOURCE_TRUSTED_FLAGGER", b"SOURCE_ARTICLE_16")})), + mutate("the complaint withheld", lambda vs, cs, fs: vs[appeal].update(notices=[])), + mutate("the appeal's reversal stated not standing", lambda vs, cs, fs: vs[appeal]["decisions"][1].update(standing=False)), + mutate("the redacted chunk's object stated after the decision", + lambda vs, cs, fs: next(o for o in vs[red]["objects"] if o["digest"] == vs[red]["decisions"][0]["target"]).update(t=21000000)), + mutate("the clip given the redacted chunk's bytes", lambda vs, cs, fs: cs[cn["clip_withheld"]]["parts"][0]["bytes"].__setitem__(1, cs[cn["clip_restored_whole"]]["parts"][0]["bytes"][1])), + mutate("the trimmed clip's stated digest", lambda vs, cs, fs: cs[cn["clip_trimmed_withheld"]]["facts"][0].update(sha256="00" * 32)), + mutate("the withheld clip stated over the reversed room", lambda vs, cs, fs: cs[cn["clip_withheld"]].update(room="redaction_reversed")), + mutate("a stated export file removed", lambda vs, cs, fs: fs.pop(first_export(fs, "appeal_reverses"))), + ] + + +def main(corpus_dir): + fails = [] + st = ED._self_test() + print(("PASS" if not st else "FAIL") + " Ed25519 strict rule self-test " + ",".join(st)) + fails += ["ed25519 self-test"] if st else [] + ok_tables = len(CATEGORIES) == 16 and len(REASONS) == 20 and len(CONTENT_TYPES) == 12 + print(("PASS" if ok_tables else "FAIL") + " §9.5, §9.6 and §10 read from the extension: %d categories, %d content types, %d reasons" + % (len(CATEGORIES), len(CONTENT_TYPES), len(REASONS))) + fails += [] if ok_tables else ["the extension's tables do not read"] + with open(os.path.join(corpus_dir, "vectors.json"), encoding="utf-8") as f: + doc = json.load(f) + files = {} + for name in sorted(os.listdir(corpus_dir)): + if name.endswith(".sor.json"): + with open(os.path.join(corpus_dir, name), "rb") as f: + files[name] = f.read() + got, written = check(doc, files) + fails += got + extra = sorted(set(os.listdir(corpus_dir)) - set(written) - {"vectors.json", "README.md"}) + print(("PASS" if not extra else "FAIL") + " no file but vectors.json, README.md and the exports the rooms write") + fails += ["an extra file: %s" % n for n in extra] + seen = {v.get("reason") for v in doc["vectors"] + doc["clips"]} + seen |= {e.get("refuse") for v in doc["vectors"] for e in v.get("exports", [])} + missing = [r for r in REASONS if r not in seen] + print(("PASS" if not missing else "FAIL") + " every reason of §10 appears in the corpus") + fails += ["no case gives %s" % r for r in missing] + for label, d, fs in mutations(doc, files): + caught, _ = check(d, fs, quiet=True) + print(("PASS" if caught else "FAIL") + " mutated copy fails: %s%s" % (label, " (%s)" % caught[0][:100] 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") + " live-moderation corpus: %d rooms, %d clips, %d exports" + % (len(doc["vectors"]), len(doc["clips"]), len(files))) + return 1 if fails else 0 + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("usage: live_moderation_verify.py ", file=sys.stderr) + sys.exit(2) + sys.exit(main(sys.argv[1])) diff --git a/wai/live-conformance/live_record_verify.py b/wai/live-conformance/live_record_verify.py index 326a7c5c6..af8addcd1 100644 --- a/wai/live-conformance/live_record_verify.py +++ b/wai/live-conformance/live_record_verify.py @@ -580,8 +580,10 @@ def read_clip(b): return c -def verify_part(k, p, given, d, clip): - """§5.4 step 3 for part k: its facts, or Stop.""" +def verify_part(k, p, given, d, clip, exempt=frozenset()): + """§5.4 step 3 for part k: its facts, or Stop. A chunk whose leaf is in `exempt` is passed + over in step (k), as live-moderation §8.3 has a restricted chunk passed over; none is by + default.""" I, J = d["commit_interval_ms"] * 1000, d["jitter_ms"] * 1000 at_part = ["part", k] if bytes.fromhex(given["device"]) != p["device"]: # (a) @@ -656,7 +658,12 @@ def verify_part(k, p, given, d, clip): if not covers or ((p["trim_in"] or p["trim_out"]) and (wi, wo) != span): raise Stop(at_part, "clip_window_invalid") shown = b"" # (k) + trim_in, trim_out = p["trim_in"], p["trim_out"] for j, x in enumerate(ch): + if leaf(x["desc"]) in exempt: + trim_in = 0 if j == 0 else trim_in + trim_out = 0 if j == len(ch) - 1 else trim_out + continue h = given["bytes"][j] if j < len(given["bytes"]) else None if h is None: raise Stop(["chunk", k, j], "clip_chunk_missing") @@ -667,15 +674,15 @@ def verify_part(k, p, given, d, clip): shown += b if len(given["bytes"]) > len(ch): raise Stop(["chunk", k, len(ch)], "chunk_extra") - shown = shown[p["trim_in"]:len(shown) - p["trim_out"]] + shown = shown[trim_in:len(shown) - trim_out] return {"take": p["take"].hex(), "first": p["first"], "count": len(ch), "offset": o, "span": list(span), "device_window": [wi - o, wo - o], "bytes": len(shown), "sha256": sha(shown).hex(), "fetch": {"namespace": [d["room"].hex(), p["device"].hex(), "take"], "name": p["take"].hex(), "start_group": p["first"], "start_object": 0, "end_group_delta": len(ch) - 1}} -def verify_clip(v): - """§5.4: a dict of what the corpus states.""" +def verify_clip(v, exempt=frozenset()): + """§5.4: a dict of what the corpus states. `exempt`: as verify_part's.""" try: try: d = LRV.read_descriptor(bytes.fromhex(v["descriptor"])) @@ -689,7 +696,7 @@ def verify_clip(v): raise Stop(["clip"], "wrong_room") if len(v["parts"]) != len(clip["parts"]): raise Stop(["clip"], "clip_record_invalid") - facts = [verify_part(k, p, g, d, clip) for k, (p, g) in enumerate(zip(clip["parts"], v["parts"]))] + facts = [verify_part(k, p, g, d, clip, exempt) for k, (p, g) in enumerate(zip(clip["parts"], v["parts"]))] except Stop as e: return {"outcome": "refuse", "reason": e.reason, "at": e.at} J = d["jitter_ms"] * 1000 diff --git a/wai/live-conformance/moderation/README.md b/wai/live-conformance/moderation/README.md new file mode 100644 index 000000000..05f27782f --- /dev/null +++ b/wai/live-conformance/moderation/README.md @@ -0,0 +1,116 @@ +# live-conformance/moderation — live moderation + +The corpus of [`extensions/live-moderation.md`](../../extensions/live-moderation.md) §11: +rooms under review policies, each a room (its `WRD1` descriptor, `WRG1` grants, key-log head +or none, and each principal's `WEV1` chain), its `WMP1` review policies, its `WMN1` notices +and complaints, and the media objects under moderation; the decisions in its chains with +their `WMS1` statements; what a verifier states of them; each restricting decision's +statement-of-reasons export, byte for byte; and clips of a redacted take. + +**Moderation equivalence.** For each room vector, a conforming moderation verifier given its +`descriptor`, `grants`, `key_log`, `chains`, `policies`, `notices` and `objects` (§7.1) +reaches the outcome the vector states (§7.5): + +- `refuse`: the `reason` and where, `at`: `["room", …]` with the room verifier's own place + (live-rooms §9.1), `["policy", i]`, `["notice", i]`, or `["record", c, i]` for record `i` + of chain `c`; +- `accept` or `gap`: the `room_outcome` (`accept` or `gap`); the `gaps` that remain, each + `principal`, `first` and `last`; the `explained` gaps (§7.3), each with the `decisions` + withholding its seqs from `first` to `last`; the `decisions` (§7.5), each its `digest`, + `decider`, `t`, `target`, `target_type`, `verdict`, `reason`, `statement` (`known`, `none` + or `unknown`), `basis` (`own`, `notice`, `complaint`, `fallback`, or `null` for an unknown + statement), `supersedes`, `notice` and whether it is `standing`; the `items` (§6), each its + `digest`, `target_type`, `kind` (an event kind or a media kind), `t`, `entry` (`mode`, + `deadline_ms`, `fallback`) or `null`, and its `timeline`, each entry's `t`, `state`, + `decision` and whether the state is `visible`; and the `exports`: for each decision, the + `file` holding its record, `null` for an allow, or `refuse` `sor_incomplete` with the + `member` §9.8 names. + +Each export file, `NAME.dK.sor.json`, is the record of decision *K* of vector `NAME`, exactly +the bytes §9.2 writes, with no trailing newline. + +**Clip equivalence.** For each clip, a conforming verifier of a clip under moderation (§8.3), +given its `descriptor`, `record` and `parts` (as live-recording's corpus gives them) and the +standing restrictions of the room vector its `room` names, reaches the outcome the clip +states: `refuse` with the `reason` and `at` (live-recording's places), or `accept` with the +record's digest `clip`, its `signer`, `window`, `bound_us`, and the `facts` of each part as +live-recording states them (without the FETCH address) and the part's `withheld` chunks, each +its `index` and the `decision` that restricts it. + +A verifier that reaches another outcome, reason, place, decision, state, export byte or fact +does not conform. + +**Provenance.** Generated here: `wai_live_moderation_vectors gen` writes every file from rooms +authored in code, from fixed seeds. Each chat room principal's key is SHA-256 of a fixed label +and the principal's index; every time is a constant (the rooms' `t0` is 2026-10-16T00:00:00Z); +every text is written for the corpus in English; the phone number is of a reserved fictional +range; every origin, address and link is an `.example` name (RFC 2606); and Ed25519 signing is +deterministic (RFC 8032), so every file is the same bytes on every machine. The recorded take +is live-recording's lesson session, written by that corpus's own rules (`../recordings/`), +so its room, chains, commitments and chunks are that corpus's byte for byte; this corpus adds +the director's decisions to the director's chain, and the performer's complaint. The +generator asserts that each vector reaches the outcome it was written to have, and that the +corpus gives every reason of §10, before it writes. No recorded data. The legal provisions +the vocabulary cites are cited by identifier, as examples of a room's vocabulary; nothing in +the corpus states that any content is or is not lawful. + +## Layout + +- `vectors.json`: `categories` (§9.5, informative), `principals` and `lesson_principals` (the + keys, by name, informative), `vectors` and `clips`. +- `NAME.dK.sor.json`: the exports. + +The rooms: + +- `premoderated_chat`: a chat room whose descriptor holds chat for review five seconds and then + denies it; a first policy names a reviewer, a trusted flagger and the vocabulary, and a + second, from 20 s, also reviews reactions after delivery with a fallback of hold. One + message allowed before its deadline, one denied with automated detection, one past its + deadline taking the fallback, which the clock signs; a reaction held at its deadline; a + message allowed by a decision without a statement; a host's message, not reviewed. +- `subscriber_view`: the same room as a subscriber that is not a reviewer receives it: the + denied message and the fallback's are withheld, and the gap they leave is explained. +- `unexplained_gap`: the same room with the allowed message withheld: a delivery gap. +- `notice_and_decision`: an allowed message, a notice that it is illegal, and the decision that + answers it (`SOURCE_ARTICLE_16`); a message the fallback denied, a trusted flagger's notice, + and the redaction that answers it (`SOURCE_TRUSTED_FLAGGER`). +- `appeal_reverses`: a denial with automated means, its author's complaint, and the decision + on the complaint that allows the message. +- `redacted_segment` and `redaction_reversed`: live-recording's lesson session with its video + reviewed after delivery; the director redacts chunk 3 of the performer's take, and in the + second the performer complains and the director restores it. +- refused, one defect each: `not_moderator` (refused by the room, `kind_not_permitted`), + `policy_malformed`, `policy_unlinked`, `policy_conflicts_room`, `policy_bad_signature`, + `policy_wrong_room`, `notice_malformed`, `notice_bad_signature`, `statement_misplaced`, + `statement_malformed`, `reason_not_in_policy`, `target_unknown`, `target_not_decidable`, + `target_prev_mismatch`, `not_reviewer`, `supersede_gap`, `supersede_unknown`, + `supersede_mismatch`, `notice_unknown`, `notice_mismatch`, `fallback_not_in_policy` and + `fallback_early`; +- `sor_incomplete`: a denial whose statement states no facts, accepted, its export refused. + +The clips, chunks 2 to 5 of the performer's take: `clip_withheld` and +`clip_trimmed_withheld` (a byte range from inside the redacted chunk) withhold chunk 3; +`clip_redaction_not_applied` gives its bytes; after the appeal, `clip_restored_missing` +leaves it out and `clip_restored_whole` presents it. + +## Running + +``` +cd ../../wai-rs +cargo run --no-default-features --features live_moderation --bin wai_live_moderation_vectors -- verify ../live-conformance/moderation +cargo run --no-default-features --features live_moderation --bin wai_live_moderation_vectors -- gen ../live-conformance/moderation # regenerate +cargo test --no-default-features --features live_moderation --test live_moderation +cd ../live-conformance +python3 -I live_moderation_verify.py moderation +``` + +`wai_live_moderation_vectors verify` and `tests/live_moderation.rs` require every file to +regenerate byte for byte, no other file but this one to be there, and `wai-rs` to give every +case its outcome; the test also requires §10 to list exactly the reasons the reference +reports, and the generator that the corpus gives each of them. `live_moderation_verify.py` is +the second implementation, written from the extension's text and sharing no code with +`wai-rs`: it verifies each room with `live_rooms_verify.py` and each clip with +`live_record_verify.py`, writes every export itself, reads §9.5, §9.6 and §10 from the +extension, gives every case the same outcome, requires every reason of §10 to appear, and +then mutates copies of the corpus, one defect each, each of which must fail. Pass = an exit +status of 0 from each. diff --git a/wai/live-conformance/moderation/appeal_reverses.d0.sor.json b/wai/live-conformance/moderation/appeal_reverses.d0.sor.json new file mode 100644 index 000000000..8392054f2 --- /dev/null +++ b/wai/live-conformance/moderation/appeal_reverses.d0.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"A classifier matched the message to a promotion pattern and proposed denial; a reviewer confirmed it at 10.4 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#4.2","incompatible_content_ground":"Room terms, clause 4.2: no unsolicited promotion","incompatible_content_explanation":"The message advertises a paid service to the room's participants, which clause 4.2 of the room's terms does not allow.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"Yes","automated_decision":"AUTOMATED_DECISION_PARTIALLY","puid":"a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e1"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/notice_and_decision.d1.sor.json b/wai/live-conformance/moderation/notice_and_decision.d1.sor.json new file mode 100644 index 000000000..f2dc6d0df --- /dev/null +++ b/wai/live-conformance/moderation/notice_and_decision.d1.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"A notice received at 40 s named the message; a reviewer confirmed the number is a private one and disabled access at 45 s.","decision_ground":"DECISION_GROUND_ILLEGAL_CONTENT","illegal_content_legal_ground":"Regulation (EU) 2016/679, Article 6(1)","illegal_content_explanation":"The message discloses a private phone number of a person outside the room, with no ground for processing it.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_DATA_PROTECTION_AND_PRIVACY_VIOLATIONS","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_ARTICLE_16","automated_detection":"No","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"e8125d22e92e65373d1a3411c2eb841bede81a43e96795d22bf50267fead3123"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/notice_and_decision.d2.sor.json b/wai/live-conformance/moderation/notice_and_decision.d2.sor.json new file mode 100644 index 000000000..5c1fda7f9 --- /dev/null +++ b/wai/live-conformance/moderation/notice_and_decision.d2.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"Held for review at 50 s of the session; no decision by 55 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#6","incompatible_content_ground":"Room terms, clause 6: a message held for review and not reviewed by its deadline is not shown","incompatible_content_explanation":"No reviewer decided on the message within the room's five-second deadline, and clause 6 of the room's terms withholds such a message.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"No","automated_decision":"AUTOMATED_DECISION_FULLY","puid":"3d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/notice_and_decision.d3.sor.json b/wai/live-conformance/moderation/notice_and_decision.d3.sor.json new file mode 100644 index 000000000..699aeee6f --- /dev/null +++ b/wai/live-conformance/moderation/notice_and_decision.d3.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_REMOVED"],"decision_facts":"A trusted flagger's notice received at 60 s named the message; a reviewer opened the link and removed the message at 62 s.","decision_ground":"DECISION_GROUND_ILLEGAL_CONTENT","illegal_content_legal_ground":"Directive 2001/29/EC, Article 3(1)","illegal_content_explanation":"The message links a recording communicated to the public without authorisation.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_TRUSTED_FLAGGER","automated_detection":"No","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"de3dcf9be4ccec87f5a0632cc0f9720e9d798130e43b3a8b14916db2f70f7de9"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/premoderated_chat.d1.sor.json b/wai/live-conformance/moderation/premoderated_chat.d1.sor.json new file mode 100644 index 000000000..4af26ae33 --- /dev/null +++ b/wai/live-conformance/moderation/premoderated_chat.d1.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"Held for review at 11.5 s of the session; a classifier flagged its link, and a reviewer read the message and denied it at 12.5 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#4.2","incompatible_content_ground":"Room terms, clause 4.2: no unsolicited promotion","incompatible_content_explanation":"The message advertises a paid service to the room's participants, which clause 4.2 of the room's terms does not allow.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"Yes","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/premoderated_chat.d2.sor.json b/wai/live-conformance/moderation/premoderated_chat.d2.sor.json new file mode 100644 index 000000000..d8427f7bc --- /dev/null +++ b/wai/live-conformance/moderation/premoderated_chat.d2.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"Held for review at 12 s of the session; no decision by 17 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#6","incompatible_content_ground":"Room terms, clause 6: a message held for review and not reviewed by its deadline is not shown","incompatible_content_explanation":"No reviewer decided on the message within the room's five-second deadline, and clause 6 of the room's terms withholds such a message.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"No","automated_decision":"AUTOMATED_DECISION_FULLY","puid":"9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/redacted_segment.d0.sor.json b/wai/live-conformance/moderation/redacted_segment.d0.sor.json new file mode 100644 index 000000000..c26e7006b --- /dev/null +++ b/wai/live-conformance/moderation/redacted_segment.d0.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_REMOVED"],"decision_facts":"An audio match flagged a commercial recording playing behind the performer during chunk 3 of the take; the director listened to it and removed the chunk at 20 s.","decision_ground":"DECISION_GROUND_ILLEGAL_CONTENT","illegal_content_legal_ground":"Directive 2001/29/EC, Article 3(1)","illegal_content_explanation":"The segment plays a recording protected by copyright, which the room holds no licence to communicate to the public.","content_type":["CONTENT_TYPE_VIDEO"],"category":"STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS","territorial_scope":["AT","DE","FR"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"Yes","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/redaction_reversed.d0.sor.json b/wai/live-conformance/moderation/redaction_reversed.d0.sor.json new file mode 100644 index 000000000..c26e7006b --- /dev/null +++ b/wai/live-conformance/moderation/redaction_reversed.d0.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_REMOVED"],"decision_facts":"An audio match flagged a commercial recording playing behind the performer during chunk 3 of the take; the director listened to it and removed the chunk at 20 s.","decision_ground":"DECISION_GROUND_ILLEGAL_CONTENT","illegal_content_legal_ground":"Directive 2001/29/EC, Article 3(1)","illegal_content_explanation":"The segment plays a recording protected by copyright, which the room holds no licence to communicate to the public.","content_type":["CONTENT_TYPE_VIDEO"],"category":"STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS","territorial_scope":["AT","DE","FR"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"Yes","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/unexplained_gap.d1.sor.json b/wai/live-conformance/moderation/unexplained_gap.d1.sor.json new file mode 100644 index 000000000..4af26ae33 --- /dev/null +++ b/wai/live-conformance/moderation/unexplained_gap.d1.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"Held for review at 11.5 s of the session; a classifier flagged its link, and a reviewer read the message and denied it at 12.5 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#4.2","incompatible_content_ground":"Room terms, clause 4.2: no unsolicited promotion","incompatible_content_explanation":"The message advertises a paid service to the room's participants, which clause 4.2 of the room's terms does not allow.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"Yes","automated_decision":"AUTOMATED_DECISION_NOT_AUTOMATED","puid":"9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/unexplained_gap.d2.sor.json b/wai/live-conformance/moderation/unexplained_gap.d2.sor.json new file mode 100644 index 000000000..d8427f7bc --- /dev/null +++ b/wai/live-conformance/moderation/unexplained_gap.d2.sor.json @@ -0,0 +1 @@ +{"decision_visibility":["DECISION_VISIBILITY_CONTENT_DISABLED"],"decision_facts":"Held for review at 12 s of the session; no decision by 17 s.","decision_ground":"DECISION_GROUND_INCOMPATIBLE_CONTENT","decision_ground_reference_url":"https://rooms.example/terms#6","incompatible_content_ground":"Room terms, clause 6: a message held for review and not reviewed by its deadline is not shown","incompatible_content_explanation":"No reviewer decided on the message within the room's five-second deadline, and clause 6 of the room's terms withholds such a message.","content_type":["CONTENT_TYPE_TEXT"],"category":"STATEMENT_CATEGORY_OTHER_VIOLATION_TC","territorial_scope":["AT","BE","BG","CY","CZ","DE","DK","EE","ES","FI","FR","GR","HR","HU","IE","IS","IT","LI","LT","LU","LV","MT","NL","NO","PL","PT","RO","SE","SI","SK"],"content_date":"2026-10-16","application_date":"2026-10-16","source_type":"SOURCE_VOLUNTARY","automated_detection":"No","automated_decision":"AUTOMATED_DECISION_FULLY","puid":"9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560"} \ No newline at end of file diff --git a/wai/live-conformance/moderation/vectors.json b/wai/live-conformance/moderation/vectors.json new file mode 100644 index 000000000..6769a863f --- /dev/null +++ b/wai/live-conformance/moderation/vectors.json @@ -0,0 +1,3120 @@ +{ + "about": "extensions/live-moderation.md §11: rooms under review policies, their decisions and statements, notices and complaints, explained gaps, the items' timelines, each decision's statement-of-reasons export, and clips of a redacted take", + "categories": [ + "STATEMENT_CATEGORY_ANIMAL_WELFARE", + "STATEMENT_CATEGORY_CONSUMER_INFORMATION", + "STATEMENT_CATEGORY_CYBER_VIOLENCE", + "STATEMENT_CATEGORY_CYBER_VIOLENCE_AGAINST_WOMEN", + "STATEMENT_CATEGORY_DATA_PROTECTION_AND_PRIVACY_VIOLATIONS", + "STATEMENT_CATEGORY_ILLEGAL_OR_HARMFUL_SPEECH", + "STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS", + "STATEMENT_CATEGORY_NEGATIVE_EFFECTS_ON_CIVIC_DISCOURSE_OR_ELECTIONS", + "STATEMENT_CATEGORY_NOT_SPECIFIED_NOTICE", + "STATEMENT_CATEGORY_OTHER_VIOLATION_TC", + "STATEMENT_CATEGORY_PROTECTION_OF_MINORS", + "STATEMENT_CATEGORY_RISK_FOR_PUBLIC_SECURITY", + "STATEMENT_CATEGORY_SCAMS_AND_FRAUD", + "STATEMENT_CATEGORY_SELF_HARM", + "STATEMENT_CATEGORY_UNSAFE_AND_PROHIBITED_PRODUCTS", + "STATEMENT_CATEGORY_VIOLENCE" + ], + "principals": { + "authority": "9b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b35841", + "clock": "0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174", + "host": "69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4", + "moderator": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "viewer_a": "23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903", + "viewer_b": "88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f", + "submitter": "f545da3b8a00bce9b198180d2277db1d5968ab700f90dc4922aee59cb271340d", + "flagger": "db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f1" + }, + "lesson_principals": { + "authority": "d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd", + "relay": "0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b72", + "director": "d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52", + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "performer": "59425465004500032d6893f980a7dad483af70b4e116a10b7caa4e2052593699" + }, + "vectors": [ + { + "name": "premoderated_chat", + "about": "chat held five seconds under the room's review field: one message allowed, one denied, one denied by the fallback the clock signs; a second policy reviews reactions after delivery, and one is held at its deadline", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc464066030100000000000b230002acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f840314d657d503c87bdf1c58cb5a5c4d24f904b651d3141dc8cae0fc6af26482007c3e5945da093f3055ec0df7fe7d1d725b237e74a96f812a703f74e47f54416509", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317405000000000000009e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560406603010000000000013001574d533101011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0400000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742031322073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920313720732e23541ef27b22f4efef5be84966b45eb15c305d318fa3366f07b6509806883e49e544a998fd8ccdfa794f7dd44e30fedb487dde3e7ede04eafb2df79d15aa7203" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99030300000000000000acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f405dc600000000000004040001010000f74b6e77b4fe359b555cbf7882e7e20d69d2c37c4aab68ef2e550e74733dbf3f30b6776d41387883bbb409f6411d80bd5e2c95ddaa90203170c7989c06dda30e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b23000151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430246500f450fa3601f366ee48422ac29981800d7990b5cfdbe714e9e29a738485e3c1eea5afd96157f20bae7280e333660af91ad7069b4f7fb00efd36c6ae4cd9702705", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544cc0d8a700000000000001ca00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002f00546865206d6573736167652069732061206772656574696e673b2069742070726f6d6f746573206e6f7468696e672e2c005265766965776564207768696c652068656c643a2061206772656574696e6720746f2074686520726f6f6d2ed4cccc86a23c1ce440e1bfb6bc42d47af6a70e3f58e0b4f56396bf56d94098f3085ff2eb5a523b45df958a91b13aa46124dc87c6cdde21d151e3feeba91d8d02", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad02000000000000004c26d81f8f3f0daea168fd650ea25b51b9946af32c8ba94d8c3909275ad62e8920bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650069e139ae42b66cc7f63d13d19831719b1bb1d2a2fc84c15b99ba3c091b4d57249fa86e333924bbd6af2907a6c4be2143d9e1036855df6a2aa3527b956f31e205", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad03000000000000009566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c820bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e6d37412959ab1eae7ddd5d265c6d9d12a11e152da3dd99d5c1df5faf791d2366db963c485e23049688b4b25eb1d1c27b80ed4043163facd3f95724026a62260c", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0400000000000000afefa662fc623729aed308a8e8b907b60bd18a157aa9984b1c48c6875a098f60003fab0100000000000b23000181931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b716500eaa8964b922180c6f15899ba53343e87db79ddd76f1e34786434cbfed17499e202f972a49cb11bf4b6e55d897944e2ffa32e403a47e3d5bcface0e63b0a44102" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0000000000000000000000000000000000000000000000000000000000000000000000000000000040787d0100000000000404000101000081b4de748bd7d3819623774b0421904e98e2a15d76ca2088e9c684b6be2305bb357125eeb84b82d7edf15b82ad496e842fa5b7f7ab6567c94e5e98e9c3a60f05", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0100000000000000344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e80ba8c0100000000000320001e00697320746865206e6578742073657373696f6e206f6e204672696461793f4f839c019b2d8347c5db2e767f9392cf4271d63125d21a2193ec24b38547cd53ee323a4bdbafd30f74213b0efe72d4ff8251d351060784fd923e0e303e28830f" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c40000000000000000000000000000000000000000000000000000000000000000000000000000000080c3c9010000000000031300110077656c636f6d652c2065766572796f6e65d8e4f1653d97638bfef5fa45b4d92726338514e309c7326dd9e3115c26e2143f9464f48a1b948abc0fdb53c9d5688947297855fab4dc92c95a2218e8a9303c07" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05", + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a2088d22189bf6307323c690a761a3bb9f4006da73117b0473606eddd986ed107002d310100000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f1020103018813000002840301040210270000038403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e21274892087b37775d151e08927a7b3bb33a5407e541c684edc8818c682f27a4a01c8f35d9c9667de3fb26a79d51c1fa79dbc9cce2dcf91524546e609be7ee0a" + ], + "notices": [], + "objects": [], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 11000000, + "target": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 12500000, + "target": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "verdict": "deny", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "decider": "0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174", + "t": 17000000, + "target": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "verdict": "deny", + "reason": 900, + "statement": "known", + "basis": "fallback", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 28000000, + "target": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "none", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + } + ], + "items": [ + { + "digest": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "kind": "chat", + "t": 10000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 10000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 11000000, + "state": "allowed", + "decision": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "visible": true + } + ] + }, + { + "digest": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "kind": "chat", + "t": 11500000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 11500000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 12500000, + "state": "denied", + "decision": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "visible": false + } + ] + }, + { + "digest": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "kind": "chat", + "t": 12000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 12000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 17000000, + "state": "fallback_deny", + "decision": null, + "visible": false + }, + { + "t": 17000000, + "state": "denied", + "decision": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "visible": false + } + ] + }, + { + "digest": "344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e", + "target_type": "event", + "kind": "reaction", + "t": 25000000, + "entry": { + "mode": "post", + "deadline_ms": 10000, + "fallback": "hold" + }, + "timeline": [ + { + "t": 25000000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 35000000, + "state": "fallback_hold", + "decision": null, + "visible": false + } + ] + }, + { + "digest": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "kind": "chat", + "t": 26000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 26000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 28000000, + "state": "allowed", + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "file": null + }, + { + "decision": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "file": "premoderated_chat.d1.sor.json" + }, + { + "decision": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "file": "premoderated_chat.d2.sor.json" + }, + { + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "file": null + } + ] + }, + { + "name": "subscriber_view", + "about": "the same room as a subscriber that is not a reviewer receives it: the denied message and the fallback's are withheld, and the gap they leave is explained by the decisions", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc464066030100000000000b230002acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f840314d657d503c87bdf1c58cb5a5c4d24f904b651d3141dc8cae0fc6af26482007c3e5945da093f3055ec0df7fe7d1d725b237e74a96f812a703f74e47f54416509", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317405000000000000009e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560406603010000000000013001574d533101011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0400000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742031322073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920313720732e23541ef27b22f4efef5be84966b45eb15c305d318fa3366f07b6509806883e49e544a998fd8ccdfa794f7dd44e30fedb487dde3e7ede04eafb2df79d15aa7203" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99030300000000000000acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f405dc600000000000004040001010000f74b6e77b4fe359b555cbf7882e7e20d69d2c37c4aab68ef2e550e74733dbf3f30b6776d41387883bbb409f6411d80bd5e2c95ddaa90203170c7989c06dda30e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b23000151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430246500f450fa3601f366ee48422ac29981800d7990b5cfdbe714e9e29a738485e3c1eea5afd96157f20bae7280e333660af91ad7069b4f7fb00efd36c6ae4cd9702705", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544cc0d8a700000000000001ca00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002f00546865206d6573736167652069732061206772656574696e673b2069742070726f6d6f746573206e6f7468696e672e2c005265766965776564207768696c652068656c643a2061206772656574696e6720746f2074686520726f6f6d2ed4cccc86a23c1ce440e1bfb6bc42d47af6a70e3f58e0b4f56396bf56d94098f3085ff2eb5a523b45df958a91b13aa46124dc87c6cdde21d151e3feeba91d8d02", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad02000000000000004c26d81f8f3f0daea168fd650ea25b51b9946af32c8ba94d8c3909275ad62e8920bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650069e139ae42b66cc7f63d13d19831719b1bb1d2a2fc84c15b99ba3c091b4d57249fa86e333924bbd6af2907a6c4be2143d9e1036855df6a2aa3527b956f31e205", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad03000000000000009566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c820bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e6d37412959ab1eae7ddd5d265c6d9d12a11e152da3dd99d5c1df5faf791d2366db963c485e23049688b4b25eb1d1c27b80ed4043163facd3f95724026a62260c", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0400000000000000afefa662fc623729aed308a8e8b907b60bd18a157aa9984b1c48c6875a098f60003fab0100000000000b23000181931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b716500eaa8964b922180c6f15899ba53343e87db79ddd76f1e34786434cbfed17499e202f972a49cb11bf4b6e55d897944e2ffa32e403a47e3d5bcface0e63b0a44102" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0000000000000000000000000000000000000000000000000000000000000000000000000000000040787d0100000000000404000101000081b4de748bd7d3819623774b0421904e98e2a15d76ca2088e9c684b6be2305bb357125eeb84b82d7edf15b82ad496e842fa5b7f7ab6567c94e5e98e9c3a60f05", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0100000000000000344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e80ba8c0100000000000320001e00697320746865206e6578742073657373696f6e206f6e204672696461793f4f839c019b2d8347c5db2e767f9392cf4271d63125d21a2193ec24b38547cd53ee323a4bdbafd30f74213b0efe72d4ff8251d351060784fd923e0e303e28830f" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c40000000000000000000000000000000000000000000000000000000000000000000000000000000080c3c9010000000000031300110077656c636f6d652c2065766572796f6e65d8e4f1653d97638bfef5fa45b4d92726338514e309c7326dd9e3115c26e2143f9464f48a1b948abc0fdb53c9d5688947297855fab4dc92c95a2218e8a9303c07" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05", + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a2088d22189bf6307323c690a761a3bb9f4006da73117b0473606eddd986ed107002d310100000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f1020103018813000002840301040210270000038403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e21274892087b37775d151e08927a7b3bb33a5407e541c684edc8818c682f27a4a01c8f35d9c9667de3fb26a79d51c1fa79dbc9cce2dcf91524546e609be7ee0a" + ], + "notices": [], + "objects": [], + "outcome": "accept", + "room_outcome": "gap", + "gaps": [], + "explained": [ + { + "principal": "23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903", + "first": 1, + "last": 2, + "decisions": [ + "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560" + ] + } + ], + "decisions": [ + { + "digest": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 11000000, + "target": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 12500000, + "target": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "verdict": "deny", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "decider": "0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174", + "t": 17000000, + "target": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "verdict": "deny", + "reason": 900, + "statement": "known", + "basis": "fallback", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 28000000, + "target": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "none", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + } + ], + "items": [ + { + "digest": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "kind": "chat", + "t": 10000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 10000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 11000000, + "state": "allowed", + "decision": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "visible": true + } + ] + }, + { + "digest": "344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e", + "target_type": "event", + "kind": "reaction", + "t": 25000000, + "entry": { + "mode": "post", + "deadline_ms": 10000, + "fallback": "hold" + }, + "timeline": [ + { + "t": 25000000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 35000000, + "state": "fallback_hold", + "decision": null, + "visible": false + } + ] + }, + { + "digest": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "kind": "chat", + "t": 26000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 26000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 28000000, + "state": "allowed", + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "file": null + }, + { + "decision": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "file": null, + "refuse": "sor_incomplete", + "member": "content_type" + }, + { + "decision": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "file": null, + "refuse": "sor_incomplete", + "member": "content_type" + }, + { + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "file": null + } + ] + }, + { + "name": "unexplained_gap", + "about": "the same room with the allowed message withheld: no restriction explains the gap, which remains a delivery gap", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc464066030100000000000b230002acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f840314d657d503c87bdf1c58cb5a5c4d24f904b651d3141dc8cae0fc6af26482007c3e5945da093f3055ec0df7fe7d1d725b237e74a96f812a703f74e47f54416509", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317405000000000000009e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560406603010000000000013001574d533101011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0400000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742031322073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920313720732e23541ef27b22f4efef5be84966b45eb15c305d318fa3366f07b6509806883e49e544a998fd8ccdfa794f7dd44e30fedb487dde3e7ede04eafb2df79d15aa7203" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99030300000000000000acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f405dc600000000000004040001010000f74b6e77b4fe359b555cbf7882e7e20d69d2c37c4aab68ef2e550e74733dbf3f30b6776d41387883bbb409f6411d80bd5e2c95ddaa90203170c7989c06dda30e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b23000151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430246500f450fa3601f366ee48422ac29981800d7990b5cfdbe714e9e29a738485e3c1eea5afd96157f20bae7280e333660af91ad7069b4f7fb00efd36c6ae4cd9702705", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544cc0d8a700000000000001ca00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002f00546865206d6573736167652069732061206772656574696e673b2069742070726f6d6f746573206e6f7468696e672e2c005265766965776564207768696c652068656c643a2061206772656574696e6720746f2074686520726f6f6d2ed4cccc86a23c1ce440e1bfb6bc42d47af6a70e3f58e0b4f56396bf56d94098f3085ff2eb5a523b45df958a91b13aa46124dc87c6cdde21d151e3feeba91d8d02", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad02000000000000004c26d81f8f3f0daea168fd650ea25b51b9946af32c8ba94d8c3909275ad62e8920bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650069e139ae42b66cc7f63d13d19831719b1bb1d2a2fc84c15b99ba3c091b4d57249fa86e333924bbd6af2907a6c4be2143d9e1036855df6a2aa3527b956f31e205", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad03000000000000009566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c820bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e6d37412959ab1eae7ddd5d265c6d9d12a11e152da3dd99d5c1df5faf791d2366db963c485e23049688b4b25eb1d1c27b80ed4043163facd3f95724026a62260c", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0400000000000000afefa662fc623729aed308a8e8b907b60bd18a157aa9984b1c48c6875a098f60003fab0100000000000b23000181931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b716500eaa8964b922180c6f15899ba53343e87db79ddd76f1e34786434cbfed17499e202f972a49cb11bf4b6e55d897944e2ffa32e403a47e3d5bcface0e63b0a44102" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0000000000000000000000000000000000000000000000000000000000000000000000000000000040787d0100000000000404000101000081b4de748bd7d3819623774b0421904e98e2a15d76ca2088e9c684b6be2305bb357125eeb84b82d7edf15b82ad496e842fa5b7f7ab6567c94e5e98e9c3a60f05", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0100000000000000344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e80ba8c0100000000000320001e00697320746865206e6578742073657373696f6e206f6e204672696461793f4f839c019b2d8347c5db2e767f9392cf4271d63125d21a2193ec24b38547cd53ee323a4bdbafd30f74213b0efe72d4ff8251d351060784fd923e0e303e28830f" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c40000000000000000000000000000000000000000000000000000000000000000000000000000000080c3c9010000000000031300110077656c636f6d652c2065766572796f6e65d8e4f1653d97638bfef5fa45b4d92726338514e309c7326dd9e3115c26e2143f9464f48a1b948abc0fdb53c9d5688947297855fab4dc92c95a2218e8a9303c07" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05", + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a2088d22189bf6307323c690a761a3bb9f4006da73117b0473606eddd986ed107002d310100000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f1020103018813000002840301040210270000038403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e21274892087b37775d151e08927a7b3bb33a5407e541c684edc8818c682f27a4a01c8f35d9c9667de3fb26a79d51c1fa79dbc9cce2dcf91524546e609be7ee0a" + ], + "notices": [], + "objects": [], + "outcome": "gap", + "room_outcome": "gap", + "gaps": [ + { + "principal": "23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903", + "first": 0, + "last": 0 + } + ], + "explained": [], + "decisions": [ + { + "digest": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 11000000, + "target": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 12500000, + "target": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "verdict": "deny", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "decider": "0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174", + "t": 17000000, + "target": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "verdict": "deny", + "reason": 900, + "statement": "known", + "basis": "fallback", + "supersedes": null, + "notice": null, + "standing": true + }, + { + "digest": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 28000000, + "target": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "none", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + } + ], + "items": [ + { + "digest": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "kind": "chat", + "t": 11500000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 11500000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 12500000, + "state": "denied", + "decision": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "visible": false + } + ] + }, + { + "digest": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "kind": "chat", + "t": 12000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 12000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 17000000, + "state": "fallback_deny", + "decision": null, + "visible": false + }, + { + "t": 17000000, + "state": "denied", + "decision": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "visible": false + } + ] + }, + { + "digest": "344a1c385d2bd2ce35a69c2fec8ddf98a7b3b336dc31844c47ed0ae56359ba6e", + "target_type": "event", + "kind": "reaction", + "t": 25000000, + "entry": { + "mode": "post", + "deadline_ms": 10000, + "fallback": "hold" + }, + "timeline": [ + { + "t": 25000000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 35000000, + "state": "fallback_hold", + "decision": null, + "visible": false + } + ] + }, + { + "digest": "81931ea9586ecf796e806d9754f115a0db420dcf93baae121ab1657455881b71", + "target_type": "event", + "kind": "chat", + "t": 26000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 26000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 28000000, + "state": "allowed", + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c", + "file": null + }, + { + "decision": "9566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c8", + "file": "unexplained_gap.d1.sor.json" + }, + { + "decision": "9e7aa6a53dec448ef4c871f002e56e2255056e5c50836abfa4c02ed6df719560", + "file": "unexplained_gap.d2.sor.json" + }, + { + "decision": "257348c481a5c85775ceb87f6824b805e728064d9c24f9b691c6a2a4c4bcb983", + "file": null + } + ] + }, + { + "name": "notice_and_decision", + "about": "an allowed message, then a notice that it is illegal and the decision that answers it; and a trusted flagger's notice on a message the fallback denied, answered by a redaction", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc46c03b470300000000000b23000283e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add5778403aa255f67905a732ae27cfe5e71796d0fea604c62e9dab380c66e51ca4980d0eb99a5b38abbb6f227d490bea4fe6838ae171514565d60153fd51b177640a0cc06", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317405000000000000003d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7c03b47030000000000013001574d53310101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742035302073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920353520732eda143a562085893c5e5c9f628e903984d8efcd9855af08fa5f0182aea254ed7d47f3a7811f887c3c5a72a3a7b4f172f1ad9b0af49a92f47f1d109265a209e705" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000339003700666f72206578747261206c6573736f6e732c2072696e6720746865207465616368657220617420686f6d65206f6e20353535203031303009d9016c57703610c3e9b60132cd7f5b01da348a8260b82df032652bf72c9a7e1065d623425188e5389d75ced8abe66e53d2a419df5abbc3b3ad192390250d0f" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b2300018c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecac6500f5bd8abc1fd02128908cd129605b754f2ce894506ef16507d9d9b06fcc4b22166b42f9cb0e97d48a2d39d56464c9abc56e6d265e68f952d7f21b952f8e4db20f", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26c0d8a700000000000001bd00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002500546865206d6573736167652070726f6d6f746573206e6f207061696420736572766963652e29005265766965776564207768696c652068656c643a20616e206f66666572206f66206c6573736f6e732e4e562d3fcad261213536c3324db0bc6693c4de35409b6aaf744abedb3b42ab8c8693727ab6ed4fb6371db2e8d4ce92eed732fc2c3c4bd44e32932bd95b385e04", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0200000000000000b0dca712d912975577f130b11a0b35e78c6193b68e79d73fe878cc330013443e40a5ae0200000000000b2300028c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecacc900d3c8ac061bc03f7a9d6a8b02713ca76ae0e6ed719bee5e7d8af33a9de44048cba6d731321e1e7181bcb0886de0651ed618457ff71cb1f2ae22cf61727727520f", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0300000000000000e8125d22e92e65373d1a3411c2eb841bede81a43e96795d22bf50267fead312340a5ae020000000000015501574d533101010000000000000000000000000000000000000000000000000000000000000000246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26022bf72a7b407052195a70d84ebd26f93bff7e3039211c50f3bc9945d97e92c939000100006c00546865206d65737361676520646973636c6f736573206120707269766174652070686f6e65206e756d626572206f66206120706572736f6e206f7574736964652074686520726f6f6d2c2077697468206e6f2067726f756e6420666f722070726f63657373696e672069742e7a0041206e6f746963652072656365697665642061742034302073206e616d656420746865206d6573736167653b206120726576696577657220636f6e6669726d656420746865206e756d62657220697320612070726976617465206f6e6520616e642064697361626c65642061636365737320617420343520732e7b267e960722ee464be82d8a1ab13fb096385ec1af49e299f3411b7e261f56b6370dadc18b559f308a07e94cadf353cd89fca621e37710402fc5bd6682ba7d04", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad04000000000000003dd712a0bb1ca65b0112395e0ebebe104700bcf0323b1eb38535c631530b36fb800bb20300000000000b23000383e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add5772d014e865ab1fb4b116b7218ec36e5b4fdf311f64f99a3020f25a241fc13d8f4597e1a0e01b13c5a39be75e5b4f18520efe480afe9b08a617353e69f69e1921a7900", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0500000000000000de3dcf9be4ccec87f5a0632cc0f9720e9d798130e43b3a8b14916db2f70f7de9800bb2030000000000013801574d5331010100000000000000000000000000000000000000000000000000000000000000003d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f702104cc0687097eac8941b3038400c237fcb9d01e769d72efaeda23beaa1b0cd60000100004f00546865206d657373616765206c696e6b732061207265636f7264696e6720636f6d6d756e69636174656420746f20746865207075626c696320776974686f757420617574686f7269736174696f6e2e7a0041207472757374656420666c61676765722773206e6f746963652072656365697665642061742036302073206e616d656420746865206d6573736167653b2061207265766965776572206f70656e656420746865206c696e6b20616e642072656d6f76656420746865206d65737361676520617420363220732ec3066a9fe339df7da2bec36954a2ab8a6b58f0476e256df042f600ca8093e3822af89583ed9ccc91f0e7b7e27ee06a3c115b1438ccfb4d8b98cd5bbe9a044e0c" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99030000000000000000000000000000000000000000000000000000000000000000000000000000000080f0fa020000000000033c003a007468652077686f6c6520636f6e63657274207265636f7264696e672069732075702061742066696c65732e6578616d706c652f636f6e636572749354c0b4d38f67e07356d3916e50a03d0507e0c3a511357570d99756d57ff393a817277e8227714dd9cb566c992da04c5904dd9a242846db1a932ea8d774ca0d" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [ + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a01018c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecac005a62020000000001012600526567756c6174696f6e202845552920323031362f3637392c2041727469636c6520362831296800546865206d657373616765207075626c69736865732074686520707269766174652070686f6e65206e756d626572206f6620736f6d656f6e652077686f206973206e6f7420696e2074686520726f6f6d2c20776974686f757420746865697220636f6e73656e742e14006e6f746966696572406578616d706c652e6f7267f545da3b8a00bce9b198180d2277db1d5968ab700f90dc4922aee59cb271340d49af8dbe9ebd7b5ca134a5f40ed818164c23de8ba90a840a5a3bc92607e221f3c9009cc7f73f47467b961c2503ba4eb98326c8489cba32e9a37d20e23c1b7602", + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a010183e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add57700879303000000000101220044697265637469766520323030312f32392f45432c2041727469636c6520332831296100546865206c696e6b206f666665727320612066756c6c207265636f7264696e67206f66206120636f6d6d65726369616c20636f6e6365727420776974686f757420746865207269676874686f6c646572732720617574686f7269736174696f6e2e1b007269676874732d6465736b40666c61676765722e6578616d706c65db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f1b621aab4bf8c25ca55394466ccdee79f6f947673b4292ea435cc41493f4edca64f33f249f100c11bc836f72cad56605617f685c50592464ce94712856acdfd04" + ], + "objects": [], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 11000000, + "target": "8c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecac", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": false + }, + { + "digest": "e8125d22e92e65373d1a3411c2eb841bede81a43e96795d22bf50267fead3123", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 45000000, + "target": "8c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecac", + "target_type": "event", + "verdict": "deny", + "reason": 201, + "statement": "known", + "basis": "notice", + "supersedes": "246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26", + "notice": "2bf72a7b407052195a70d84ebd26f93bff7e3039211c50f3bc9945d97e92c939", + "standing": true + }, + { + "digest": "3d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7", + "decider": "0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174", + "t": 55000000, + "target": "83e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add577", + "target_type": "event", + "verdict": "deny", + "reason": 900, + "statement": "known", + "basis": "fallback", + "supersedes": null, + "notice": null, + "standing": false + }, + { + "digest": "de3dcf9be4ccec87f5a0632cc0f9720e9d798130e43b3a8b14916db2f70f7de9", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 62000000, + "target": "83e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add577", + "target_type": "event", + "verdict": "redact", + "reason": 301, + "statement": "known", + "basis": "notice", + "supersedes": "3d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7", + "notice": "104cc0687097eac8941b3038400c237fcb9d01e769d72efaeda23beaa1b0cd60", + "standing": true + } + ], + "items": [ + { + "digest": "8c78f39898b73e91c24e3c5c4f98d5af437002b78779ec32e34b672533c3ecac", + "target_type": "event", + "kind": "chat", + "t": 10000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 10000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 11000000, + "state": "allowed", + "decision": "246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26", + "visible": true + }, + { + "t": 45000000, + "state": "denied", + "decision": "e8125d22e92e65373d1a3411c2eb841bede81a43e96795d22bf50267fead3123", + "visible": false + } + ] + }, + { + "digest": "83e5957ec04070b71cbc543a701b35deb331539397543ee4d6eaa45e40add577", + "target_type": "event", + "kind": "chat", + "t": 50000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 50000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 55000000, + "state": "fallback_deny", + "decision": null, + "visible": false + }, + { + "t": 55000000, + "state": "denied", + "decision": "3d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7", + "visible": false + }, + { + "t": 62000000, + "state": "redacted", + "decision": "de3dcf9be4ccec87f5a0632cc0f9720e9d798130e43b3a8b14916db2f70f7de9", + "visible": false + } + ] + } + ], + "exports": [ + { + "decision": "246611171ee858d96e79b15b073390fadc2182ba954e53813a0af2389ebb9f26", + "file": null + }, + { + "decision": "e8125d22e92e65373d1a3411c2eb841bede81a43e96795d22bf50267fead3123", + "file": "notice_and_decision.d1.sor.json" + }, + { + "decision": "3d422ec7bf5f065daf98a6cb76808d9e72a8faf4c9b43b8e8e91667447f338f7", + "file": "notice_and_decision.d2.sor.json" + }, + { + "decision": "de3dcf9be4ccec87f5a0632cc0f9720e9d798130e43b3a8b14916db2f70f7de9", + "file": "notice_and_decision.d3.sor.json" + } + ] + }, + { + "name": "appeal_reverses", + "about": "a message denied with automated means, a complaint from its author, and the decision on the complaint that allows it", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c40000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000331002f007468652062616e642077696c6c2074656c6c20796f752061626f757420746865697220736869727473206c61746572580a0a63315ea1ceb5487b41a25e0e06fd3569a635c51c3e9abbadf4e2ba68b97c184068bb9aec49c1306e0705f7937bdb977abcb1cf3a1513759102f3efd30f" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000330002e0067697665617761793a207069636b207570206120667265652073686972742061742073686f702e6578616d706c65e883b1dd04eb4aba2e420c1fa6d62e148bd67f8c9c7cc0959fc52659236334ed2e48754c2bd5abddbdf550791f02dc329320068aa8fca81324fe98029671d407" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000000b19e0000000000000b230002f6760ef5cef89e687458a8a131a7ced43c6cb1e6b86eb1b0ad77de9a2d470eb06500141f6d350c868bc59ba22ca6208a6cca9900b51cf0a1f2f1bfefc8ea301d1de63be0a04adba527f44aba20665a98071bceae8d2f9cc9310b368982dba3870c05", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e100b19e000000000000015401574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000030200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e6f004120636c6173736966696572206d61746368656420746865206d65737361676520746f20612070726f6d6f74696f6e207061747465726e20616e642070726f706f7365642064656e69616c3b206120726576696577657220636f6e6669726d65642069742061742031302e3420732e0d52720dbf1dc55672efb87de2eda6fe1a3c8007fb2a9ceabe87ccd4d73d4b988687ded4eb9b8e17a00ffe9b809ab5c26ff65de422ae4cb12ad2218580f74604", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0200000000000000899fde7a98b945cbb2626df08201690759e0e7fbf6c59f54273c9688ca602135005a620200000000000b230001f6760ef5cef89e687458a8a131a7ced43c6cb1e6b86eb1b0ad77de9a2d470eb0650013b390230d6f0c27c94e72ed461459b7779d828b96e17d88447bf33c148f239844068f33805e0d3178668be74dc6a835bfbfd014d1147a13c5c55cd38faca10a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad030000000000000070c8a8dea71e94655ef6eb2fb4910251d4b6ba61db642af8896729bdce1547ae005a62020000000000016c01574d533101010000000000000000000000000000000000000000000000000000000000000000a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e103488b1cbadbde44ed404704565fd436259363e311ebe9f1e93e19f6f89b7b88c90002000063004f6e2072657669657720746865206d656e74696f6e2077617320696e76697465642062792074686520686f73742c20736f206974206973206e6f7420756e736f6c6963697465642070726f6d6f74696f6e20756e64657220636c6175736520342e322e9a0054686520636f6d706c61696e7420706f696e74656420746f2074686520686f7374277320696e7669746174696f6e20617420322073206f66207468652073657373696f6e3b207468652072657669657765722072656164207468652073657373696f6e277320636861742c20636f6e6669726d65642069742c20616e6420616c6c6f77656420746865206d65737361676520617420343020732e62a2f4f698735b8f0e117de396628990999b08a1915dca1effdae2d99a403ec88f7cb302ccef5070227e82cc60e1e5bfcd1236ca822dc7e451d200cc40c45301" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [ + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0201a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e180c3c901000000000001000060005468652073686972747320617265207468652062616e642773206f776e2c20616e642074686520686f737420696e7669746564207468652062616e6420746f206d656e74696f6e207468656d20647572696e67207468652073657373696f6e2e000023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99030b4157086372956a8fdb5111c9304d6cee6c27d52a85abe54fbcc457d63fdee947fc6faea0e00da6603a9868d0d7d21cae186eca76aa90911b798dbd1cdac700" + ], + "objects": [], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e1", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 10400000, + "target": "f6760ef5cef89e687458a8a131a7ced43c6cb1e6b86eb1b0ad77de9a2d470eb0", + "target_type": "event", + "verdict": "deny", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": false + }, + { + "digest": "70c8a8dea71e94655ef6eb2fb4910251d4b6ba61db642af8896729bdce1547ae", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 40000000, + "target": "f6760ef5cef89e687458a8a131a7ced43c6cb1e6b86eb1b0ad77de9a2d470eb0", + "target_type": "event", + "verdict": "allow", + "reason": 101, + "statement": "known", + "basis": "complaint", + "supersedes": "a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e1", + "notice": "488b1cbadbde44ed404704565fd436259363e311ebe9f1e93e19f6f89b7b88c9", + "standing": true + } + ], + "items": [ + { + "digest": "f6760ef5cef89e687458a8a131a7ced43c6cb1e6b86eb1b0ad77de9a2d470eb0", + "target_type": "event", + "kind": "chat", + "t": 10000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 10000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 10400000, + "state": "denied", + "decision": "a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e1", + "visible": false + }, + { + "t": 40000000, + "state": "allowed", + "decision": "70c8a8dea71e94655ef6eb2fb4910251d4b6ba61db642af8896729bdce1547ae", + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "a3de7474effdcfa7b047476e0094bd3bf862e96ccd8ec70a5133445d808500e1", + "file": "appeal_reverses.d0.sor.json" + }, + { + "decision": "70c8a8dea71e94655ef6eb2fb4910251d4b6ba61db642af8896729bdce1547ae", + "file": null + } + ] + }, + { + "name": "not_moderator", + "about": "a viewer, without the moderate power, sends a decision: the room refuses it", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b046500ce44ad193db9cb6e7b7a4fb3781b4572229647ff2ee9d1c6c240df671da0ad41625e862412b616b3e70c4ee6c75306dcbbc260ff8fdde0eb8dd3ecbe118e7802" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "kind_not_permitted", + "at": [ + "room", + "record", + 2, + 0 + ] + }, + { + "name": "policy_malformed", + "about": "a policy entry whose fallback is none of allow, deny and hold", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000048403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2ee57590c2e8e85e81dbb43682524cc164ea9c25963d4a3b598c895a2b2e898f0714962b93a3e85c713f52c1f5215241467247f8b7e7e4f1b91f99c14ed41a8c0f" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "policy_malformed", + "at": [ + "policy", + 0 + ] + }, + { + "name": "policy_unlinked", + "about": "a second policy that does not name the first", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05", + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0000000000000000000000000000000000000000000000000000000000000000002d310100000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e430dfef23616335d9c639070fa1118613d2621e46eb1a64e92a7452ba6473bb91618400e79cbbb86a914cd9474857a51825f201e3a5efe0d3df9aec725e2210d" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "policy_unlinked", + "at": [ + "policy", + 1 + ] + }, + { + "name": "policy_conflicts_room", + "about": "a policy that reviews chat with another deadline than the room descriptor's", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f101010301a00f0000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e10bcf66d7c37797e956dafe61ceefd9641942a89c7196c356ee40560defdff3289323d223adf95250446bbdcc031c9c1a3b002c0cac5b79611de84d9f3116905" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "policy_conflicts_room", + "at": [ + "policy", + 0 + ] + }, + { + "name": "policy_bad_signature", + "about": "a policy whose signature does not verify", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5f5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "policy", + 0 + ] + }, + { + "name": "policy_wrong_room", + "about": "a policy of another room", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d503101766e8ff519463373b29e195b4de43b96128c19d70056ea223231d816622db83c00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2ea4acf4fde3e08a934afd9910ed528c3aae07ed3b6e3d18605b7e3c62f2c3628d2df91f682b3c003834ecf5b1630ca0be47b5d9e35b2abba1a9e75ec7cf1a1005" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "wrong_room", + "at": [ + "policy", + 0 + ] + }, + { + "name": "notice_malformed", + "about": "a notice of a type this revision does not define", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [ + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a03011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04002d3101000000000101000004007370616d0000f545da3b8a00bce9b198180d2277db1d5968ab700f90dc4922aee59cb271340d923ef85f0de8946f07f271164b380e3ee2935416b1d50ddf85cf6fa497cf8777d2cd8cd81e4c4c033c598c156f7aa0c3cb84223ec141d97b0eb7dc873295090b" + ], + "objects": [], + "outcome": "refuse", + "reason": "notice_malformed", + "at": [ + "notice", + 0 + ] + }, + { + "name": "notice_bad_signature", + "about": "a notice whose signature does not verify", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [ + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a01011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04002d31010000000002010000140054686973206973206164766572746973696e672e0000f545da3b8a00bce9b198180d2277db1d5968ab700f90dc4922aee59cb271340d293e4bab505a1c9cc6b01adcdff12f62aee02a79d7957c0401e3aafac2d331af22493b828d6f1e77fb4f00217a904629b67116d622200eaa23fbadc292d5fa4f" + ], + "objects": [], + "outcome": "refuse", + "reason": "bad_signature", + "at": [ + "notice", + 0 + ] + }, + { + "name": "statement_misplaced", + "about": "a statement that follows a chat message, not a decision", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe00000000000003070005006e6f7465649dc2147594d0f5c77e9aa7c9c199abf51a08d5865f9ecf45d0255de7151c62ffee23b73f005d72713b7bb0eb309eb363a7c47ffefb31b7f180f4573036bb9604", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01000000000000007a2ee56b32e8d093eba776a273fae679905f68d7b82ed5b88e15d417c96c701720bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732eb502b32ff3e7e2514179dbb5c25cad1da1ad396cb591501579803de6bf3f06c7b4a82e0fc8db8c0dd0fe319660d820afc20aef9322fb7aef9ecc254f1af1790a" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "statement_misplaced", + "at": [ + "record", + 2, + 1 + ] + }, + { + "name": "statement_malformed", + "about": "a statement whose basis is none this revision defines", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e2d619ce2a5c7e48b452812ea192e6bc28dc6540d2006e3372b49e81e666f14added4b59e42ab7a639b9419f65b22a046acc338c72e169efb5e8164a766ae740b" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "statement_malformed", + "at": [ + "record", + 2, + 1 + ] + }, + { + "name": "reason_not_in_policy", + "about": "a decision whose reason code the policy's vocabulary does not hold", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b042b02b69c1d047e76abbe79a24aa2b0faee084ea4bbf63828e6fe82cbebc7d377f68a4b34f65c85fcf05e411f06c08df82be2b7b192f616e227b3fe35ff14dae5530e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000e174ccddef8b6ff1956fef37babd7d268ef07f012aeb04a2b9c4134015a7d10320bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e27db5c2e0586b782c68cf3386a56390862307a34f0594e71dc7cbb9580bfa9d3faee120457601871c25235743bd0c47e2d0b109f4f0900fc2274ccf48731c600" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "reason_not_in_policy", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "target_unknown", + "about": "a decision on a digest that names no event of the room, which the verifier holds whole", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300022c733ea660fca1c6e20c54f39d5b8ca651bfa6e3bd2f16e54a4b401a7040f1236500421fe4c5376900e7fad5e153f81f212c6c73416ed2050b0fe76bb213d9ed847a39edee81358147421163c73dce4d74b477f8550548287c81be4fac648530da0c", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01000000000000003531c7324525254547f904c00d4f1a0ee0e50c2170bd2dc5b6fcb8c7eb435d1120bcbe000000000000016601574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732ed641fb501e0ad1fbe2d92510dd2825e2aee8c4d7457634ac578504a6779cd38830dd7629bc8f3a1cc6053ea11b8b4030a025dfc0ead22880f403be620e2d3d01" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "target_unknown", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "target_not_decidable", + "about": "a decision on the clock's join of a viewer", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b230002464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f565002b58c1dee220addafc5ccfe8b1ba3e70266186dd7a1ca71cac311ba69252a2974f25786383662d748d5cf61eb6b3eb6cf883dc0fed59ef38f0dd1580409ed70a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000c46c7196658141ae7dfffaadb457f994657f19f3ac4188d0bf5a49c40b72741920bcbe000000000000016601574d5331010122949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e3930000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e261103c32c92a92bd8ab0b02294cb49321fcff87ef89426574e4b4ce93b9e2fc6399790493ff59ec67330307dca278521f760e660f2fd18b42158ddb742de308" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "target_not_decidable", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "target_prev_mismatch", + "about": "a statement whose target_prev is not its target's prev", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe000000000000016601574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e0a32a38596dda323a6895964c08d852fd6fc2417a390ae14036542270778328d87f82ed16d2c02edc077b4a53abff0d720eaf0dee3703c97f2179e9a1b79f405" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "target_prev_mismatch", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "not_reviewer", + "about": "the host, with the moderate power but not among the policy's reviewers, denies a held message", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c40000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0465009efd6fc86225d9a39bbf4b2dbbec375f864e8ddcc808bd15e8c3f5ec86094d88c6ae7f331ac03a7f1251afee99133862db8d06c15b85c3029f39dd775937d403", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4010000000000000071cc489b455f1bf88caf7a7a69a387bf0444f2d34f40418eb69876720daac35d20bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e4f1d813f87c4a8eeaddd963ed1ab5deefd79fd2473339412cf6e1cfc9f8603db0d6a310c7a3303d473068d64d2ef3823467e66cece3cd301cad8e450c5643f0a" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "not_reviewer", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "supersede_gap", + "about": "a second decision on a message that supersedes nothing while the first stands", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b23000151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430246500f450fa3601f366ee48422ac29981800d7990b5cfdbe714e9e29a738485e3c1eea5afd96157f20bae7280e333660af91ad7069b4f7fb00efd36c6ae4cd9702705", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544cc0d8a700000000000001ca00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002f00546865206d6573736167652069732061206772656574696e673b2069742070726f6d6f746573206e6f7468696e672e2c005265766965776564207768696c652068656c643a2061206772656574696e6720746f2074686520726f6f6d2ed4cccc86a23c1ce440e1bfb6bc42d47af6a70e3f58e0b4f56396bf56d94098f3085ff2eb5a523b45df958a91b13aa46124dc87c6cdde21d151e3feeba91d8d02", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad02000000000000004c26d81f8f3f0daea168fd650ea25b51b9946af32c8ba94d8c3909275ad62e89405dc60000000000000b23000251d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf584302465000d5f542c64aa832b4f5263255bf5a2c8bae0382328c58714f8bb4afaafe90321d3d0d29b47b93f56339742b6c4d4d4d3b254462351c74cab7a3456eace698006", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0300000000000000573c195e3e25c91d40b2c39b9bf78511868459172d23a52a0eb7809eca085424405dc6000000000000016601574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732eb89af1030f3cc5c13a508aed9bdf6edbd44872ab763e586f19a4f7026de1a20ab8020ac7abb6d2ef000fb85d92185663402269e4e2638fe95e7dae5926edce08" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "supersede_gap", + "at": [ + "record", + 2, + 2 + ] + }, + { + "name": "supersede_unknown", + "about": "a decision that supersedes a digest naming no decision of the room", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430244721b98e4417e0774dfa0d7ce057257631550e2093961d814b001ee8ed4ed1de010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e0283219e9362de4d2a8981d4d476520766825eb350adcd15d732f8f0f4e4df098023faa1751ffc479a35dfd58faa44bc2628d69276d3ef708aa04b8b8747a809" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "supersede_unknown", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "supersede_mismatch", + "about": "a decision on one message that supersedes the decision on another", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000c0d8a70000000000000b23000151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430246500f450fa3601f366ee48422ac29981800d7990b5cfdbe714e9e29a738485e3c1eea5afd96157f20bae7280e333660af91ad7069b4f7fb00efd36c6ae4cd9702705", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544cc0d8a700000000000001ca00574d5331010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000200002f00546865206d6573736167652069732061206772656574696e673b2069742070726f6d6f746573206e6f7468696e672e2c005265766965776564207768696c652068656c643a2061206772656574696e6720746f2074686520726f6f6d2ed4cccc86a23c1ce440e1bfb6bc42d47af6a70e3f58e0b4f56396bf56d94098f3085ff2eb5a523b45df958a91b13aa46124dc87c6cdde21d151e3feeba91d8d02", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad02000000000000004c26d81f8f3f0daea168fd650ea25b51b9946af32c8ba94d8c3909275ad62e8920bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650069e139ae42b66cc7f63d13d19831719b1bb1d2a2fc84c15b99ba3c091b4d57249fa86e333924bbd6af2907a6c4be2143d9e1036855df6a2aa3527b956f31e205", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad03000000000000009566e5ae10c876ca924c518d452f230fa9c2a4c79daf1c93690af3da02df92c820bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024f0f1053435faf26e0947e081c77d37b117e7fc93449b9053086f9b9490bb544c010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732eeb6250a0eede60fa12147378a0d58033d853c1a19aedf14e9ff3051525935de332d215d9748eda2f68043e7d9ab5106e45b45900ad2c818cc0f808cb85711a00" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "supersede_mismatch", + "at": [ + "record", + 2, + 2 + ] + }, + { + "name": "notice_unknown", + "about": "a decision answering a notice the verifier is not given", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf584302400000000000000000000000000000000000000000000000000000000000000000257bf38990aba4f7260056062928ffd204e32bc355d8e14f91cb9f21ba794d199010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e0e88fbbb4443cfad8566c1ecb5f137e4a24659af171728137dfa2839ea96f44ee0fd650859a5c2c5533838acc49c01762b4528b64afedc941078a7ca49495807" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "notice_unknown", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "fallback_not_in_policy", + "about": "the clock signs a fallback that allows a message the policy's fallback denies", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc464066030100000000000b230001acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f8403e181ca7fbd48c69e0b7ddd1d20624e16c7ed8719d3198f5480f2163599607d8708a85e174f4298a208f107d4c3bf135b8b781f9a50e82b147a632ae2ce5acf09", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740500000000000000811764fc3fd25d35feaa1a14f13308120c0b4e8c868c9bb6e9546f143506da1e406603010000000000013001574d533101011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0400000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742031322073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920313720732e51012748725843e162ff10063ad4769bb8800189d7ae7861a2e844468aff1fcbe63131312c523be9015a5247325dc4e601d3766a3fa9284c96e9317d0c6c1306" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "fallback_not_in_policy", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "fallback_early", + "about": "the clock signs a fallback two seconds before the message's deadline", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174040000000000000051735fee4882b14ca74c5c796a2ee265e70d8650fd685002874a6cdcbccdcc46c0e1e40000000000000b230002acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f8403c5a2447811fda00febeb5a5b96586b7e3c857f89acf35fea1cd23c7d5da0f234451665f82cb8b0dabac524cb7742cd74592af12eb7e6918def4e702775e3dc01", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740500000000000000bb7cb65b2623144a06e7cba1b957c04628d13fe6289525b84f643ae928485007c0e1e4000000000000013001574d533101011b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b0400000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000402000085004e6f2072657669657765722064656369646564206f6e20746865206d6573736167652077697468696e2074686520726f6f6d277320666976652d7365636f6e6420646561646c696e652c20616e6420636c617573652036206f662074686520726f6f6d2773207465726d732077697468686f6c647320737563682061206d6573736167652e3c0048656c6420666f72207265766965772061742031322073206f66207468652073657373696f6e3b206e6f206465636973696f6e20627920313720732e54a3d729b101894f04f3e3b7a9f59843128f1ef26e65181b7da622e970b1dae66a0159bf9dd5bfdc7be3b26b0ede28745881bdbfd6d8db99761524ffc8299703" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "refuse", + "reason": "fallback_early", + "at": [ + "record", + 0, + 4 + ] + }, + { + "name": "notice_mismatch", + "about": "a decision on one message answering a notice about another", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe000000000000016601574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024000000000000000000000000000000000000000000000000000000000000000002f14c37daa078bb031b4d393b0254b2c5b0d7a15b7d4c66bfb0d16d0e80e4607b010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e810048656c6420666f72207265766965772061742031312e352073206f66207468652073657373696f6e3b206120636c617373696669657220666c616767656420697473206c696e6b2c20616e642061207265766965776572207265616420746865206d65737361676520616e642064656e6965642069742061742031322e3520732e454cc6f888612a28e5991b939bfdfb56f0718af9451627cd3b585b72bd3d764c220605f8aa2a19f3f445ee5bb26f87cc4aaf1b16e62364bd9231bb3aae3baf01" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [ + "574d4e31014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024c0d8a7000000000002010000140054686973206973206164766572746973696e672e0000f545da3b8a00bce9b198180d2277db1d5968ab700f90dc4922aee59cb271340d449084315d9317aab181043fb319fcaab3f10cf99aebd9a9e3af58fcf0c6e9a5360c136837dd4d22f15d67ed5a90a2ece1c72523830be28d64b7f965de353f0a" + ], + "objects": [], + "outcome": "refuse", + "reason": "notice_mismatch", + "at": [ + "record", + 2, + 0 + ] + }, + { + "name": "sor_incomplete", + "about": "a denial whose statement states no facts: the room accepts it, and its export cannot be written", + "descriptor": "57524431019b89c003531e6db01db74930211912642426603bbd818775ed2c016e03b358410768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317400406cd8e95d060040420f00000000000000100000000400000000005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f00000000000304686f7374000101011a08000000000000000000000000000000000000000000000000000000000000096d6f64657261746f72000101010a080000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000088130000020000000000000000000000006bef26b910d5eb61ee52ad327a27c556660c0ab972dca9e8ca881ac58e475db482835139318e5bc49903083e37b93c07dfc1c98a4bb97bc7798e0aab94345201", + "grants": [ + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a69ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c400000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000001010100000000000000000000000000000000000000000000000000000000000000000057455031011a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c65000098133cd6fb94618202b51f82d2223308fe8542970ed9cc60c90e9f586fb2b538793ed14bf1d870e9416419467d23637de92535775057b1bc7d5687a8e1f86c0f", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000010001010100000000000000000000000000000000000000000000000000000000000000000057455031010a080000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000633eb7991c5a5ba4f6ac6a3493f32b8323612ed3d918b275c250beff1f44320e14aaaa28bb4499e91e86c3f4dc9cd4a1364a14743780379acce02067c167ca0d", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990300000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c650000889f33bca67b3b49e644dd5cf3232879543c7a82d80223d5eb6fae44252488570f53b659c5e3e64ca8d67ee049a276ac753637f9c8276ab96f550dc74cfb2902", + "57524731014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a88ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836f00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011b68747470733a2f2f72656c61792e726f6f6d732e6578616d706c6500005ab38769b715a509c73eac8057c7b22fcf9d225627374c8f370e02b70b964f7d619686ff76cf83ad7629de95533cb85abedd393f3426e921a651c0c54a1f110d" + ], + "key_log": null, + "chains": [ + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400069ceaa0873a2ff574832dc33a8251e9642aff678895e417cb46b5bd8bbd654c4d8e5cafdceb3172c08beeacdcef6f12522cd50eb2b25d9cf0254148b8ff2b82f49f1a942099a7aeb66b447f05be0dc1ce483968200e9b07a00ac8691a0039fafa103d493f01c2114abb3407cd7a18d92c8ee680a2967ca424a7ea4c7ec69220b", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c317401000000000000006d5f4e5a83bea56252ae6d9ecb279ecc28231846e1a9e5032c06b951456789e70000000000000000001040006598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad6aaa0b1230b2dda876253111ac3257649d1823a89381e4e0d6faa7ea7f997947c2b9a674071b65ae1fcbb5771f1cd0be287c16038d1924a4275a75b839db2ebdd552e601ac7b4ff052cc3f2de12158006582128d0ab2b76dc9cda2923caccb0a", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c3174020000000000000022949f2a378f6bb4169ca450d01d1e58d538c5f2c062634ac7d4e8fd3709e39300000000000000000010400023c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c99034b3cc6d67456c5e47101dceacf5e2061766868cde904d93232c161a9b4383c836b149f0a41ec6c011f046f307662aec8906639b023851cdc45fc538268446b924d44cdf4eb56131b9948060f9f04033d052db3f7a896b5aed15a3bf020fe3400", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a0768608a31ba85b20c86c0975d527e7f8dde1ecb456a3a78d4f2370f615c31740300000000000000464c48f90c7245c1ea0f393c55cfc6b0e00362837622d40629310ab9e5a323f500000000000000000010400088ffa96f66e4ca247c7428b4c54fd7b5e2a92ac7e113dea013cd80008d54836fd7ffcc39e45de19b3f96e7ccb50c42d8adabaca8b9e5a68d8caf53bf5f6dfcad4ff9f0091167cf93d116eb4da13c64d3edf4f623367584cab8776c9309463dc9d9c8db7e10688f83a0943b4a514637e190a8b5c1cec2aab2c4c98f8fcc83660e" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903000000000000000000000000000000000000000000000000000000000000000000000000000000008096980000000000000321001f0068656c6c6f2065766572796f6e652c20676c616420746f20626520686572652179ca4fb59f0fcc4f4d1f28dc5a10e5e7ee7f29048faab9d832e05763c862e1835efb13da68df390fa840fdf503acea04f8bb3fbde2a647e97a26ed83f2b607", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c9903010000000000000051d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024e079af000000000000032d002b00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c20746f646179206f6e6c79e924fdb2592f0cb7289ac51819b9d7cefeadf5febd53b1a45d2d755696c8a21d0018e00a1d5b85b66cca8668144d41be96b9fa76c60f7ab606ed162efa8a5409", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a23c15f074664e24492be905b4f875508651bf2ffccbdc7343de811515e3c990302000000000000001b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04001bb7000000000000032e002c00636865617020666f6c6c6f776572732061742073686f702e6578616d706c652c206c617374206368616e6365c087dd22d55b52994160333d0de04201759500d37aafbb387bd5813f35bd825f0205cfb800ccfe711d737b7b8bdf14bc8beded47619b9aa15ed510fa0d4fd108" + ], + [ + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0000000000000000000000000000000000000000000000000000000000000000000000000000000020bcbe0000000000000b2300021b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04650068884365a60db2c8a761768153b2335b634a52017e576a7b61927673373e04078a235dc6380fbb2d7f5257f235ce18eecb7093dbd7d4a469557647d9a08be000", + "57455631014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad0100000000000000b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f20bcbe00000000000001e500574d5331010151d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf58430240000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010200007600546865206d657373616765206164766572746973657320612070616964207365727669636520746f2074686520726f6f6d2773207061727469636970616e74732c20776869636820636c6175736520342e32206f662074686520726f6f6d2773207465726d7320646f6573206e6f7420616c6c6f772e000049aab2f1609ec3892abd1c64d2b7132706c23b859fa65a00a0045acc7e6a5a6115d479ea911f49dbb5906db0323dc110fa48a3d26658aecb8a661cdc88f59a03" + ] + ], + "policies": [ + "574d5031014451792ccdaab8a816f98a1e390579bb5acf73e6c04a0ef053f72d6c24104d0a00000000000000000000000000000000000000000000000000000000000000000000000000000000016598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad01db39de57f50fa0881b4da69b4c6a00b92ee951e8a242cd5f30b9c9bc89a313f10101030188130000028403056500020a3000526f6f6d207465726d732c20636c6175736520342e323a206e6f20756e736f6c6963697465642070726f6d6f74696f6e1f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e32660002033500526f6f6d207465726d732c20636c6175736520342e313a206e6f206861726173736d656e74206f66207061727469636970616e74731f0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323342e31c90001052600526567756c6174696f6e202845552920323031362f3637392c2041727469636c65203628312900002d010107220044697265637469766520323030312f32392f45432c2041727469636c65203328312900008403020a5d00526f6f6d207465726d732c20636c6175736520363a2061206d6573736167652068656c6420666f722072657669657720616e64206e6f742072657669657765642062792069747320646561646c696e65206973206e6f742073686f776e1d0068747470733a2f2f726f6f6d732e6578616d706c652f7465726d7323361e4154424542474359435a4445444b45454553464946524752485248554945495349544c494c544c554c564d544e4c4e4f504c5054524f53455349534bb50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e240bb1d05cb5d21b9919345a9d7bbbebe2eed88abd920c57bd9e462e97669cc6c5cb1171274df6dbc44fdc420ba091b1752fd06966bf5e5dbd66ae0bdff2de05" + ], + "notices": [], + "objects": [], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f", + "decider": "6598a8c75f2741022fd5c143633a5b4f28c3f1235c5df9fa1b971390714a1cad", + "t": 12500000, + "target": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "verdict": "deny", + "reason": 101, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + } + ], + "items": [ + { + "digest": "51d8714b79ae0afdf450c45b85640e5f86d9ee3ba800ca22b92df7ebf5843024", + "target_type": "event", + "kind": "chat", + "t": 10000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 10000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 15000000, + "state": "fallback_deny", + "decision": null, + "visible": false + } + ] + }, + { + "digest": "1b00f2d809e38809a06df7e424ca8597d6d30eeacbfe9589493fc21470272b04", + "target_type": "event", + "kind": "chat", + "t": 11500000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 11500000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 12500000, + "state": "denied", + "decision": "b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f", + "visible": false + } + ] + }, + { + "digest": "acd48091ddbb9ca4011a809985f6d5e567342da791ca76ccbf6a6235efe9726f", + "target_type": "event", + "kind": "chat", + "t": 12000000, + "entry": { + "mode": "pre", + "deadline_ms": 5000, + "fallback": "deny" + }, + "timeline": [ + { + "t": 12000000, + "state": "held", + "decision": null, + "visible": false + }, + { + "t": 17000000, + "state": "fallback_deny", + "decision": null, + "visible": false + } + ] + } + ], + "exports": [ + { + "decision": "b6b400d40a8b01df2dcb15f03545536764aa0b63b0287cbaf85c7e8a9e690a8f", + "file": null, + "refuse": "sor_incomplete", + "member": "decision_facts" + } + ] + }, + { + "name": "redacted_segment", + "about": "live-recording's lesson session, its video reviewed after delivery: the director redacts chunk 3 of the performer's take", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000101011568747470733a2f2f72656c61792e6578616d706c654a00077375626a6563744000326239353662613939326462643264333664383166633461346137373162373034386237333261326533366365656132663537343438323136656635363663366bdb59c65869a0afca34a2621ee9aeeb703943d47add18510dde8e8f7fbf96ad1faf6f30d37f9c37c03d87cf28491ddd92dabefc125953bfcd8b826456f2f008" + ], + "key_log": "{\"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", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294ac027090000000000001040007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee5049ff9730d6dfe01fac966ac59ee80c8d6ac1ce5ba9dac9fa5a60bf00e04bfce0f1494867812a1eac7c3a700648ffb8a2053c117fa832b6e4173184336fb9ae826a7e590844f1ed6b0a45a95a624842543a78db51da7eea19082caf2d4db50a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7204000000000000003de0a8c521de91ada6dd32d8123ebe00830dca8fcfb0c094a23f9a0742cf664b40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101c70a1796b8b190c838cac4ae3e204d79b6c63fec99176e52eaf1d937c2e3e04962da79f57b2118c72193aa1104ebd3f4cf8f47ede24ddde2b63f2ec889d72a08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000fe14ebdfa829d20ed82d6404bf3b7dbda784978cdd900e37a8ba3be11dc5814640420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202035cf626357b5980930a4bec359a9241db0087ca63e35d3f2d98242ae76f33aeaad638ad984c68888dc4bc9d37a50e8b48307c180cefda5c1dd4e920740b245200", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7206000000000000001f0001f6fe0500b19e55c86925ca9973d4679f6c0e3e0d5ecb343b659f21958140420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520001000111842f2be19d36d7dd1f834be5008bdc85d528d455458b42badc9023a560fbc40e16aeb5572449ac83063d510a71d8eca3cbd619c40b5cbc926d86fbfbe32f03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720700000000000000d2a73fcea547e6900048baf298ef120df2de8993e5c2041358c5371690ce04fe40420f0000000000001224007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee00010101ee39477813a67f761b8434ffe739ef6c2399883396e47a40da89dd5ce08b3331e24c955ecc89c6a85914de460a348268d5c96eb1b66cc1785fc816885c327909" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee000000000000000000000000000000000000000000000000000000000000000000000000000000006018230000000000000c7e00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004039d2ffffffffff00f2e388c087c2503482a45e440d1fc88a7046ef2ec9f2c32484d09912a9d2a1824bbf932cd343d5efe6ce9e64cf5a31ab36a5994d1735156aaf89646c178db007", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0100000000000000f734b0ef8ac90053ae425a18c55654e92a6747ca5fea258637996adaa9ca3250802c800000000000000c7e00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960100000002f734b0ef8ac90053ae425a18c55654e92a6747ca5fea258637996adaa9ca325000000000000000000100000000000000ea1a9c44b721ca2a583fad19bca966298c4958034505c8143c6779e0b73bbd9e4039d2ffffffffff002fc21495251cb6ba873a003fd4cbb67353772f72f7607d68398df3c6895f07a5255a6f116b3713d3f7143316d71167fdbdb4aae682efb891ee7b46fc39f87307", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0200000000000000e1f805e1a054cfe57d4e303ff2dc073eb428c86c15e028e81921fafeda4a613200b19e0000000000000cbe00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960200000002e1f805e1a054cfe57d4e303ff2dc073eb428c86c15e028e81921fafeda4a61320100000000000000030000000000000075ea44294bf1e20d670345b52e104bd360523168f8b0046b23a6bae059558c5c4039d2ffffffffff02e1a39c21b47bc7d6c78d0678749d84614817a2fb9b0a7dcbf19e940ff564df98a0a547193b22c6cc66acb6f6c926bbb61155ada07da896581acf52eaab6c211209eea0f6ae94f642561a1d4c9e5cb400080d58ce43c59ccf82b4fc2ab4c9c8d9453751c4cbd593dd230524269cf968ec539d9c42815136dd72fc339e6ee7a600", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee030000000000000007fbbcdbbb53c31866316874c87c33bca4008c0b9ba53c8182b0f2a23941ca7e8035bd0000000000000cfe00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96030000000207fbbcdbbb53c31866316874c87c33bca4008c0b9ba53c8182b0f2a23941ca7e030000000000000005000000000000003935b6c803043cd12ec5bd53c252b49dfc9ca51a329fbc669de2c40288a414934039d2ffffffffff04a0a547193b22c6cc66acb6f6c926bbb61155ada07da896581acf52eaab6c21123ef26fe17f9c983fbd0f910c1b02459555aa96cf6bcb0b9b4ee374c6cbbb4890903e2f87b64d80ebb638e313ac851980a6667905bb6fca955b2786600ea9cc45c3213641a266ecdba0b17573dba5aa10ad9d831686d7e4e4248174f065e0c69614a5d3db02cbdfda2c0c90f024e5e45de8d413467ca32425ba485436a24c5fd395082402baff19b5eaac086cc072132c7fcb0d0f5389d046c4f1b89132597c01", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee040000000000000097618a571a9b984b4dedb9ee2a84c23b01f34575c3be407139b11b8f9c1db04300badb0000000000000cde00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96040000000297618a571a9b984b4dedb9ee2a84c23b01f34575c3be407139b11b8f9c1db043050000000000000006000000000000009a192de50070c39f440893ca66028c0fde3db238081fadf11e676d5cfd6e16bd4039d2ffffffffff03c3213641a266ecdba0b17573dba5aa10ad9d831686d7e4e4248174f065e0c696de40ac758d31d7dcaeff289171af8d3adc07c59cab6f3faaaae3ab769b9d9ce8c40d49c1602bd6fb0f81d107ddfcc04e9e08ba6bb91af36c94d2a7157e8b7a32ee420b433d82a151988b473df76d258d89b1f2e426a550cffd57fc8fa3752fb436a0fcd5e5b9e940e616761934cb813604bae3594ad72d8832ecc422fd1f9c03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0500000000000000857500f8ce56c356d7786b989c828ff62ae65be2cf879dc7b44e5d494dba7a8e20c5fb0000000000000cde00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960500000003857500f8ce56c356d7786b989c828ff62ae65be2cf879dc7b44e5d494dba7a8e060000000000000008000000000000005b8ad24298b11d4afe4acabf254c55d99e1badc4d20a3f293fef3c8e9870e6eb4039d2ffffffffff03d3b72f96114a9bdb8b730b48a4075a66d0b5c8641ad0c2e05e35a52e0baa7cb2b946fd25fcd2fff7393541ee8d0fd387535cd9280821cdabfe528936c6784e88c40d49c1602bd6fb0f81d107ddfcc04e9e08ba6bb91af36c94d2a7157e8b7a3252a926fc4f574281686592b21fed08f25de5ac61c6429b5804fc60f425a5f07b80d88001e264e3ca62527e81fc99f9bbaf306daff9691ba05af48f147177910c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd80841e0000000000000925007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee01a00f00005121655adf61434514263760a76b9b4909fea95cf84df358246bf3712e62690dd1ca2f54eec9545572fb3b98e322984b637d50fd9a4baca092d41a5d49569809", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52020000000000000033e0b0f17cbf9038a6f929902e62ba208c8957164db56d31f0688eacd208069b40548900000000000008160004000000020e00727573686564207468652072756e0099137ecc27e646730f76509258212e0f18b422e4b4e5982e2b1ae4ebcf9d3ed8540cc52e952d3ec327de71b01de1c757953e7d1a14d890882a8be5bca4bf900c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5203000000000000001b672fe4bc3a572db5fda9e00599d367fc34f2582d23c7d4d61a9ccc2849183f405dc600000000000008170004000000010f006c6f76656c79207068726173696e67002e5b8adea1bc333c1bd8a46175dc9ee01e588cab423c29b18694494e42ae558eaf9eea838f5143c1d611adba9b8920e6f72789ea15dab8f9400430bfea438807", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52040000000000000022090dd32799436ce8a82b6226a4f3c980342faee81feda1f24c5e33616d0d400024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502a8c64b918b366a3b85949c05ec973569bd951b08d1069f9348542d99b755d6a8309f0e2edd2c06cc753223a736826c5aa32770bceefb645caf8448f637ae7f0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5205000000000000001267edb63d9c6bd779859c7ba19959b6b2c05e3d8d7a53eb6adb5e26b213b2500024f40000000000000921007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee02f45f7600d7d10e68e30b0c7ac9ddcc886a9854e5e30946b9af5868d0cd56ef28d3ef6d84e880e21ef612fc0c383bb473d06da851e5b605495d68c9ca79e58204", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52060000000000000060a9eb9d304cb47fba7c2149f7586d78cf82cc8f996f66ff8d592bc81b3d598e002d310100000000000b230003b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb92d015ec099ffb4d196376bdef863f3dabad02713b33ca53e713ed48384a42e050f28fd8b7a65ccf098d0aeef10420509907f8b243fca686ca8f4b67dfa7279cf1d0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5207000000000000005d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f002d31010000000000018301574d5331010200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010100007300546865207365676d656e7420706c6179732061207265636f7264696e672070726f74656374656420627920636f707972696768742c2077686963682074686520726f6f6d20686f6c6473206e6f206c6963656e636520746f20636f6d6d756e696361746520746f20746865207075626c69632ea100416e20617564696f206d6174636820666c6167676564206120636f6d6d65726369616c207265636f7264696e6720706c6179696e6720626568696e642074686520706572666f726d657220647572696e67206368756e6b2033206f66207468652074616b653b20746865206469726563746f72206c697374656e656420746f20697420616e642072656d6f76656420746865206368756e6b20617420323020732e22bde9fe834d55f8acc7c99e70cb6b005578010025e697581618d73694b21f6d93f15b2eba2169e6e3162074b9ad5a162392db1cc8a1f48cecba4b60aaeeef0c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ] + ], + "policies": [ + "574d5031015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000102020260ea0000010000012d010107220044697265637469766520323030312f32392f45432c2041727469636c652033283129000003415444454652b50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e219d25686a04de408872c92c867f34bd93977ab1f405bfb16db543c6a6c8b28be73c59e97f3e63d3b65707c8ecd3e8abd98945efea4c190251f4e79d1899810c" + ], + "notices": [], + "objects": [ + { + "digest": "4388fed2f888a9d39be9b9aa64dbfc0612ea8644f5bfe4f70049ca0d9f90efef", + "media": 2, + "t": 8300000 + }, + { + "digest": "a23283680c1e79ea6a7e1313788e42a79c4215ca9e6ede3d34107603dd44cadc", + "media": 2, + "t": 8300000 + }, + { + "digest": "c261f4fd67c5cc77a8471309dc250c4cd5d17d2ed91f4c0d19b8cd3741deb8b9", + "media": 2, + "t": 10300000 + }, + { + "digest": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "media": 2, + "t": 10300000 + }, + { + "digest": "abb6ee130dffb53dd90971116164608ebf63507ddc92d7af724ca909df66775c", + "media": 2, + "t": 12300000 + }, + { + "digest": "42cf2390e19203569ebbfbb9a4ffedaa69546c681dfb5d0d1aff3c9d1f9437dd", + "media": 2, + "t": 12300000 + }, + { + "digest": "5d26b58c3a0fe012e42ab642d96c8129ff040aff8c390433c0ae5675e00c6ff0", + "media": 2, + "t": 14300000 + }, + { + "digest": "1db1c196a2f527259f64f0e99b2927a38b5eaa6ad637f580fb319c363450d3ff", + "media": 2, + "t": 14300000 + }, + { + "digest": "bac6a8ec79490e68bfffb69330405498af1953beef2ee58cfe1fcab7ce8ee07f", + "media": 2, + "t": 16400000 + }, + { + "digest": "bf2210dd82e38609a8652af2d572bfecbdd4f0020c4d783008920ab919f7590b", + "media": 2, + "t": 16400000 + } + ], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "decider": "d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52", + "t": 20000000, + "target": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "target_type": "object", + "verdict": "redact", + "reason": 301, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": true + } + ], + "items": [ + { + "digest": "4388fed2f888a9d39be9b9aa64dbfc0612ea8644f5bfe4f70049ca0d9f90efef", + "target_type": "object", + "kind": "video", + "t": 8300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 8300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 68300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "a23283680c1e79ea6a7e1313788e42a79c4215ca9e6ede3d34107603dd44cadc", + "target_type": "object", + "kind": "video", + "t": 8300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 8300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 68300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "c261f4fd67c5cc77a8471309dc250c4cd5d17d2ed91f4c0d19b8cd3741deb8b9", + "target_type": "object", + "kind": "video", + "t": 10300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 10300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 70300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "target_type": "object", + "kind": "video", + "t": 10300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 10300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 20000000, + "state": "redacted", + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "visible": false + } + ] + }, + { + "digest": "abb6ee130dffb53dd90971116164608ebf63507ddc92d7af724ca909df66775c", + "target_type": "object", + "kind": "video", + "t": 12300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 12300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 72300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "42cf2390e19203569ebbfbb9a4ffedaa69546c681dfb5d0d1aff3c9d1f9437dd", + "target_type": "object", + "kind": "video", + "t": 12300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 12300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 72300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "5d26b58c3a0fe012e42ab642d96c8129ff040aff8c390433c0ae5675e00c6ff0", + "target_type": "object", + "kind": "video", + "t": 14300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 14300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 74300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "1db1c196a2f527259f64f0e99b2927a38b5eaa6ad637f580fb319c363450d3ff", + "target_type": "object", + "kind": "video", + "t": 14300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 14300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 74300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "bac6a8ec79490e68bfffb69330405498af1953beef2ee58cfe1fcab7ce8ee07f", + "target_type": "object", + "kind": "video", + "t": 16400000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 16400000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 76400000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "bf2210dd82e38609a8652af2d572bfecbdd4f0020c4d783008920ab919f7590b", + "target_type": "object", + "kind": "video", + "t": 16400000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 16400000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 76400000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "file": "redacted_segment.d0.sor.json" + } + ] + }, + { + "name": "redaction_reversed", + "about": "the same room after the performer's complaint and the director's decision restoring the chunk", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "grants": [ + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5200000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a00000000000101020b00000000000000000000000000000000000000000000000000000000000000000057455031011a0f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000100011568747470733a2f2f72656c61792e6578616d706c650000a6d55133ccc1ee02980a7f731208746f5d4e186c9c01081b529cb5b7ab35e78fdb9f1462a627082e401b8c579d9efccb2318daefc273d59ffc2709f9fb48c70a", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff000000020102011568747470733a2f2f72656c61792e6578616d706c655900086665617475726564040074727565077375626a656374400035393432353436353030343530303033326436383933663938306137646164343833616637306234653131366131306237636161346532303532353933363939543fbef56edc49e6b3c29295d7e0529fd464ebf046dfa2e1fd4db3bdb93af7346ef665560cc44fd23978ca4c24f0da660a50dcd846ed1a8647c0d00446cd2502", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000200010100000000000000000000000000000000000000000000000000000000000000000000574550310118000000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff00000000011568747470733a2f2f72656c61792e6578616d706c65000056fb21a81ef4d7ee9c3a0396274535a17aa69369c753afaa8b825aed8e979f7a48884c1d3b8bc2c64679ec82eff38166c0df7c76ab5de60c393a1273ce422a06", + "57524731015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee00000000000000000000000000000000000000000000000000000000000000000000000000000000f05ad16a0000000080bad26a000000000103010200000000000000000000000000000000000000000000000000000000000000000000574550310118110000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f0000000000ffffffffffffffffffffffffffffffff0000000101011568747470733a2f2f72656c61792e6578616d706c654a00077375626a6563744000326239353662613939326462643264333664383166633461346137373162373034386237333261326533366365656132663537343438323136656635363663366bdb59c65869a0afca34a2621ee9aeeb703943d47add18510dde8e8f7fbf96ad1faf6f30d37f9c37c03d87cf28491ddd92dabefc125953bfcd8b826456f2f008" + ], + "key_log": "{\"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", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7203000000000000004dfe996a8c2cb1d606032e1048652cf210c7d866d6110013ac6df7b64e61294ac027090000000000001040007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee5049ff9730d6dfe01fac966ac59ee80c8d6ac1ce5ba9dac9fa5a60bf00e04bfce0f1494867812a1eac7c3a700648ffb8a2053c117fa832b6e4173184336fb9ae826a7e590844f1ed6b0a45a95a624842543a78db51da7eea19082caf2d4db50a", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7204000000000000003de0a8c521de91ada6dd32d8123ebe00830dca8fcfb0c094a23f9a0742cf664b40420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500010101c70a1796b8b190c838cac4ae3e204d79b6c63fec99176e52eaf1d937c2e3e04962da79f57b2118c72193aa1104ebd3f4cf8f47ede24ddde2b63f2ec889d72a08", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720500000000000000fe14ebdfa829d20ed82d6404bf3b7dbda784978cdd900e37a8ba3be11dc5814640420f000000000000122400e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5000202035cf626357b5980930a4bec359a9241db0087ca63e35d3f2d98242ae76f33aeaad638ad984c68888dc4bc9d37a50e8b48307c180cefda5c1dd4e920740b245200", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7206000000000000001f0001f6fe0500b19e55c86925ca9973d4679f6c0e3e0d5ecb343b659f21958140420f000000000000122400d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520001000111842f2be19d36d7dd1f834be5008bdc85d528d455458b42badc9023a560fbc40e16aeb5572449ac83063d510a71d8eca3cbd619c40b5cbc926d86fbfbe32f03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b720700000000000000d2a73fcea547e6900048baf298ef120df2de8993e5c2041358c5371690ce04fe40420f0000000000001224007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee00010101ee39477813a67f761b8434ffe739ef6c2399883396e47a40da89dd5ce08b3331e24c955ecc89c6a85914de460a348268d5c96eb1b66cc1785fc816885c327909" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca78a50426ccfca7ce958e1c52db484fc712687799e1ff84bc4cdd4182aad891c600000000000000000000000000000000000000000000000000000000000000000000000000000000a02526000000000000030b000900676f6f64206c75636b6417feb3fb6578be2bd1d5c4637abd7c659c3457bb2e8281a5a3f5b3faae8c06fe11623662a96528d54180df0d465b94517f3ed4ea0c7f10d6e0257783eb310c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee000000000000000000000000000000000000000000000000000000000000000000000000000000006018230000000000000c7e00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004039d2ffffffffff00f2e388c087c2503482a45e440d1fc88a7046ef2ec9f2c32484d09912a9d2a1824bbf932cd343d5efe6ce9e64cf5a31ab36a5994d1735156aaf89646c178db007", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0100000000000000f734b0ef8ac90053ae425a18c55654e92a6747ca5fea258637996adaa9ca3250802c800000000000000c7e00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960100000002f734b0ef8ac90053ae425a18c55654e92a6747ca5fea258637996adaa9ca325000000000000000000100000000000000ea1a9c44b721ca2a583fad19bca966298c4958034505c8143c6779e0b73bbd9e4039d2ffffffffff002fc21495251cb6ba873a003fd4cbb67353772f72f7607d68398df3c6895f07a5255a6f116b3713d3f7143316d71167fdbdb4aae682efb891ee7b46fc39f87307", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0200000000000000e1f805e1a054cfe57d4e303ff2dc073eb428c86c15e028e81921fafeda4a613200b19e0000000000000cbe00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960200000002e1f805e1a054cfe57d4e303ff2dc073eb428c86c15e028e81921fafeda4a61320100000000000000030000000000000075ea44294bf1e20d670345b52e104bd360523168f8b0046b23a6bae059558c5c4039d2ffffffffff02e1a39c21b47bc7d6c78d0678749d84614817a2fb9b0a7dcbf19e940ff564df98a0a547193b22c6cc66acb6f6c926bbb61155ada07da896581acf52eaab6c211209eea0f6ae94f642561a1d4c9e5cb400080d58ce43c59ccf82b4fc2ab4c9c8d9453751c4cbd593dd230524269cf968ec539d9c42815136dd72fc339e6ee7a600", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee030000000000000007fbbcdbbb53c31866316874c87c33bca4008c0b9ba53c8182b0f2a23941ca7e8035bd0000000000000cfe00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96030000000207fbbcdbbb53c31866316874c87c33bca4008c0b9ba53c8182b0f2a23941ca7e030000000000000005000000000000003935b6c803043cd12ec5bd53c252b49dfc9ca51a329fbc669de2c40288a414934039d2ffffffffff04a0a547193b22c6cc66acb6f6c926bbb61155ada07da896581acf52eaab6c21123ef26fe17f9c983fbd0f910c1b02459555aa96cf6bcb0b9b4ee374c6cbbb4890903e2f87b64d80ebb638e313ac851980a6667905bb6fca955b2786600ea9cc45c3213641a266ecdba0b17573dba5aa10ad9d831686d7e4e4248174f065e0c69614a5d3db02cbdfda2c0c90f024e5e45de8d413467ca32425ba485436a24c5fd395082402baff19b5eaac086cc072132c7fcb0d0f5389d046c4f1b89132597c01", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee040000000000000097618a571a9b984b4dedb9ee2a84c23b01f34575c3be407139b11b8f9c1db04300badb0000000000000cde00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d96040000000297618a571a9b984b4dedb9ee2a84c23b01f34575c3be407139b11b8f9c1db043050000000000000006000000000000009a192de50070c39f440893ca66028c0fde3db238081fadf11e676d5cfd6e16bd4039d2ffffffffff03c3213641a266ecdba0b17573dba5aa10ad9d831686d7e4e4248174f065e0c696de40ac758d31d7dcaeff289171af8d3adc07c59cab6f3faaaae3ab769b9d9ce8c40d49c1602bd6fb0f81d107ddfcc04e9e08ba6bb91af36c94d2a7157e8b7a32ee420b433d82a151988b473df76d258d89b1f2e426a550cffd57fc8fa3752fb436a0fcd5e5b9e940e616761934cb813604bae3594ad72d8832ecc422fd1f9c03", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca7d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee0500000000000000857500f8ce56c356d7786b989c828ff62ae65be2cf879dc7b44e5d494dba7a8e20c5fb0000000000000cde00fef202dc0b11f9dbebe831ff51d297dc7ab644f0d5341d87dc95c939721a9d960500000003857500f8ce56c356d7786b989c828ff62ae65be2cf879dc7b44e5d494dba7a8e060000000000000008000000000000005b8ad24298b11d4afe4acabf254c55d99e1badc4d20a3f293fef3c8e9870e6eb4039d2ffffffffff03d3b72f96114a9bdb8b730b48a4075a66d0b5c8641ad0c2e05e35a52e0baa7cb2b946fd25fcd2fff7393541ee8d0fd387535cd9280821cdabfe528936c6784e88c40d49c1602bd6fb0f81d107ddfcc04e9e08ba6bb91af36c94d2a7157e8b7a3252a926fc4f574281686592b21fed08f25de5ac61c6429b5804fc60f425a5f07b80d88001e264e3ca62527e81fc99f9bbaf306daff9691ba05af48f147177910c" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520000000000000000000000000000000000000000000000000000000000000000000000000000000080841e000000000000092500e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f501a00f0000fccfdaad37227a751f2c374c994a9ec76edab94ac0c3ffc186229f9fe7c579639a49d4520725a3d74b42b0139bb99cdd4a0a56cfce8c507fa8233bd6603bab0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520100000000000000a23aa809cbe525bc1baf27797870ec0dcf440b60fa739c2314788c7b102e69fd80841e0000000000000925007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee01a00f00005121655adf61434514263760a76b9b4909fea95cf84df358246bf3712e62690dd1ca2f54eec9545572fb3b98e322984b637d50fd9a4baca092d41a5d49569809", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52020000000000000033e0b0f17cbf9038a6f929902e62ba208c8957164db56d31f0688eacd208069b40548900000000000008160004000000020e00727573686564207468652072756e0099137ecc27e646730f76509258212e0f18b422e4b4e5982e2b1ae4ebcf9d3ed8540cc52e952d3ec327de71b01de1c757953e7d1a14d890882a8be5bca4bf900c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5203000000000000001b672fe4bc3a572db5fda9e00599d367fc34f2582d23c7d4d61a9ccc2849183f405dc600000000000008170004000000010f006c6f76656c79207068726173696e67002e5b8adea1bc333c1bd8a46175dc9ee01e588cab423c29b18694494e42ae558eaf9eea838f5143c1d611adba9b8920e6f72789ea15dab8f9400430bfea438807", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52040000000000000022090dd32799436ce8a82b6226a4f3c980342faee81feda1f24c5e33616d0d400024f4000000000000092100e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f502a8c64b918b366a3b85949c05ec973569bd951b08d1069f9348542d99b755d6a8309f0e2edd2c06cc753223a736826c5aa32770bceefb645caf8448f637ae7f0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5205000000000000001267edb63d9c6bd779859c7ba19959b6b2c05e3d8d7a53eb6adb5e26b213b2500024f40000000000000921007d3b3098d82fddc8585faa3e84b8f2c13cb7fc723a01bfb8bbacfba4ed388eee02f45f7600d7d10e68e30b0c7ac9ddcc886a9854e5e30946b9af5868d0cd56ef28d3ef6d84e880e21ef612fc0c383bb473d06da851e5b605495d68c9ca79e58204", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52060000000000000060a9eb9d304cb47fba7c2149f7586d78cf82cc8f996f66ff8d592bc81b3d598e002d310100000000000b230003b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb92d015ec099ffb4d196376bdef863f3dabad02713b33ca53e713ed48384a42e050f28fd8b7a65ccf098d0aeef10420509907f8b243fca686ca8f4b67dfa7279cf1d0e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5207000000000000005d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f002d31010000000000018301574d5331010200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010100007300546865207365676d656e7420706c6179732061207265636f7264696e672070726f74656374656420627920636f707972696768742c2077686963682074686520726f6f6d20686f6c6473206e6f206c6963656e636520746f20636f6d6d756e696361746520746f20746865207075626c69632ea100416e20617564696f206d6174636820666c6167676564206120636f6d6d65726369616c207265636f7264696e6720706c6179696e6720626568696e642074686520706572666f726d657220647572696e67206368756e6b2033206f66207468652074616b653b20746865206469726563746f72206c697374656e656420746f20697420616e642072656d6f76656420746865206368756e6b20617420323020732e22bde9fe834d55f8acc7c99e70cb6b005578010025e697581618d73694b21f6d93f15b2eba2169e6e3162074b9ad5a162392db1cc8a1f48cecba4b60aaeeef0c", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c5208000000000000001b644959eb4d1f4fdf6df0251a0154bed648010e86500de8ddcd2c5d1e55c3d4005a620200000000000b230001b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb92d01903a4dabc65c9be2a20bf6e41f748430fac1b65b74909b4f8ae00b24a44d81b440da01558044e9b91e866ab40b7ecafd0ff9fec6edccc2ec088959950ce16608", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cad927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c520900000000000000cd4a172e1993281f91b7401d9e96b623739ed83da837c6195e4ad74ccf8b3c64005a62020000000000014301574d5331010200000000000000000000000000000000000000000000000000000000000000005d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f0355ca2abec2c27611728b8e54bb5c2d72ef198282432d4f21b69bc4adc4611b04000100007600546865206c6963656e636520636f7665727320636f6d6d756e69636174696e672074686520747261636b20746f20746865207075626c696320696e2074686520706572666f726d65722773206c6573736f6e732c20736f20746865207365676d656e7420696e6672696e676573206e6f7468696e672e5e0054686520636f6d706c61696e74206761766520746865206c6963656e63653b20746865206469726563746f7220636865636b656420697473207465726d7320616e6420726573746f72656420746865206368756e6b20617420343020732e4fcd734e6d42ded1f7df9b8670849327265137f972eab1ffad49b1de9c1263aa377e71b2c3ece14dff6cef138ec2ce708f23c11cb80e24b3da1db67f6a7c6105" + ], + [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ] + ], + "policies": [ + "574d5031015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000102020260ea0000010000012d010107220044697265637469766520323030312f32392f45432c2041727469636c652033283129000003415444454652b50041207061727469636970616e742077686f7365206d65737361676520697320726573747269637465642063616e20636f6d706c61696e2077697468696e20736978206d6f6e7468732062792061207369676e656420636f6d706c61696e74206e616d696e6720746865206465636973696f6e3b206f75742d6f662d636f757274206469737075746520736574746c656d656e7420616e64206a7564696369616c20726564726573732072656d61696e206f70656e2e219d25686a04de408872c92c867f34bd93977ab1f405bfb16db543c6a6c8b28be73c59e97f3e63d3b65707c8ecd3e8abd98945efea4c190251f4e79d1899810c" + ], + "notices": [ + "574d4e31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca02015d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f80c3c90100000000000100006f00546865207265636f7264696e6720696e20746865206261636b67726f756e64206973206120707261637469636520747261636b206c6963656e73656420746f2074686520706572666f726d657220666f72206c6573736f6e7320616e64207468656972207265636f7264696e67732e000059425465004500032d6893f980a7dad483af70b4e116a10b7caa4e20525936992edd7e3d38fe7a94ff606de443437186e86aec4ed5498c318c68f915693eab7e1d53e276d6dd7310bd80ef9c64a4116e0dae24b4afbdff3184165c916c51450b" + ], + "objects": [ + { + "digest": "4388fed2f888a9d39be9b9aa64dbfc0612ea8644f5bfe4f70049ca0d9f90efef", + "media": 2, + "t": 8300000 + }, + { + "digest": "a23283680c1e79ea6a7e1313788e42a79c4215ca9e6ede3d34107603dd44cadc", + "media": 2, + "t": 8300000 + }, + { + "digest": "c261f4fd67c5cc77a8471309dc250c4cd5d17d2ed91f4c0d19b8cd3741deb8b9", + "media": 2, + "t": 10300000 + }, + { + "digest": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "media": 2, + "t": 10300000 + }, + { + "digest": "abb6ee130dffb53dd90971116164608ebf63507ddc92d7af724ca909df66775c", + "media": 2, + "t": 12300000 + }, + { + "digest": "42cf2390e19203569ebbfbb9a4ffedaa69546c681dfb5d0d1aff3c9d1f9437dd", + "media": 2, + "t": 12300000 + }, + { + "digest": "5d26b58c3a0fe012e42ab642d96c8129ff040aff8c390433c0ae5675e00c6ff0", + "media": 2, + "t": 14300000 + }, + { + "digest": "1db1c196a2f527259f64f0e99b2927a38b5eaa6ad637f580fb319c363450d3ff", + "media": 2, + "t": 14300000 + }, + { + "digest": "bac6a8ec79490e68bfffb69330405498af1953beef2ee58cfe1fcab7ce8ee07f", + "media": 2, + "t": 16400000 + }, + { + "digest": "bf2210dd82e38609a8652af2d572bfecbdd4f0020c4d783008920ab919f7590b", + "media": 2, + "t": 16400000 + } + ], + "outcome": "accept", + "room_outcome": "accept", + "gaps": [], + "explained": [], + "decisions": [ + { + "digest": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "decider": "d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52", + "t": 20000000, + "target": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "target_type": "object", + "verdict": "redact", + "reason": 301, + "statement": "known", + "basis": "own", + "supersedes": null, + "notice": null, + "standing": false + }, + { + "digest": "cd4a172e1993281f91b7401d9e96b623739ed83da837c6195e4ad74ccf8b3c64", + "decider": "d927eb9f5070076df3e4dc37934542e59028145ef587af8e71dc001a4ba81c52", + "t": 40000000, + "target": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "target_type": "object", + "verdict": "allow", + "reason": 301, + "statement": "known", + "basis": "complaint", + "supersedes": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "notice": "55ca2abec2c27611728b8e54bb5c2d72ef198282432d4f21b69bc4adc4611b04", + "standing": true + } + ], + "items": [ + { + "digest": "4388fed2f888a9d39be9b9aa64dbfc0612ea8644f5bfe4f70049ca0d9f90efef", + "target_type": "object", + "kind": "video", + "t": 8300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 8300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 68300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "a23283680c1e79ea6a7e1313788e42a79c4215ca9e6ede3d34107603dd44cadc", + "target_type": "object", + "kind": "video", + "t": 8300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 8300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 68300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "c261f4fd67c5cc77a8471309dc250c4cd5d17d2ed91f4c0d19b8cd3741deb8b9", + "target_type": "object", + "kind": "video", + "t": 10300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 10300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 70300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "b4d1f5a4d7a65adf085ec760c03cbee8881a4642b2e75faac4f4e0abc129ccb9", + "target_type": "object", + "kind": "video", + "t": 10300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 10300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 20000000, + "state": "redacted", + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "visible": false + }, + { + "t": 40000000, + "state": "allowed", + "decision": "cd4a172e1993281f91b7401d9e96b623739ed83da837c6195e4ad74ccf8b3c64", + "visible": true + } + ] + }, + { + "digest": "abb6ee130dffb53dd90971116164608ebf63507ddc92d7af724ca909df66775c", + "target_type": "object", + "kind": "video", + "t": 12300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 12300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 72300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "42cf2390e19203569ebbfbb9a4ffedaa69546c681dfb5d0d1aff3c9d1f9437dd", + "target_type": "object", + "kind": "video", + "t": 12300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 12300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 72300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "5d26b58c3a0fe012e42ab642d96c8129ff040aff8c390433c0ae5675e00c6ff0", + "target_type": "object", + "kind": "video", + "t": 14300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 14300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 74300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "1db1c196a2f527259f64f0e99b2927a38b5eaa6ad637f580fb319c363450d3ff", + "target_type": "object", + "kind": "video", + "t": 14300000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 14300000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 74300000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "bac6a8ec79490e68bfffb69330405498af1953beef2ee58cfe1fcab7ce8ee07f", + "target_type": "object", + "kind": "video", + "t": 16400000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 16400000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 76400000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + }, + { + "digest": "bf2210dd82e38609a8652af2d572bfecbdd4f0020c4d783008920ab919f7590b", + "target_type": "object", + "kind": "video", + "t": 16400000, + "entry": { + "mode": "post", + "deadline_ms": 60000, + "fallback": "allow" + }, + "timeline": [ + { + "t": 16400000, + "state": "pending", + "decision": null, + "visible": true + }, + { + "t": 76400000, + "state": "fallback_allow", + "decision": null, + "visible": true + } + ] + } + ], + "exports": [ + { + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f", + "file": "redaction_reversed.d0.sor.json" + }, + { + "decision": "cd4a172e1993281f91b7401d9e96b623739ed83da837c6195e4ad74ccf8b3c64", + "file": null + } + ] + } + ], + "clips": [ + { + "name": "clip_withheld", + "about": "chunks 2 to 5 of the performer's take, the redacted chunk 3 withheld: the range proof verifies over all four", + "room": "redacted_segment", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "record": "57434c31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca00127a0000000000001bb7000000000001e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f541f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f250200000000000000040000000000000000000000000000000000000002000000000000000004802a0100000040468f2a010000003a0000000000000097f5ee9829746c16c29946a44489846e4a385eb6d62804ba22a18a99a92642ab030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a4803880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1bd75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9ddd6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bdcf465481994918ce5ace4641f4e4d1ac2704d40f0a6c2e0ed1787145cfb38788499855a50ac018e3aaf2cd0773b05230a2b8a1a805c69bd7061b0aac63d14508", + "parts": [ + { + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "commits": [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ], + "bytes": [ + "48ebf0b168a3c7fc0c55b3c91416022da660a350dd70aef26ddc6a124ed3f89554cbaa4b0a623251e046c5d051bb2184160fb0d45061c051e7cc", + null, + "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43", + "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + ] + } + ], + "outcome": "accept", + "clip": "e631e431d2f0280ab344d5a5fb7e2c3e2b9c7e1fdd555d03dc931d0f764b2fc2", + "signer": "d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd", + "window": [ + 8000000, + 12000000 + ], + "bound_us": 500000, + "facts": [ + { + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "first": 2, + "count": 4, + "offset": -5000000000, + "span": [ + 8000000, + 12000000 + ], + "device_window": [ + 5008000000, + 5012000000 + ], + "bytes": 231, + "sha256": "8d86949a6b6abf60ea539ad06265f890528a83a06a2402e5e1a21491c1cdc64c", + "withheld": [ + { + "index": 3, + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f" + } + ] + } + ] + }, + { + "name": "clip_trimmed_withheld", + "about": "a byte range from inside the redacted chunk 3 to inside chunk 5: the trim at the withheld chunk is not applied", + "room": "redacted_segment", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "record": "57434c31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca4054890000000000001bb7000000000001e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f541f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f250300000000000000030000000a000000000000001400000000000000030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a4804c261f4fd67c5cc77a8471309dc250c4cd5d17d2ed91f4c0d19b8cd3741deb8b9880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1bd75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9ddd6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd4f037c5223e9570edc98f9fbf8b9f3f4c18c7fb703142058260b64fcac42ee447e9a72f86a2d5a652cd0a22fd00cea6eed18242197e45edb9e86ec453cce4102", + "parts": [ + { + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "commits": [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ], + "bytes": [ + null, + "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43", + "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + ] + } + ], + "outcome": "accept", + "clip": "485a36a2215fb0cc1385c5fe67d21de926034ea1a228cf60deb7496529c09d4f", + "signer": "d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd", + "window": [ + 9000000, + 12000000 + ], + "bound_us": 500000, + "facts": [ + { + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "first": 3, + "count": 3, + "offset": -5000000000, + "span": [ + 9000000, + 12000000 + ], + "device_window": [ + 5009000000, + 5012000000 + ], + "bytes": 153, + "sha256": "aea970b3b5a38363527a4620ba25b3307e5ccc22467722807a059716d6af7180", + "withheld": [ + { + "index": 3, + "decision": "5d5a4a8c74ede0dbcb2015db0d168a37752f9ce23652e9eef5ae967ba46cd64f" + } + ] + } + ] + }, + { + "name": "clip_redaction_not_applied", + "about": "the same chunks with the redacted chunk's bytes given", + "room": "redacted_segment", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "record": "57434c31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca00127a0000000000001bb7000000000001e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f541f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f250200000000000000040000000000000000000000000000000000000002000000000000000004802a0100000040468f2a010000003a0000000000000097f5ee9829746c16c29946a44489846e4a385eb6d62804ba22a18a99a92642ab030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a4803880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1bd75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9ddd6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bdcf465481994918ce5ace4641f4e4d1ac2704d40f0a6c2e0ed1787145cfb38788499855a50ac018e3aaf2cd0773b05230a2b8a1a805c69bd7061b0aac63d14508", + "parts": [ + { + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "commits": [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ], + "bytes": [ + "48ebf0b168a3c7fc0c55b3c91416022da660a350dd70aef26ddc6a124ed3f89554cbaa4b0a623251e046c5d051bb2184160fb0d45061c051e7cc", + "b89715796bae21b2526339343c05418d5d89c863b331588fe0005f588148aca6c1d6f8fabc0c1453628552025d98e640e92c6e1bc36306e50db0fe471ca92773b96f17ab3617a16f0685f0135d6f061965e8a49060fd5fc6fb32e22e2dd9fa", + "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43", + "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + ] + } + ], + "outcome": "refuse", + "reason": "redaction_not_applied", + "at": [ + "chunk", + 0, + 1 + ] + }, + { + "name": "clip_restored_missing", + "about": "after the appeal restores chunk 3, a clip that still leaves it out", + "room": "redaction_reversed", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "record": "57434c31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca00127a0000000000001bb7000000000001e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f541f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f250200000000000000040000000000000000000000000000000000000002000000000000000004802a0100000040468f2a010000003a0000000000000097f5ee9829746c16c29946a44489846e4a385eb6d62804ba22a18a99a92642ab030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a4803880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1bd75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9ddd6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bdcf465481994918ce5ace4641f4e4d1ac2704d40f0a6c2e0ed1787145cfb38788499855a50ac018e3aaf2cd0773b05230a2b8a1a805c69bd7061b0aac63d14508", + "parts": [ + { + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "commits": [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ], + "bytes": [ + "48ebf0b168a3c7fc0c55b3c91416022da660a350dd70aef26ddc6a124ed3f89554cbaa4b0a623251e046c5d051bb2184160fb0d45061c051e7cc", + null, + "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43", + "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + ] + } + ], + "outcome": "refuse", + "reason": "clip_chunk_missing", + "at": [ + "chunk", + 0, + 1 + ] + }, + { + "name": "clip_restored_whole", + "about": "after the appeal, the clip with every chunk's bytes", + "room": "redaction_reversed", + "descriptor": "5752443101d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd0a29cf514deebfd5ca029b1d658b198bade764af98e09848c6fd53b129678b7200406cd8e95d060040420f0000000000170068747470733a2f2f6c6573736f6e732e6578616d706c650800000003002c0100005745503101fe1f0000000000000000000000000000000000000000000000000000000000000004f4013200000040420f00000000000100000040420f000000000003086469726563746f720101020b1a0f00000000000000000000000000000000000000000000000000000000000009706572666f726d65720301020018110000000000000000000000000000000000000000000000000000000000000861756469656e63650001010018000000000000000000000000000000000000000000000000000000000000000003067370656563680101046f707573000001000000000000100000004000000080bb0000010f056d757369630101046f70757300000100000000000080000000fe01000080bb000002000b63616d6572612d3130383002020d617630312e302e30384d2e30380b617663312e363430303238010003800268011e0096000000f40100000005d0021e00f4010000dc050000800738041e00dc050000a00f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e00d0070000f401000002444546522c74e5c056bb1b6f962b4f7da37965c09b1753128837f7b1667991716b3a291d8f4a5b9303941d108fe20b89be7321d556fc9952d102095aaae736247edc540d", + "record": "57434c31015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974ca00127a0000000000001bb7000000000001e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f541f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e5c8b70c3a2bcef603d7df6edc44efe9a9dc4f2aa92c7c5fb23414057b21c10e80a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f250200000000000000040000000000000000000000000000000000000002000000000000000004802a0100000040468f2a010000003a0000000000000097f5ee9829746c16c29946a44489846e4a385eb6d62804ba22a18a99a92642ab030000000000000040468f2a0100000080889e2a010000005f000000000000004bb0df0483b6370199dc9196f695ec65b029d8ffb09dfd7ec24bf5d5c59a72f3040000000000000080889e2a01000000c0caad2a010000004400000000000000733b22d5d80b9a80443b60a14334000a8ab43f139364fa9cd3a547e8a7c523640500000000000000c0caad2a01000000000dbd2a0100000069000000000000009395a39fcaaab116f14a5e4f1e51abe694d712e0f912827045471c6283730a4803880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1bd75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9ddd6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bdcf465481994918ce5ace4641f4e4d1ac2704d40f0a6c2e0ed1787145cfb38788499855a50ac018e3aaf2cd0773b05230a2b8a1a805c69bd7061b0aac63d14508", + "parts": [ + { + "device": "e57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5", + "commits": [ + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f500000000000000000000000000000000000000000000000000000000000000000000000000000000c091210000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e00000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efad5feffffff00b225c83a2ca0425ec89b11dd2b1e0ed0e6e7efdd631b6f710d677202d7a0cef1e45393eb7b2bb9cbb81512fb3e06fde8ec83eb80922a929d9c5a54945d38d50e", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50100000000000000d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e6e0a57e0000000000000c7e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0100000002d01b2ceb50bf890fd1732ca8571fbc36528777c1700f022f152a107036ad41e600000000000000000200000000000000880211aa301be185e15a6c1895c2d43367360f1104ca7e72fa3c576cf0437c1b000efad5feffffff004925dc67c54d87781c324edf555bdb731b121cbd675b33fc8cd2701b3b411bb2811310a25be4cb8d5863bbaa9454d63d7424c75c59e30befe4f8b586269ac003", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50200000000000000e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b0602a9d0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0200000002e66ae4f48b7d7b0f1d68ad2108e1004b82599f70aeefc04750889da9ea5049b002000000000000000400000000000000c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00000efad5feffffff01bbf572927af2d03d45aa66c8f630bda9d29429e07e09a3a3d6c9a8d93332624434d5c46a8ec9252c35de44a3697254601dcbc25dec5af9ed2114f05ac64dacb79637cce6bf3e1a0e651af68894e3b832aeb050ef19ce5853242b441e9a7ebd07", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f50300000000000000108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e4002621e0aebb0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e0300000002108de42c4bee54b94f97054909bc94cea6a6a65a2c9eb30090b514a7e400262104000000000000000600000000000000249f88d1dcac0f7d98b53d89fdbeb22c284ffc97c90ff18a1ee27980e3ce88bd000efad5feffffff01eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a218665fd17bff9911efed8a34e7165ddf2aae8d8f94f6fb44156d1c5929ff8186922b9f24e714834b5de5968e07dc0e7e5d4565ad95ef76ecc80b6803e017b6205", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f5040000000000000039c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe46033da0000000000000cde0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e040000000239c62d2ccabc3770a207fa1560cb87d69299f7d78119a46d300a0fcc81251fe406000000000000000800000000000000cef53df7a17ba27234381bf4fb47ad712b9f2aab80d4f837db1155d18af26a55000efad5feffffff03eb6ddc57c1c32eeef5f7ff5f2a73f33e16684a4b4249d3cb0b99f72adb199a21d75f76241ecda381c6d8d9232daab10b13803e2fe52ab86871c6bca67199fef3c6cda45663cd175aa9ba5f30289803a8059baa9924a9f919ef40d91902ca7e00ee5e6803bd5d5229a44bc456a97836a6bb5365652b2a68a6f570dfc0451a1fb0fd86776b39cc3bfed05f80580257a8142429100ac7f6635136afca694e9dc005", + "57455631015f7bde3d64b102ebfb82fb02abbba177fd67bdd1e1766b22969af847746974cae57d3fbe7257b2118009296bf654b41c7823e730f86568799b01b442d7a300f505000000000000008967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad803efa0000000000000c9e0041f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e05000000038967cc4ff845c3efd0139b621aa7202a890aaac2ad7e6978a6c725c0a0acc2ad08000000000000000a000000000000008883ea090e9f374f91bacaac0864af7b6dafa57c4f8a3ac0040ec7fc669f1f25000efad5feffffff01b09aef291cbbb9927cefbbb3a26f4c2d4689a03a6b1cc7f938ce9c615890e9dd4393ecb00dac808558942659c01f4b61f0abc468ff7dd55a14b8002cb0a5f4da016d9a2f03e1592b1ce19f95b2bc7086380ecc92f6745a0e4e758b79041cee0d" + ], + "bytes": [ + "48ebf0b168a3c7fc0c55b3c91416022da660a350dd70aef26ddc6a124ed3f89554cbaa4b0a623251e046c5d051bb2184160fb0d45061c051e7cc", + "b89715796bae21b2526339343c05418d5d89c863b331588fe0005f588148aca6c1d6f8fabc0c1453628552025d98e640e92c6e1bc36306e50db0fe471ca92773b96f17ab3617a16f0685f0135d6f061965e8a49060fd5fc6fb32e22e2dd9fa", + "65417e62fa739f4aff802db45b951d3e527b30dba413fe4cc2666addb28654cd04ae27cff61f094e86bb995a4dd954641b9f66b8a6e9b327aa384ed9155a97bd55619f43", + "2d85f153ed4c1fe072eb315b2c07a273b4283df24e0b266bac2a89800c29b04258e739605e48aab5a10656b5c16283a4ee5c86f34988b92990d35aa86c7f31ed29a528a19bac2a1265810d04daaa3d1e8b93e0e90f17e2894dcd66b0c074cd9a4089b7c661bb5b8ddc" + ] + } + ], + "outcome": "accept", + "clip": "e631e431d2f0280ab344d5a5fb7e2c3e2b9c7e1fdd555d03dc931d0f764b2fc2", + "signer": "d6b5a6849f61a8bbd9d4db526a9fc1c73ef949590cdcd9b0b65ce6375262d9bd", + "window": [ + 8000000, + 12000000 + ], + "bound_us": 500000, + "facts": [ + { + "take": "41f4686756b9083ffac11b1d229c5fc28a7fcd8e318f713ac7d417b930eda03e", + "first": 2, + "count": 4, + "offset": -5000000000, + "span": [ + 8000000, + 12000000 + ], + "device_window": [ + 5008000000, + 5012000000 + ], + "bytes": 326, + "sha256": "6577bc81132b290f0ad067455d3d1de26c609c8592e90b66b9558ad4ed5cbf96", + "withheld": [] + } + ] + } + ] +} diff --git a/wai/registry/capabilities.json b/wai/registry/capabilities.json index 422707641..be856f45c 100644 --- a/wai/registry/capabilities.json +++ b/wai/registry/capabilities.json @@ -644,6 +644,20 @@ "edition": null, "registered": "2026-10-18" }, + { + "capability": "wai.live.moderation", + "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-19" + }, { "capability": "wai.live.recording", "kind": "record", @@ -1934,6 +1948,20 @@ "section": "§3.1", "status": "defined" }, + { + "name": "WMN1", + "kind": "magic", + "document": "extensions/live-moderation.md", + "section": "§5.1", + "status": "defined" + }, + { + "name": "WMP1", + "kind": "magic", + "document": "extensions/live-moderation.md", + "section": "§3.1", + "status": "defined" + }, { "name": "WMR1", "kind": "magic", @@ -1941,6 +1969,13 @@ "section": "§4.1", "status": "defined" }, + { + "name": "WMS1", + "kind": "magic", + "document": "extensions/live-moderation.md", + "section": "§4.2", + "status": "defined" + }, { "name": "WRD1", "kind": "magic", diff --git a/wai/vocab/v2.ttl b/wai/vocab/v2.ttl index ad7d99348..c9828a62f 100644 --- a/wai/vocab/v2.ttl +++ b/wai/vocab/v2.ttl @@ -555,6 +555,13 @@ wai:wai.live.metering a wai:Capability ; wai:specSection "§5 Interactive, temporal & computed content" ; wai:registeredOn "2026-10-18"^^xsd:date . +wai:wai.live.moderation a wai:Capability ; + rdfs:label "wai.live.moderation" ; + wai:kind wai:kind-record ; + wai:status wai:status-registered ; + wai:specSection "§5 Interactive, temporal & computed content" ; + wai:registeredOn "2026-10-19"^^xsd:date . + wai:wai.live.recording a wai:Capability ; rdfs:label "wai.live.recording" ; wai:kind wai:kind-record ; diff --git a/wai/wai-rs/Cargo.toml b/wai/wai-rs/Cargo.toml index 3958266e6..4f7b8b82a 100644 --- a/wai/wai-rs/Cargo.toml +++ b/wai/wai-rs/Cargo.toml @@ -230,6 +230,15 @@ live_metering = ["live_compose", "capture_take", "telemetry"] # steering manifest, the HLS tag and the DASH element, written exactly. SHA-256, Ed25519 and the key # log only; no new dependency. energy_steering = ["live_metering"] +# Live moderation (extensions/live-moderation): `wai.live.moderation` — the room authority's +# signed review policy (WMP1: what is held for review or reviewed after delivery, by whom, each +# deadline and fallback, and the reason codes with their grounds), the statement (WMS1) that +# follows a `decision` event, notices and complaints (WMN1), lines of decisions by digest, the +# review state machine, gaps that withheld events leave explained by the decisions that restrict +# them, clips of a redacted take through live-recording's clip verifier, and the export of each +# restricting decision as a statement of reasons in the DSA Transparency Database's format, +# written by hand. SHA-256, Ed25519 and the key log only; no new dependency. +live_moderation = ["live_events", "live_room", "live_record"] # Timed text and live captions (extensions/timed-text): `wai.text.timed` — the cue model, # live caption revisions (`caption` events of wai.live.events with the WTX1 annotation), # and their exact mappings onto WebVTT documents and segments, the IMSC1 Text Profile, @@ -699,6 +708,11 @@ name = "wai_energy_steering_vectors" path = "src/bin/wai_energy_steering_vectors.rs" required-features = ["energy_steering"] +[[bin]] +name = "wai_live_moderation_vectors" +path = "src/bin/wai_live_moderation_vectors.rs" +required-features = ["live_moderation"] + [[bin]] name = "wai_timed_text_vectors" path = "src/bin/wai_timed_text_vectors.rs" @@ -1375,6 +1389,11 @@ name = "energy_steering" path = "tests/energy_steering.rs" required-features = ["energy_steering"] +[[test]] +name = "live_moderation" +path = "tests/live_moderation.rs" +required-features = ["live_moderation"] + [[test]] name = "timed_text" path = "tests/timed_text.rs" diff --git a/wai/wai-rs/src/bin/wai_live_moderation_vectors.rs b/wai/wai-rs/src/bin/wai_live_moderation_vectors.rs new file mode 100644 index 000000000..ab9bafcab --- /dev/null +++ b/wai/wai-rs/src/bin/wai_live_moderation_vectors.rs @@ -0,0 +1,75 @@ +//! Conformance corpus for live moderation (`live-conformance/moderation/`, extensions/live-moderation.md §11). +//! +//! wai_live_moderation_vectors gen write vectors.json and every statement-of- +//! reasons export (.sor.json), from fixed seeds +//! wai_live_moderation_vectors verify every file regenerates byte for byte, no other +//! file but README.md is there, and every case +//! gets the outcome it states +//! +//! The generator and this verifier are one implementation. The corpus's second +//! implementation is `live-conformance/live_moderation_verify.py`, written from the extension's +//! text and sharing no code with this binary. + +use std::collections::BTreeMap; +use std::path::Path; +use wai::live_moderation::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)) => { + if let Err(e) = std::fs::create_dir_all(d) { + eprintln!("create {d}: {e}"); + std::process::exit(1); + } + for (name, body) in corpus::generate() { + let p = Path::new(d).join(&name); + if let Err(e) = std::fs::write(&p, body) { + eprintln!("write {}: {e}", p.display()); + std::process::exit(1); + } + } + println!("wrote {d}"); + } + (Some("verify"), Some(d)) => std::process::exit(verify(Path::new(d))), + _ => { + eprintln!("usage: wai_live_moderation_vectors gen|verify "); + std::process::exit(2); + } + } +} + +fn verify(dir: &Path) -> i32 { + let mut files = BTreeMap::new(); + let entries = match std::fs::read_dir(dir) { + Ok(e) => e, + Err(e) => { + eprintln!("read {}: {e}", dir.display()); + return 1; + } + }; + for e in entries.flatten() { + let name = e.file_name().to_string_lossy().into_owned(); + if name == "README.md" { + continue; + } + match std::fs::read_to_string(e.path()) { + Ok(s) => { + files.insert(name, s); + } + Err(err) => { + eprintln!("read {name}: {err}"); + return 1; + } + } + } + let generated: BTreeMap = corpus::generate().into_iter().collect(); + let same = files == generated; + println!("{} every file regenerates byte for byte from its seeds, and no other file is there", if same { "PASS" } else { "FAIL" }); + let fails = corpus::verify(&files); + for f in &fails { + println!("FAIL {f}"); + } + println!("{} every case gets the outcome the corpus states", if fails.is_empty() { "PASS" } else { "FAIL" }); + (!same || !fails.is_empty()) as i32 +} diff --git a/wai/wai-rs/src/codecs/registry.rs b/wai/wai-rs/src/codecs/registry.rs index e94f50ad2..70764ee01 100644 --- a/wai/wai-rs/src/codecs/registry.rs +++ b/wai/wai-rs/src/codecs/registry.rs @@ -217,6 +217,7 @@ pub const CAP_LIVE_RECORDING: &str = "wai.live.recording"; pub const CAP_LIVE_METERING: &str = "wai.live.metering"; pub const CAP_LIVE_STEERING: &str = "wai.live.steering"; pub const CAP_TEXT_TIMED: &str = "wai.text.timed"; +pub const CAP_LIVE_MODERATION: &str = "wai.live.moderation"; /// One row per string SPEC §5 registers that is a payload, companion or record: /// `(string, SPEC section, edition, registered)`. @@ -302,6 +303,7 @@ const ROWS: &[(&str, &str, Option<&str>, &str)] = &[ (CAP_LIVE_METERING, S_INTERACTIVE, None, "2026-10-18"), (CAP_LIVE_STEERING, S_INTERACTIVE, None, "2026-10-18"), (CAP_TEXT_TIMED, S_INTERACTIVE, None, "2026-10-17"), + (CAP_LIVE_MODERATION, S_INTERACTIVE, None, "2026-10-19"), (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"), @@ -351,7 +353,7 @@ 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, CAP_LIVE_COMPOSE, CAP_LIVE_RECORDING, - CAP_LIVE_METERING, CAP_LIVE_STEERING, CAP_TEXT_TIMED, + CAP_LIVE_METERING, CAP_LIVE_STEERING, CAP_TEXT_TIMED, CAP_LIVE_MODERATION, ]; /// A named identifier SPEC uses that has the shape of a capability string but is @@ -504,6 +506,7 @@ const LIVE_RECORDING: &str = "extensions/live-recording.md"; const TIMED_TEXT: &str = "extensions/timed-text.md"; const LIVE_METERING: &str = "extensions/live-metering.md"; const ENERGY_STEERING: &str = "extensions/energy-steering.md"; +const LIVE_MODERATION: &str = "extensions/live-moderation.md"; const fn wire(name: &'static str, kind: WireKind, document: &'static str, section: &'static str, status: WireStatus) -> WireIdentifier { @@ -513,8 +516,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), of packaging, of live events, of live rooms, of capture binding, of -/// live composition, of live recording, of timed text and of live metering, in document -/// order. The export lists them sorted by name and kind. +/// live composition, of live recording, of timed text, of live metering, of energy steering +/// and of live moderation, 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), @@ -589,6 +592,9 @@ pub const WIRE_IDENTIFIERS: &[WireIdentifier] = &[ wire("WMR1", WireKind::Magic, LIVE_METERING, "§4.1", WireStatus::Defined), wire("WSP1", WireKind::Magic, ENERGY_STEERING, "§3.1", WireStatus::Defined), wire("WSD1", WireKind::Magic, ENERGY_STEERING, "§7.1", WireStatus::Defined), + wire("WMP1", WireKind::Magic, LIVE_MODERATION, "§3.1", WireStatus::Defined), + wire("WMS1", WireKind::Magic, LIVE_MODERATION, "§4.2", WireStatus::Defined), + wire("WMN1", WireKind::Magic, LIVE_MODERATION, "§5.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 2b3c5805e..0ddd880ed 100644 --- a/wai/wai-rs/src/lib.rs +++ b/wai/wai-rs/src/lib.rs @@ -451,6 +451,15 @@ pub mod live_metering; /// cbindgen:ignore #[cfg(feature = "energy_steering")] pub mod energy_steering; +// Live moderation (extensions/live-moderation.md): `wai.live.moderation` — the room authority's +// review policy, the statement that follows a `decision` event, notices and complaints, lines +// of decisions by digest, the review state machine, gaps explained by the decisions that +// restrict the events they withhold, clips of a redacted take, and each restricting decision's +// statement-of-reasons export. Rust-only, like the other live modules: its constants must not +// become macros in include/wai.h. +/// cbindgen:ignore +#[cfg(feature = "live_moderation")] +pub mod live_moderation; // Timed text and live captions (extensions/timed-text.md): `wai.text.timed` — the cue model // both WebVTT and the IMSC1 Text Profile express, live caption revisions as `caption` // events of `wai.live.events` with the WTX1 annotation, and the exact mappings onto WebVTT diff --git a/wai/wai-rs/src/live_moderation.rs b/wai/wai-rs/src/live_moderation.rs new file mode 100644 index 000000000..c668f8af7 --- /dev/null +++ b/wai/wai-rs/src/live_moderation.rs @@ -0,0 +1,1632 @@ +//! Live moderation — `wai.live.moderation` ([extensions/live-moderation.md]). +//! +//! The room authority signs a review policy (`WMP1`): which event kinds and media are held +//! for review before delivery or reviewed after it, by whom, each one's deadline and fallback, +//! and the reason codes in use with their grounds. A moderator's verdict is a `decision` event +//! of `wai.live.events`, unchanged, followed by a `meta` event carrying this extension's +//! statement (`WMS1`): what the decision targets, the decision it supersedes, its basis, its +//! use of automated means, and its ground, explanation and facts. Notices and complaints +//! (`WMN1`) are signed by whoever submits them. Decisions on one target form a line by digest, +//! a restricted item is withheld, and a gap a withheld event leaves in its chain is explained +//! by the decisions that restrict it. Each restricting decision maps onto one record of the +//! DSA Transparency Database's statement-of-reasons format, byte for byte. +//! +//! What this module implements, by section of the extension: +//! +//! - §3: the review policy, its rules, its chain and the room's review field; +//! - §4: the statement, lines of decisions and fallback decisions; +//! - §5: notices and complaints; +//! - §6: items under review and their states, as timelines; +//! - §7: verification over a room the live-rooms verifier replays, with explained gaps; +//! - §8.3: clips under moderation, through live-recording's clip verifier; +//! - §9: the statement-of-reasons export. +//! +//! §8.2, a recording package under moderation, is specified only. +//! +//! The corpus `live-conformance/moderation/` is written by [`corpus::generate`] and checked by +//! [`corpus::verify`], and by `live-conformance/live_moderation_verify.py`, which shares no code +//! with this module. +//! +//! [extensions/live-moderation.md]: ../../extensions/live-moderation.md + +use std::collections::{BTreeMap, BTreeSet}; + +use ed25519_dalek::{Signer, SigningKey}; +use sha2::{Digest, Sha256}; + +use crate::capture_take::Chunk; +use crate::live_events::{self as events, kind, Event, Payload}; +use crate::live_record::{self as record, ClipFacts, ClipOutcome, ClipPlace, PartInputs}; +use crate::live_room::{self as room, power, Descriptor}; + +pub mod corpus; + +/// The capability string this extension registers. +pub const CAPABILITY: &str = "wai.live.moderation"; +/// The magic of a review policy (§3.1). +pub const POLICY_MAGIC: [u8; 4] = *b"WMP1"; +/// The magic of a statement (§4.2). +pub const STATEMENT_MAGIC: [u8; 4] = *b"WMS1"; +/// The magic of a notice or complaint (§5.1). +pub const NOTICE_MAGIC: [u8; 4] = *b"WMN1"; +/// The version of every record this revision defines. +pub const RECORD_VERSION: u8 = 1; +/// The domain a policy's signature is made under (§3.2). +pub const POLICY_DOMAIN: &[u8] = b"wai:live-moderation-policy\x01"; +/// The domain a notice's signature is made under (§5.2). +pub const NOTICE_DOMAIN: &[u8] = b"wai:live-moderation-notice\x01"; +/// The bytes of a statement before its three texts (§4.2). +pub const STATEMENT_HEAD: usize = 105; + +/// A decision's verdict (live-events §4.11). +pub mod verdict { + pub const ALLOW: u8 = 1; + pub const DENY: u8 = 2; + pub const REDACT: u8 = 3; +} + +/// What a decision or a notice targets (§4.1). +pub mod target_type { + pub const EVENT: u8 = 1; + pub const OBJECT: u8 = 2; +} + +/// A statement's basis (§4.2). +pub mod basis { + pub const OWN: u8 = 1; + pub const NOTICE: u8 = 2; + pub const COMPLAINT: u8 = 3; + pub const FALLBACK: u8 = 4; +} + +/// An entry's scope (§3.1). +pub mod scope { + pub const KIND: u8 = 1; + pub const MEDIA: u8 = 2; +} + +/// An entry's mode (§3.1). +pub mod mode { + pub const PRE: u8 = 1; + pub const POST: u8 = 2; +} + +/// An entry's fallback (§3.1). +pub mod fallback { + pub const ALLOW: u8 = 1; + pub const DENY: u8 = 2; + pub const HOLD: u8 = 3; +} + +/// A ground (§3.1, §4.2, §5.1). +pub mod ground { + pub const ILLEGAL: u8 = 1; + pub const INCOMPATIBLE: u8 = 2; +} + +/// A record of §5: a notice or a complaint. +pub mod notice_type { + pub const NOTICE: u8 = 1; + pub const COMPLAINT: u8 = 2; +} + +/// The database's categories, numbered from 1 in this order (§9.5). +pub const CATEGORIES: [&str; 16] = [ + "STATEMENT_CATEGORY_ANIMAL_WELFARE", + "STATEMENT_CATEGORY_CONSUMER_INFORMATION", + "STATEMENT_CATEGORY_CYBER_VIOLENCE", + "STATEMENT_CATEGORY_CYBER_VIOLENCE_AGAINST_WOMEN", + "STATEMENT_CATEGORY_DATA_PROTECTION_AND_PRIVACY_VIOLATIONS", + "STATEMENT_CATEGORY_ILLEGAL_OR_HARMFUL_SPEECH", + "STATEMENT_CATEGORY_INTELLECTUAL_PROPERTY_INFRINGEMENTS", + "STATEMENT_CATEGORY_NEGATIVE_EFFECTS_ON_CIVIC_DISCOURSE_OR_ELECTIONS", + "STATEMENT_CATEGORY_NOT_SPECIFIED_NOTICE", + "STATEMENT_CATEGORY_OTHER_VIOLATION_TC", + "STATEMENT_CATEGORY_PROTECTION_OF_MINORS", + "STATEMENT_CATEGORY_RISK_FOR_PUBLIC_SECURITY", + "STATEMENT_CATEGORY_SCAMS_AND_FRAUD", + "STATEMENT_CATEGORY_SELF_HARM", + "STATEMENT_CATEGORY_UNSAFE_AND_PROHIBITED_PRODUCTS", + "STATEMENT_CATEGORY_VIOLENCE", +]; + +/// The thirty codes `territorial_scope` accepts, in ascending order (§9.3). +pub const TERRITORY: [&str; 30] = [ + "AT", "BE", "BG", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", "FR", "GR", "HR", "HU", "IE", "IS", "IT", "LI", "LT", "LU", "LV", "MT", + "NL", "NO", "PL", "PT", "RO", "SE", "SI", "SK", +]; + +/// The decidable event kinds (§4.1). +pub const DECIDABLE: [u8; 9] = [kind::META, kind::CUE, kind::CHAT, kind::REACTION, kind::POLL_OPEN, kind::VOTE, kind::POLL_CLOSE, kind::MARKER, kind::CAPTION]; + +/// Why a policy, a notice, a decision, an export or a clip is refused (§10). +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum Reason { + /// A code of live-rooms §11, or through it of live-events §9. + Room(room::Reason), + /// A code of live-recording §9, or through it of capture-binding §12, for a clip. + Record(record::Reason), + PolicyMalformed, + PolicyUnlinked, + PolicyConflictsRoom, + NoticeMalformed, + StatementMisplaced, + StatementMalformed, + ReasonNotInPolicy, + TargetUnknown, + TargetNotDecidable, + TargetPrevMismatch, + NotReviewer, + SupersedeGap, + SupersedeUnknown, + SupersedeMismatch, + NoticeUnknown, + NoticeMismatch, + FallbackNotInPolicy, + FallbackEarly, + SorIncomplete, + RedactionNotApplied, +} + +impl Reason { + /// The codes this extension adds, in §10's order. + pub const ALL: [Reason; 20] = [ + Reason::PolicyMalformed, + Reason::PolicyUnlinked, + Reason::PolicyConflictsRoom, + Reason::NoticeMalformed, + Reason::StatementMisplaced, + Reason::StatementMalformed, + Reason::ReasonNotInPolicy, + Reason::TargetUnknown, + Reason::TargetNotDecidable, + Reason::TargetPrevMismatch, + Reason::NotReviewer, + Reason::SupersedeGap, + Reason::SupersedeUnknown, + Reason::SupersedeMismatch, + Reason::NoticeUnknown, + Reason::NoticeMismatch, + Reason::FallbackNotInPolicy, + Reason::FallbackEarly, + Reason::SorIncomplete, + Reason::RedactionNotApplied, + ]; + + /// The reason's code. + pub fn code(self) -> &'static str { + match self { + Reason::Room(r) => r.code(), + Reason::Record(r) => r.code(), + Reason::PolicyMalformed => "policy_malformed", + Reason::PolicyUnlinked => "policy_unlinked", + Reason::PolicyConflictsRoom => "policy_conflicts_room", + Reason::NoticeMalformed => "notice_malformed", + Reason::StatementMisplaced => "statement_misplaced", + Reason::StatementMalformed => "statement_malformed", + Reason::ReasonNotInPolicy => "reason_not_in_policy", + Reason::TargetUnknown => "target_unknown", + Reason::TargetNotDecidable => "target_not_decidable", + Reason::TargetPrevMismatch => "target_prev_mismatch", + Reason::NotReviewer => "not_reviewer", + Reason::SupersedeGap => "supersede_gap", + Reason::SupersedeUnknown => "supersede_unknown", + Reason::SupersedeMismatch => "supersede_mismatch", + Reason::NoticeUnknown => "notice_unknown", + Reason::NoticeMismatch => "notice_mismatch", + Reason::FallbackNotInPolicy => "fallback_not_in_policy", + Reason::FallbackEarly => "fallback_early", + Reason::SorIncomplete => "sor_incomplete", + Reason::RedactionNotApplied => "redaction_not_applied", + } + } +} + +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 {} + +fn ev(r: events::Reason) -> Reason { + Reason::Room(room::Reason::Events(r)) +} + +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() +} + +const ZERO: [u8; 32] = [0; 32]; + +/// A cursor that reports running out as `None`. +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 text(&mut self) -> Option<&'a [u8]> { + let n = self.u16()? as usize; + self.take(n) + } + fn done(&self) -> bool { + self.p == self.b.len() + } +} + +fn put_text(o: &mut Vec, s: &str) { + assert!(s.len() <= u16::MAX as usize, "a text field is at most 65535 bytes"); + o.extend_from_slice(&(s.len() as u16).to_le_bytes()); + o.extend_from_slice(s.as_bytes()); +} + +/// The head every record of this extension reads first (§3.3 step 1): its magic and version. +fn read_head(b: &[u8], magic: &[u8; 4]) -> Result<(), Reason> { + if b.len() < 4 { + return Err(ev(events::Reason::Truncated)); + } + if b[..4] != *magic { + return Err(ev(events::Reason::Malformed)); + } + if b.len() < 5 { + return Err(ev(events::Reason::Truncated)); + } + if b[4] != RECORD_VERSION { + return Err(ev(events::Reason::UnknownVersion)); + } + 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 => ev(events::Reason::BadKey), + crate::sig::SigError::BadSignature => ev(events::Reason::BadSignature), + }) +} + +fn ascending(v: &[T]) -> bool { + v.windows(2).all(|w| w[0] < w[1]) +} + +// --------------------------------------------------------------------------------------- +// §3 The review policy +// --------------------------------------------------------------------------------------- + +/// How items of one kind are reviewed (§3.1). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Entry { + pub scope: u8, + pub code: u8, + pub mode: u8, + pub deadline_ms: u32, + pub fallback: u8, + pub fallback_reason: u16, +} + +/// One reason code of a policy's vocabulary (§3.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ReasonCode { + pub code: u16, + pub ground: u8, + /// Its number in §9.5, from 1. + pub category: u8, + pub reference: String, + pub url: String, +} + +/// A review policy, `WMP1` (§3.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ReviewPolicy { + pub room: [u8; 32], + pub prev: [u8; 32], + pub effective: u64, + pub reviewers: Vec<[u8; 32]>, + pub flaggers: Vec<[u8; 32]>, + pub entries: Vec, + pub reasons: Vec, + pub territory: Vec<[u8; 2]>, + pub redress: String, + pub sig: [u8; 64], +} + +/// `reference`, a URL's and a territory's rules (§3.1). +fn url_ok(u: &str) -> bool { + u.is_empty() || (u.len() <= 500 && u.starts_with("https://") && u.bytes().all(|b| (0x21..=0x7e).contains(&b))) +} + +impl ReviewPolicy { + /// The record without `sig` (§3.2). + pub fn body(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&POLICY_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.room); + o.extend_from_slice(&self.prev); + o.extend_from_slice(&self.effective.to_le_bytes()); + for keys in [&self.reviewers, &self.flaggers] { + o.push(keys.len() as u8); + for k in keys { + o.extend_from_slice(k); + } + } + o.push(self.entries.len() as u8); + for e in &self.entries { + o.extend_from_slice(&[e.scope, e.code, e.mode]); + o.extend_from_slice(&e.deadline_ms.to_le_bytes()); + o.push(e.fallback); + o.extend_from_slice(&e.fallback_reason.to_le_bytes()); + } + o.push(self.reasons.len() as u8); + for r in &self.reasons { + o.extend_from_slice(&r.code.to_le_bytes()); + o.extend_from_slice(&[r.ground, r.category]); + put_text(&mut o, &r.reference); + put_text(&mut o, &r.url); + } + o.push(self.territory.len() as u8); + for t in &self.territory { + o.extend_from_slice(t); + } + put_text(&mut o, &self.redress); + o + } + + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + /// The policy's digest (§3.2). + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Signed by the room authority (§3.2). + pub fn sign(mut self, authority: &SigningKey) -> ReviewPolicy { + let mut m = POLICY_DOMAIN.to_vec(); + m.extend_from_slice(&self.body()); + self.sig = authority.sign(&m).to_bytes(); + self + } + + /// Read one policy (§3.3): its layout, then its rules. The signature, the room, the link + /// and the room's review field are §7.2's steps. + pub fn parse(b: &[u8]) -> Result { + read_head(b, &POLICY_MAGIC)?; + let t = ev(events::Reason::Truncated); + let mut r = Rd::new(&b[5..]); + let room = r.d32().ok_or(t)?; + let prev = r.d32().ok_or(t)?; + let effective = r.u64().ok_or(t)?; + let mut keys = [Vec::new(), Vec::new()]; + for k in keys.iter_mut() { + let n = r.u8().ok_or(t)?; + for _ in 0..n { + k.push(r.d32().ok_or(t)?); + } + } + let [reviewers, flaggers] = keys; + let n = r.u8().ok_or(t)?; + let mut entries = Vec::new(); + for _ in 0..n { + entries.push(Entry { + scope: r.u8().ok_or(t)?, + code: r.u8().ok_or(t)?, + mode: r.u8().ok_or(t)?, + deadline_ms: r.u32().ok_or(t)?, + fallback: r.u8().ok_or(t)?, + fallback_reason: r.u16().ok_or(t)?, + }); + } + let n = r.u8().ok_or(t)?; + let mut raw_reasons = Vec::new(); + for _ in 0..n { + let code = r.u16().ok_or(t)?; + let ground = r.u8().ok_or(t)?; + let category = r.u8().ok_or(t)?; + let reference = r.text().ok_or(t)?; + let url = r.text().ok_or(t)?; + raw_reasons.push((code, ground, category, reference, url)); + } + let n = r.u8().ok_or(t)?; + let mut territory = Vec::new(); + for _ in 0..n { + territory.push(<[u8; 2]>::try_from(r.take(2).ok_or(t)?).map_err(|_| t)?); + } + let redress = r.text().ok_or(t)?; + let sig: [u8; 64] = r.take(64).ok_or(t)?.try_into().map_err(|_| t)?; + if !r.done() { + return Err(ev(events::Reason::Malformed)); + } + // The rules (§3.3). + let bad = Reason::PolicyMalformed; + let text = |b: &[u8]| String::from_utf8(b.to_vec()).map_err(|_| bad); + let mut reasons = Vec::new(); + for (code, ground, category, reference, url) in raw_reasons { + reasons.push(ReasonCode { code, ground, category, reference: text(reference)?, url: text(url)? }); + } + let p = ReviewPolicy { room, prev, effective, reviewers, flaggers, entries, reasons, territory, redress: text(redress)?, sig }; + if p.reviewers.len() > 16 || p.flaggers.len() > 16 || p.entries.len() > 32 || !(1..=64).contains(&p.reasons.len()) || !(1..=30).contains(&p.territory.len()) { + return Err(bad); + } + if !ascending(&p.reviewers) || !ascending(&p.flaggers) { + return Err(bad); + } + let keys: Vec<(u8, u8)> = p.entries.iter().map(|e| (e.scope, e.code)).collect(); + let codes: Vec = p.reasons.iter().map(|r| r.code).collect(); + if !ascending(&keys) || !ascending(&codes) { + return Err(bad); + } + for e in &p.entries { + let code_ok = match e.scope { + scope::KIND => DECIDABLE.contains(&e.code), + scope::MEDIA => (1..=3).contains(&e.code), + _ => false, + }; + let reason_ok = if e.fallback == fallback::ALLOW { e.fallback_reason == 0 } else { codes.contains(&e.fallback_reason) }; + if !code_ok || !(1..=2).contains(&e.mode) || e.deadline_ms == 0 || !(1..=3).contains(&e.fallback) || !reason_ok { + return Err(bad); + } + } + for c in &p.reasons { + let n = c.reference.chars().count(); + if c.code == 0 || !(1..=2).contains(&c.ground) || !(1..=16).contains(&c.category) || !(1..=500).contains(&n) || !url_ok(&c.url) { + return Err(bad); + } + } + let terr: Vec<&[u8; 2]> = p.territory.iter().collect(); + if !ascending(&terr) || !p.territory.iter().all(|t| TERRITORY.iter().any(|c| c.as_bytes() == t)) { + return Err(bad); + } + Ok(p) + } + + /// The entry that reviews items of `scope` and `code`, if any. + pub fn entry(&self, scope: u8, code: u8) -> Option<&Entry> { + self.entries.iter().find(|e| e.scope == scope && e.code == code) + } + + /// The vocabulary's entry for reason code `code`, if any. + pub fn reason(&self, code: u16) -> Option<&ReasonCode> { + self.reasons.iter().find(|r| r.code == code) + } +} + +/// Is kind `k` set in a kinds bitmap (live-events §5)? +fn has_kind(bits: &[u8; 32], k: u8) -> bool { + bits[(k / 8) as usize] & (1 << (k % 8)) != 0 +} + +/// §3.5: every policy keeps the room descriptor's review field. +fn keeps_room(p: &ReviewPolicy, d: &Descriptor) -> bool { + (0..=255u8).filter(|&k| has_kind(&d.review.kinds, k)).all(|k| { + p.entry(scope::KIND, k) + .is_some_and(|e| e.mode == mode::PRE && e.deadline_ms == d.review.deadline_ms && e.fallback == d.review.fallback) + }) +} + +// --------------------------------------------------------------------------------------- +// §4 The statement +// --------------------------------------------------------------------------------------- + +/// A decision's statement, `WMS1` (§4.2). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Statement { + pub target_type: u8, + pub target_prev: [u8; 32], + pub supersedes: [u8; 32], + pub basis: u8, + pub notice: [u8; 32], + /// Bit 0 detection; bits 1 and 2 the decision's automation, 0 to 2. + pub automated: u8, + pub ground: u8, + pub ground_ref: String, + pub explanation: String, + pub facts: String, +} + +impl Statement { + /// The `meta` payload (§4.2). + pub fn encode(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&STATEMENT_MAGIC); + o.push(RECORD_VERSION); + o.push(self.target_type); + o.extend_from_slice(&self.target_prev); + o.extend_from_slice(&self.supersedes); + o.push(self.basis); + o.extend_from_slice(&self.notice); + o.push(self.automated); + o.push(self.ground); + put_text(&mut o, &self.ground_ref); + put_text(&mut o, &self.explanation); + put_text(&mut o, &self.facts); + o + } + + /// Does a `meta` payload claim to be a statement (§4.2)? + pub fn is_statement(payload: &[u8]) -> bool { + payload.len() >= 4 && payload[..4] == STATEMENT_MAGIC + } + + /// Read a statement (§4.3): every failure is `statement_malformed`. + pub fn parse(b: &[u8]) -> Result { + let bad = Reason::StatementMalformed; + let mut r = Rd::new(b); + if r.take(4).ok_or(bad)? != STATEMENT_MAGIC || r.u8().ok_or(bad)? != RECORD_VERSION { + return Err(bad); + } + let target_type = r.u8().ok_or(bad)?; + let target_prev = r.d32().ok_or(bad)?; + let supersedes = r.d32().ok_or(bad)?; + let basis = r.u8().ok_or(bad)?; + let notice = r.d32().ok_or(bad)?; + let automated = r.u8().ok_or(bad)?; + let ground = r.u8().ok_or(bad)?; + let mut texts = Vec::new(); + for _ in 0..3 { + texts.push(String::from_utf8(r.text().ok_or(bad)?.to_vec()).map_err(|_| bad)?); + } + if !r.done() { + return Err(bad); + } + let decision = (automated >> 1) & 3; + let ok = (1..=2).contains(&target_type) + && (target_type == target_type::EVENT || target_prev == ZERO) + && (1..=4).contains(&basis) + && ((basis == basis::NOTICE || basis == basis::COMPLAINT) == (notice != ZERO)) + && automated & !0b111 == 0 + && decision != 3 + && (basis != basis::FALLBACK || (decision == 2 && supersedes == ZERO)) + && (1..=2).contains(&ground); + if !ok { + return Err(bad); + } + let facts = texts.pop().expect("three texts"); + let explanation = texts.pop().expect("three texts"); + let ground_ref = texts.pop().expect("three texts"); + Ok(Statement { target_type, target_prev, supersedes, basis, notice, automated, ground, ground_ref, explanation, facts }) + } +} + +// --------------------------------------------------------------------------------------- +// §5 Notices and complaints +// --------------------------------------------------------------------------------------- + +/// A notice or a complaint, `WMN1` (§5.1). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Notice { + pub room: [u8; 32], + pub ntype: u8, + pub target_type: u8, + pub target: [u8; 32], + pub t: u64, + pub ground: u8, + pub good_faith: u8, + pub ground_ref: String, + pub statement: String, + pub contact: String, + pub submitter: [u8; 32], + pub sig: [u8; 64], +} + +impl Notice { + /// The record without `sig` (§5.2). + pub fn body(&self) -> Vec { + let mut o = Vec::new(); + o.extend_from_slice(&NOTICE_MAGIC); + o.push(RECORD_VERSION); + o.extend_from_slice(&self.room); + o.extend_from_slice(&[self.ntype, self.target_type]); + o.extend_from_slice(&self.target); + o.extend_from_slice(&self.t.to_le_bytes()); + o.extend_from_slice(&[self.ground, self.good_faith]); + put_text(&mut o, &self.ground_ref); + put_text(&mut o, &self.statement); + put_text(&mut o, &self.contact); + o.extend_from_slice(&self.submitter); + o + } + + pub fn to_bytes(&self) -> Vec { + let mut o = self.body(); + o.extend_from_slice(&self.sig); + o + } + + pub fn digest(&self) -> [u8; 32] { + sha256(&[&self.body()]) + } + + /// Signed by `key`, which becomes the submitter. + pub fn sign(mut self, key: &SigningKey) -> Notice { + self.submitter = key.verifying_key().to_bytes(); + let mut m = NOTICE_DOMAIN.to_vec(); + m.extend_from_slice(&self.body()); + self.sig = key.sign(&m).to_bytes(); + self + } + + /// Read one notice (§5.2): its layout, then its rules but the duplicate one, which needs + /// the list. + pub fn parse(b: &[u8]) -> Result { + read_head(b, &NOTICE_MAGIC)?; + let t = ev(events::Reason::Truncated); + let mut r = Rd::new(&b[5..]); + let room = r.d32().ok_or(t)?; + let ntype = r.u8().ok_or(t)?; + let target_type = r.u8().ok_or(t)?; + let target = r.d32().ok_or(t)?; + let time = r.u64().ok_or(t)?; + let ground = r.u8().ok_or(t)?; + let good_faith = r.u8().ok_or(t)?; + let texts = [r.text().ok_or(t)?, r.text().ok_or(t)?, r.text().ok_or(t)?]; + let submitter = r.d32().ok_or(t)?; + let sig: [u8; 64] = r.take(64).ok_or(t)?.try_into().map_err(|_| t)?; + if !r.done() { + return Err(ev(events::Reason::Malformed)); + } + let bad = Reason::NoticeMalformed; + let text = |b: &[u8]| String::from_utf8(b.to_vec()).map_err(|_| bad); + let ok = match ntype { + notice_type::NOTICE => (1..=2).contains(&target_type) && (1..=2).contains(&ground), + notice_type::COMPLAINT => target_type == target_type::EVENT && ground == 0, + _ => false, + }; + if !ok || good_faith > 1 { + return Err(bad); + } + Ok(Notice { + room, + ntype, + target_type, + target, + t: time, + ground, + good_faith, + ground_ref: text(texts[0])?, + statement: text(texts[1])?, + contact: text(texts[2])?, + submitter, + sig, + }) + } +} + +// --------------------------------------------------------------------------------------- +// §6 and §7: items, states and verification +// --------------------------------------------------------------------------------------- + +/// A media object under moderation (§7.1). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Object { + pub digest: [u8; 32], + pub media: u8, + pub t: u64, +} + +/// What a moderation verifier is given (§7.1). +#[derive(Clone, Copy, Debug)] +pub struct Input<'a> { + pub descriptor: &'a [u8], + pub grants: &'a [Vec], + pub head: Option<&'a str>, + pub chains: &'a [Vec>], + pub policies: &'a [Vec], + pub notices: &'a [Vec], + pub objects: &'a [Object], +} + +/// Where a verification stopped (§7.2). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum At { + Room(room::At), + Policy(usize), + Notice(usize), + Record { chain: usize, record: usize }, +} + +/// The outcome of a verification (§7.5). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Outcome { + Accept, + /// The gaps that remain, unexplained. + Gap(Vec), + Refuse { at: At, reason: Reason }, +} + +/// An item's state (§6.2). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum State { + Shown, + Held, + Pending, + Allowed, + Denied, + Redacted, + FallbackAllow, + FallbackDeny, + FallbackHold, +} + +impl State { + pub fn name(self) -> &'static str { + match self { + State::Shown => "shown", + State::Held => "held", + State::Pending => "pending", + State::Allowed => "allowed", + State::Denied => "denied", + State::Redacted => "redacted", + State::FallbackAllow => "fallback_allow", + State::FallbackDeny => "fallback_deny", + State::FallbackHold => "fallback_hold", + } + } + + /// Is an item in this state shown (§6.2)? + pub fn visible(self) -> bool { + matches!(self, State::Shown | State::Pending | State::Allowed | State::FallbackAllow) + } + + fn of_verdict(v: u8) -> State { + match v { + verdict::ALLOW => State::Allowed, + verdict::DENY => State::Denied, + _ => State::Redacted, + } + } +} + +/// What a decision's statement is to the verifier (§7.4). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Said { + Known(Statement), + None, + /// Its seq lies in a gap that remains. + Unknown, +} + +/// A decision, as a verification states it (§7.5). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct DecisionFacts { + pub digest: [u8; 32], + pub decider: [u8; 32], + pub t: u64, + pub target: [u8; 32], + pub target_type: u8, + pub verdict: u8, + pub reason: u16, + pub statement: Said, + pub standing: bool, +} + +impl DecisionFacts { + fn known(&self) -> Option<&Statement> { + match &self.statement { + Said::Known(s) => Some(s), + _ => None, + } + } + + /// Its basis: its statement's, or own initiative without a known one. + pub fn basis(&self) -> u8 { + self.known().map_or(basis::OWN, |s| s.basis) + } + + pub fn supersedes(&self) -> [u8; 32] { + self.known().map_or(ZERO, |s| s.supersedes) + } + + pub fn notice(&self) -> [u8; 32] { + self.known().map_or(ZERO, |s| s.notice) + } +} + +/// An explained gap (§7.3): the decision withholding each seq, from `first` to `last`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Explained { + pub principal: [u8; 32], + pub first: u64, + pub last: u64, + pub decisions: Vec<[u8; 32]>, +} + +/// An item, as a verification states it (§6, §7.5). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ItemFacts { + pub digest: [u8; 32], + pub target_type: u8, + /// Its event kind, or its media kind. + pub code: u8, + pub t: u64, + pub entry: Option, + /// Each change of its state: the instant, the state and the decision that made it. + pub timeline: Vec<(u64, State, Option<[u8; 32]>)>, +} + +/// A decision's export (§9). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Export { + /// An allow restricts nothing. + None, + Record(Vec), + /// `sor_incomplete`, with the member that cannot be written. + Incomplete(&'static str), +} + +/// What a moderation verification holds at its end. +#[derive(Clone, Debug)] +pub struct Run { + pub outcome: Outcome, + pub room: Option<[u8; 32]>, + /// The room's own outcome, accept or gap, when it did not refuse. + pub room_outcome: Option, + pub t0_us: u64, + pub explained: Vec, + pub decisions: Vec, + pub items: Vec, + pub exports: Vec, + policies: Vec, + notices: Vec<(Notice, [u8; 32])>, + /// For each decision: the kind or media of its target and the target's `t`, when held. + targets: Vec>, +} + +impl Run { + fn refuse(mut self, at: At, reason: Reason) -> Run { + self.outcome = Outcome::Refuse { at, reason }; + self + } + + /// The policy in effect at `t` (§3.4). + fn policy_at(&self, t: u64) -> Option<&ReviewPolicy> { + policy_at(&self.policies, t) + } + + /// The standing decisions that restrict an object, by the object's digest (§8.3): what a + /// clip under moderation withholds. + pub fn restricted_objects(&self) -> BTreeMap<[u8; 32], [u8; 32]> { + self.decisions + .iter() + .filter(|d| d.standing && d.target_type == target_type::OBJECT && d.verdict != verdict::ALLOW) + .map(|d| (d.target, d.digest)) + .collect() + } +} + +fn policy_at(ps: &[ReviewPolicy], t: u64) -> Option<&ReviewPolicy> { + ps.iter().rev().find(|p| p.effective <= t) +} + +/// One event the room accepted, in the merged order. +struct Held { + chain: usize, + record: usize, + ev: Event, + payload: Payload, + digest: [u8; 32], + /// The grant it was verified under, `None` for a room key's. + under: Option<[u8; 32]>, +} + +/// Is this event a statement (§4.2)? +fn is_statement_event(h: &Held) -> bool { + h.ev.kind == kind::META && Statement::is_statement(&h.ev.payload) +} + +fn in_gaps(gaps: &[events::Gap], p: &[u8; 32], s: u64) -> bool { + gaps.iter().any(|g| g.principal == *p && g.first <= s && s <= g.last) +} + +/// Verify a room's moderation (§7). +pub fn verify(inp: &Input) -> Run { + let mut run = Run { + outcome: Outcome::Accept, + room: None, + room_outcome: None, + t0_us: 0, + explained: Vec::new(), + decisions: Vec::new(), + items: Vec::new(), + exports: Vec::new(), + policies: Vec::new(), + notices: Vec::new(), + targets: Vec::new(), + }; + // Step 1: the room. + let rr = room::verify_room(inp.descriptor, inp.grants, inp.head, inp.chains); + if let room::RoomOutcome::Refuse { at, reason } = rr.outcome { + return run.refuse(At::Room(at), Reason::Room(reason)); + } + let d = rr.descriptor.clone().expect("a room that did not refuse has its descriptor"); + let room_id = d.room_id(); + run.room = Some(room_id); + run.t0_us = d.t0_us; + run.room_outcome = Some(rr.outcome.clone()); + let room_gaps: Vec = match &rr.outcome { + room::RoomOutcome::Gap(g) => g.clone(), + _ => Vec::new(), + }; + // Step 2: the policies. + for (i, b) in inp.policies.iter().enumerate() { + let at = At::Policy(i); + let p = match ReviewPolicy::parse(b) { + Ok(p) => p, + Err(r) => return run.refuse(at, r), + }; + if p.room != room_id { + return run.refuse(at, ev(events::Reason::WrongRoom)); + } + if let Err(r) = verify_sig(&d.authority, POLICY_DOMAIN, &p.body(), &p.sig) { + return run.refuse(at, r); + } + let linked = match run.policies.last() { + None => p.prev == ZERO && p.effective == 0, + Some(q) => p.prev == q.digest() && p.effective > q.effective, + }; + if !linked { + return run.refuse(at, Reason::PolicyUnlinked); + } + if !keeps_room(&p, &d) { + return run.refuse(at, Reason::PolicyConflictsRoom); + } + run.policies.push(p); + } + // Step 3: the notices. + for (i, b) in inp.notices.iter().enumerate() { + let at = At::Notice(i); + let n = match Notice::parse(b) { + Ok(n) => n, + Err(r) => return run.refuse(at, r), + }; + let digest = n.digest(); + if run.notices.iter().any(|(_, g)| *g == digest) { + return run.refuse(at, Reason::NoticeMalformed); + } + if n.room != room_id { + return run.refuse(at, ev(events::Reason::WrongRoom)); + } + if let Err(r) = verify_sig(&n.submitter, NOTICE_DOMAIN, &n.body(), &n.sig) { + return run.refuse(at, r); + } + run.notices.push((n, digest)); + } + // The events the room accepted, once each, in the merged order. + let mut held: Vec = Vec::new(); + let mut seen = BTreeSet::new(); + for &(c, i, under) in &rr.order { + let e = Event::parse(&inp.chains[c][i]).expect("a record the room accepted reads"); + let digest = e.digest(); + if !seen.insert(digest) { + continue; + } + let payload = events::parse_payload(e.kind, &e.payload, u16::MAX).expect("a payload the room accepted reads"); + held.push(Held { chain: c, record: i, ev: e, payload, digest, under }); + } + let by_seq: BTreeMap<([u8; 32], u64), usize> = held.iter().enumerate().map(|(k, h)| ((h.ev.principal, h.ev.seq), k)).collect(); + let by_digest: BTreeMap<[u8; 32], usize> = held.iter().enumerate().map(|(k, h)| (h.digest, k)).collect(); + let powers = |h: &Held| -> u8 { + match h.under { + None => 0xff, + Some(g) => rr.grants.iter().find(|x| x.digest == g).map_or(0, |x| x.grant.caps.powers), + } + }; + // Step 4: the statements. + let mut statements: BTreeMap = BTreeMap::new(); + for h in &held { + if !is_statement_event(h) { + continue; + } + let at = At::Record { chain: h.chain, record: h.record }; + let before = h.ev.seq.checked_sub(1).and_then(|s| by_seq.get(&(h.ev.principal, s)).copied()); + let decision = match before { + Some(b) => { + let x = &held[b]; + if x.ev.kind != kind::DECISION || x.ev.t != h.ev.t { + return run.refuse(at, Reason::StatementMisplaced); + } + b + } + None if h.ev.seq == 0 => return run.refuse(at, Reason::StatementMisplaced), + None => continue, + }; + match Statement::parse(&h.ev.payload) { + Ok(s) => { + statements.insert(decision, s); + } + Err(r) => return run.refuse(at, r), + } + } + // The last decision in the merged order on each target, for §7.3. + let mut last_on: BTreeMap<[u8; 32], usize> = BTreeMap::new(); + for (k, h) in held.iter().enumerate() { + if let Payload::Decision { target, .. } = &h.payload { + last_on.insert(*target, k); + } + } + // Step 5: the gaps. + let mut remaining = Vec::new(); + let mut withheld: BTreeSet<[u8; 32]> = BTreeSet::new(); + for g in &room_gaps { + match explain(g, &held, &by_seq, &statements, &last_on) { + Some((e, ds)) => { + withheld.extend(ds); + run.explained.push(e); + } + None => remaining.push(*g), + } + } + let gap_remains = !remaining.is_empty(); + // Is a held event an item under review (§6.1), and under which entry? + let event_entry = |h: &Held, ps: &[ReviewPolicy]| -> Option { + if !DECIDABLE.contains(&h.ev.kind) || is_statement_event(h) || d.is_room_key(&h.ev.principal) || powers(h) & power::MODERATE != 0 { + return None; + } + policy_at(ps, h.ev.t).and_then(|p| p.entry(scope::KIND, h.ev.kind)).copied() + }; + let object_entry = |o: &Object, ps: &[ReviewPolicy]| -> Option { policy_at(ps, o.t).and_then(|p| p.entry(scope::MEDIA, o.media)).copied() }; + // Step 6: the decisions. + let mut line: BTreeMap<[u8; 32], [u8; 32]> = BTreeMap::new(); + let mut decided: BTreeMap<[u8; 32], usize> = BTreeMap::new(); + for (k, h) in held.iter().enumerate() { + let Payload::Decision { verdict: v, target: x, reason: code } = h.payload else { continue }; + let at = At::Record { chain: h.chain, record: h.record }; + let p = h.ev.principal; + let said = match statements.get(&k) { + Some(s) => Said::Known(s.clone()), + None if by_seq.contains_key(&(p, h.ev.seq + 1)) => Said::None, + None if in_gaps(&remaining, &p, h.ev.seq + 1) => Said::Unknown, + None => Said::None, + }; + let st = match &said { + Said::Known(s) => Some(s), + _ => None, + }; + let tt = st.map_or(target_type::EVENT, |s| s.target_type); + // 1. The reason. + let Some(pol) = run.policy_at(h.ev.t).cloned() else { return run.refuse(at, Reason::ReasonNotInPolicy) }; + match pol.reason(code) { + Some(rc) if st.is_none_or(|s| s.ground == rc.ground) => {} + _ => return run.refuse(at, Reason::ReasonNotInPolicy), + } + // 2. The target: its kind or media and `t` when held, and its entry. + let mut target: Option<(u8, u8, u64)> = None; + let mut entry: Option = None; + if tt == target_type::OBJECT { + match inp.objects.iter().find(|o| o.digest == x && o.t <= h.ev.t) { + Some(o) => { + target = Some((target_type::OBJECT, o.media, o.t)); + entry = object_entry(o, &run.policies); + } + None => return run.refuse(at, Reason::TargetUnknown), + } + } else if let Some(&ti) = by_digest.get(&x) { + let te = &held[ti]; + if ti >= k { + return run.refuse(at, Reason::TargetUnknown); + } + if !DECIDABLE.contains(&te.ev.kind) || is_statement_event(te) { + return run.refuse(at, Reason::TargetNotDecidable); + } + if st.is_some_and(|s| s.target_prev != te.ev.prev) { + return run.refuse(at, Reason::TargetPrevMismatch); + } + target = Some((target_type::EVENT, te.ev.kind, te.ev.t)); + entry = event_entry(te, &run.policies); + } else if !withheld.contains(&x) && !gap_remains { + return run.refuse(at, Reason::TargetUnknown); + } + // 3. The reviewer. + if entry.is_some() && !pol.reviewers.is_empty() && !d.is_room_key(&p) && !pol.reviewers.contains(&p) { + return run.refuse(at, Reason::NotReviewer); + } + // 4. The line. + if said != Said::Unknown { + let sup = st.map_or(ZERO, |s| s.supersedes); + let head = line.get(&x).copied(); + if sup == ZERO { + if head.is_some() { + return run.refuse(at, Reason::SupersedeGap); + } + } else { + match decided.get(&sup) { + Some(&yi) => { + if run.decisions[yi].target != x { + return run.refuse(at, Reason::SupersedeMismatch); + } + if head != Some(sup) { + return run.refuse(at, Reason::SupersedeGap); + } + } + None if gap_remains => {} + None => return run.refuse(at, Reason::SupersedeUnknown), + } + } + } + // 5. The basis. + if let Some(s) = st { + match s.basis { + basis::NOTICE | basis::COMPLAINT => { + let want = if s.basis == basis::NOTICE { notice_type::NOTICE } else { notice_type::COMPLAINT }; + let Some((n, _)) = run.notices.iter().find(|(n, g)| *g == s.notice && n.ntype == want) else { + return run.refuse(at, Reason::NoticeUnknown); + }; + let aims = if s.basis == basis::NOTICE { n.target == x && n.target_type == tt } else { n.target == s.supersedes }; + if !aims || n.t > h.ev.t { + return run.refuse(at, Reason::NoticeMismatch); + } + } + basis::FALLBACK => { + if !d.is_room_key(&p) { + return run.refuse(at, Reason::FallbackNotInPolicy); + } + if let Some((_, _, item_t)) = target { + let Some(e) = entry else { return run.refuse(at, Reason::FallbackNotInPolicy) }; + if e.fallback == fallback::HOLD || v != e.fallback || code != e.fallback_reason { + return run.refuse(at, Reason::FallbackNotInPolicy); + } + if h.ev.t < item_t + e.deadline_ms as u64 * 1000 { + return run.refuse(at, Reason::FallbackEarly); + } + } + } + _ => {} + } + } + line.insert(x, h.digest); + decided.insert(h.digest, run.decisions.len()); + run.decisions.push(DecisionFacts { digest: h.digest, decider: p, t: h.ev.t, target: x, target_type: tt, verdict: v, reason: code, statement: said, standing: false }); + run.targets.push(target); + } + for dfact in run.decisions.iter_mut() { + dfact.standing = line.get(&dfact.target) == Some(&dfact.digest); + } + // Step 7: the outcome, then the items and the exports. + run.outcome = if gap_remains { Outcome::Gap(remaining) } else { Outcome::Accept }; + let on = |digest: &[u8; 32], tt: u8| -> Vec<&DecisionFacts> { run.decisions.iter().filter(|x| x.target == *digest && x.target_type == tt).collect() }; + let mut items = Vec::new(); + for h in &held { + let entry = event_entry(h, &run.policies); + let ds = on(&h.digest, target_type::EVENT); + if entry.is_some() || !ds.is_empty() { + items.push(item(h.digest, target_type::EVENT, h.ev.kind, h.ev.t, entry, &ds)); + } + } + for o in inp.objects { + let entry = object_entry(o, &run.policies); + let ds = on(&o.digest, target_type::OBJECT); + if entry.is_some() || !ds.is_empty() { + items.push(item(o.digest, target_type::OBJECT, o.media, o.t, entry, &ds)); + } + } + run.items = items; + run.exports = (0..run.decisions.len()).map(|i| export(&run, i)).collect(); + run +} + +/// §7.3: is gap `g` explained, and by which decisions (from `first` to `last`)? With the +/// digests of the events it withholds. +fn explain( + g: &events::Gap, + held: &[Held], + by_seq: &BTreeMap<([u8; 32], u64), usize>, + statements: &BTreeMap, + last_on: &BTreeMap<[u8; 32], usize>, +) -> Option<(Explained, Vec<[u8; 32]>)> { + let after = *by_seq.get(&(g.principal, g.last + 1))?; + let mut d = held[after].ev.prev; + let mut decisions = Vec::new(); + let mut digests = Vec::new(); + for _ in g.first..=g.last { + let k = *last_on.get(&d)?; + let s = statements.get(&k)?; + let restricts = matches!(held[k].payload, Payload::Decision { verdict: v, .. } if v != verdict::ALLOW); + if s.target_type != target_type::EVENT || !restricts { + return None; + } + decisions.push(held[k].digest); + digests.push(d); + d = s.target_prev; + } + let start = if g.first == 0 { ZERO } else { held[*by_seq.get(&(g.principal, g.first - 1))?].digest }; + if d != start { + return None; + } + decisions.reverse(); + Some((Explained { principal: g.principal, first: g.first, last: g.last, decisions }, digests)) +} + +/// An item's timeline (§6.2): its first state, the fallback at its deadline when no decision +/// came by it, and each decision on it. +fn item(digest: [u8; 32], tt: u8, code: u8, t: u64, entry: Option, ds: &[&DecisionFacts]) -> ItemFacts { + let first = match entry { + None => State::Shown, + Some(e) if e.mode == mode::PRE => State::Held, + Some(_) => State::Pending, + }; + let mut timeline = vec![(t, first, None)]; + if let Some(e) = entry { + let due = t + e.deadline_ms as u64 * 1000; + // A fallback decision records the fallback; any other decision by the deadline forestalls it. + if !ds.iter().any(|x| x.t <= due && x.basis() != basis::FALLBACK) { + let f = match e.fallback { + fallback::ALLOW => State::FallbackAllow, + fallback::DENY => State::FallbackDeny, + _ => State::FallbackHold, + }; + timeline.push((due, f, None)); + } + } + for x in ds { + timeline.push((x.t, State::of_verdict(x.verdict), Some(x.digest))); + } + ItemFacts { digest, target_type: tt, code, t, entry, timeline } +} + +// --------------------------------------------------------------------------------------- +// §8.3 Clips +// --------------------------------------------------------------------------------------- + +/// The outcome of a clip under moderation (§8.3). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ClipRun { + Refuse { at: ClipPlace, reason: Reason }, + /// What live-recording's clip verifier states, and for each part its restricted chunks: + /// the chunk's index and the decision that restricts it. + Accept { facts: ClipFacts, withheld: Vec> }, +} + +/// Verify a clip under moderation (§8.3): live-recording §5.4 with every restricted chunk passed +/// over in step (k), then no restricted chunk's bytes given. `restricted` maps a chunk's leaf to +/// the standing decision that restricts it ([`Run::restricted_objects`]). +pub fn verify_clip(descriptor: &[u8], clip_record: &[u8], parts: &[PartInputs], restricted: &BTreeMap<[u8; 32], [u8; 32]>) -> ClipRun { + let exempt = |c: &Chunk| restricted.contains_key(&c.leaf()); + let facts = match record::verify_clip_exempting(descriptor, clip_record, parts, &exempt) { + ClipOutcome::Refuse { at, reason } => return ClipRun::Refuse { at, reason: Reason::Record(reason) }, + ClipOutcome::Accept(f) => f, + }; + let clip = record::Clip::parse(clip_record).expect("an accepted clip reads"); + let mut withheld = Vec::new(); + for (k, (p, i)) in clip.parts.iter().zip(parts).enumerate() { + let mut w = Vec::new(); + for (j, c) in p.chunks.iter().enumerate() { + if let Some(decision) = restricted.get(&c.leaf()) { + if i.bytes.get(j).is_some_and(Option::is_some) { + return ClipRun::Refuse { at: ClipPlace::Chunk { part: k, index: j }, reason: Reason::RedactionNotApplied }; + } + w.push((c.index, *decision)); + } + } + withheld.push(w); + } + ClipRun::Accept { facts, withheld } +} + +// --------------------------------------------------------------------------------------- +// §9 The statement-of-reasons export +// --------------------------------------------------------------------------------------- + +/// A string as §9.2 writes it. +pub fn json_string(s: &str) -> String { + let mut o = String::with_capacity(s.len() + 2); + o.push('"'); + for c in s.chars() { + match c { + '"' => o.push_str("\\\""), + '\\' => o.push_str("\\\\"), + '\u{8}' => o.push_str("\\b"), + '\t' => o.push_str("\\t"), + '\n' => o.push_str("\\n"), + '\u{c}' => o.push_str("\\f"), + '\r' => o.push_str("\\r"), + c if (c as u32) < 0x20 => o.push_str(&format!("\\u{:04x}", c as u32)), + c => o.push(c), + } + } + o.push('"'); + o +} + +/// The UTC date of room-clock `t` (§9.2). +fn date(t0_us: u64, t: u64) -> Option { + let us = t0_us.checked_add(t)?; + events::iso8601_ms(us / 1000).map(|s| s[..10].to_string()) +} + +/// `content_type` and `content_type_other` for a target (§9.6). +pub fn content_type(target_type: u8, code: u8) -> (&'static str, Option<&'static str>) { + if target_type == target_type::OBJECT { + return (if code == 1 { "CONTENT_TYPE_AUDIO" } else { "CONTENT_TYPE_VIDEO" }, None); + } + match code { + kind::REACTION => ("CONTENT_TYPE_OTHER", Some("reaction")), + kind::VOTE => ("CONTENT_TYPE_OTHER", Some("poll vote")), + kind::POLL_CLOSE => ("CONTENT_TYPE_OTHER", Some("poll tally")), + kind::META => ("CONTENT_TYPE_OTHER", Some("timed metadata")), + kind::CUE => ("CONTENT_TYPE_OTHER", Some("cue")), + _ => ("CONTENT_TYPE_TEXT", None), + } +} + +/// `source_type` of decision `i` (§9.3), or `None` when it cannot be written. +fn source_type(run: &Run, i: usize) -> Option<&'static str> { + let x = &run.decisions[i]; + match &x.statement { + Said::Unknown => None, + Said::None => Some("SOURCE_VOLUNTARY"), + Said::Known(s) => match s.basis { + basis::NOTICE => { + let (n, _) = run.notices.iter().find(|(_, g)| *g == s.notice)?; + let flagger = run.policy_at(x.t).is_some_and(|p| p.flaggers.contains(&n.submitter)); + Some(match (n.ground, flagger) { + (ground::ILLEGAL, true) => "SOURCE_TRUSTED_FLAGGER", + (ground::ILLEGAL, false) => "SOURCE_ARTICLE_16", + _ => "SOURCE_TYPE_OTHER_NOTIFICATION", + }) + } + basis::COMPLAINT => { + let y = run.decisions[..i].iter().position(|y| y.digest == s.supersedes)?; + source_type(run, y) + } + _ => Some("SOURCE_VOLUNTARY"), + }, + } +} + +/// Decision `i`'s export (§9): the record, none for an allow, or the member §9.8 names. +fn export(run: &Run, i: usize) -> Export { + let x = &run.decisions[i]; + if x.verdict == verdict::ALLOW { + return Export::None; + } + let inc = Export::Incomplete; + let Some(s) = x.known() else { return inc("decision_facts") }; + let cp = |t: &str| t.chars().count(); + if !(1..=5000).contains(&cp(&s.facts)) { + return inc("decision_facts"); + } + let pol = run.policy_at(x.t).expect("a decision verified under a policy in effect"); + let rc = pol.reason(x.reason).expect("a reason code of its vocabulary"); + let (gname, ename, gvalue) = if s.ground == ground::ILLEGAL { + ("illegal_content_legal_ground", "illegal_content_explanation", "DECISION_GROUND_ILLEGAL_CONTENT") + } else { + ("incompatible_content_ground", "incompatible_content_explanation", "DECISION_GROUND_INCOMPATIBLE_CONTENT") + }; + let gref = if s.ground_ref.is_empty() { &rc.reference } else { &s.ground_ref }; + if !(1..=500).contains(&cp(gref)) { + return inc(gname); + } + if !(1..=2000).contains(&cp(&s.explanation)) { + return inc(ename); + } + let Some((tt, code, target_t)) = run.targets[i] else { return inc("content_type") }; + let (ctype, other) = content_type(tt, code); + let Some(cdate) = date(run.t0_us, target_t).filter(|d| ("2000-01-01"..="2038-01-01").contains(&d.as_str())) else { + return inc("content_date"); + }; + let Some(adate) = date(run.t0_us, x.t).filter(|d| ("2020-01-01"..="2038-01-01").contains(&d.as_str())) else { + return inc("application_date"); + }; + let Some(source) = source_type(run, i) else { return inc("source_type") }; + let mut o = String::from("{"); + let mut member = |name: &str, value: String| { + if o.len() > 1 { + o.push(','); + } + o.push_str(&json_string(name)); + o.push(':'); + o.push_str(&value); + }; + let array = |vs: &[&str]| format!("[{}]", vs.iter().map(|v| json_string(v)).collect::>().join(",")); + let visibility = if x.verdict == verdict::DENY { "DECISION_VISIBILITY_CONTENT_DISABLED" } else { "DECISION_VISIBILITY_CONTENT_REMOVED" }; + member("decision_visibility", array(&[visibility])); + member("decision_facts", json_string(&s.facts)); + member("decision_ground", json_string(gvalue)); + if !rc.url.is_empty() { + member("decision_ground_reference_url", json_string(&rc.url)); + } + member(gname, json_string(gref)); + member(ename, json_string(&s.explanation)); + member("content_type", array(&[ctype])); + if let Some(other) = other { + member("content_type_other", json_string(other)); + } + member("category", json_string(CATEGORIES[rc.category as usize - 1])); + let terr: Vec<&str> = pol.territory.iter().map(|t| std::str::from_utf8(t).expect("ASCII capitals")).collect(); + member("territorial_scope", array(&terr)); + member("content_date", json_string(&cdate)); + member("application_date", json_string(&adate)); + member("source_type", json_string(source)); + member("automated_detection", json_string(if s.automated & 1 != 0 { "Yes" } else { "No" })); + let automated = match (s.automated >> 1) & 3 { + 0 => "AUTOMATED_DECISION_NOT_AUTOMATED", + 1 => "AUTOMATED_DECISION_PARTIALLY", + _ => "AUTOMATED_DECISION_FULLY", + }; + member("automated_decision", json_string(automated)); + member("puid", json_string(&hex(&x.digest))); + o.push('}'); + Export::Record(o.into_bytes()) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn policy() -> ReviewPolicy { + ReviewPolicy { + room: [7; 32], + prev: ZERO, + effective: 0, + reviewers: vec![[1; 32], [2; 32]], + flaggers: vec![[3; 32]], + entries: vec![ + Entry { scope: scope::KIND, code: kind::CHAT, mode: mode::PRE, deadline_ms: 5000, fallback: fallback::DENY, fallback_reason: 900 }, + Entry { scope: scope::MEDIA, code: 2, mode: mode::POST, deadline_ms: 60_000, fallback: fallback::ALLOW, fallback_reason: 0 }, + ], + reasons: vec![ + ReasonCode { code: 101, ground: ground::INCOMPATIBLE, category: 10, reference: "Terms §4.2".into(), url: "https://rooms.example/terms".into() }, + ReasonCode { code: 900, ground: ground::INCOMPATIBLE, category: 10, reference: "Terms §6".into(), url: String::new() }, + ], + territory: vec![*b"DE", *b"FR"], + redress: "Complain within six months.".into(), + sig: [0; 64], + } + .sign(&SigningKey::from_bytes(&[9; 32])) + } + + #[test] + fn a_policy_round_trips_and_its_rules_hold() { + let p = policy(); + assert_eq!(ReviewPolicy::parse(&p.to_bytes()), Ok(p.clone())); + let b = p.to_bytes(); + assert_eq!(ReviewPolicy::parse(&b[..b.len() - 1]), Err(ev(events::Reason::Truncated))); + let mut extra = b.clone(); + extra.push(0); + assert_eq!(ReviewPolicy::parse(&extra), Err(ev(events::Reason::Malformed))); + for broken in [ + ReviewPolicy { territory: vec![*b"FR", *b"DE"], ..p.clone() }, + ReviewPolicy { territory: vec![*b"US"], ..p.clone() }, + ReviewPolicy { entries: vec![Entry { fallback: 4, ..p.entries[0] }], ..p.clone() }, + ReviewPolicy { entries: vec![Entry { code: kind::DECISION, ..p.entries[0] }], ..p.clone() }, + ReviewPolicy { entries: vec![Entry { fallback_reason: 555, ..p.entries[0] }], ..p.clone() }, + ReviewPolicy { reasons: vec![ReasonCode { url: "http://x".into(), ..p.reasons[0].clone() }, p.reasons[1].clone()], ..p.clone() }, + ReviewPolicy { reviewers: vec![[2; 32], [1; 32]], ..p.clone() }, + ] { + assert_eq!(ReviewPolicy::parse(&broken.to_bytes()), Err(Reason::PolicyMalformed), "{broken:?}"); + } + } + + fn statement() -> Statement { + Statement { + target_type: target_type::EVENT, + target_prev: [4; 32], + supersedes: ZERO, + basis: basis::OWN, + notice: ZERO, + automated: 0b011, + ground: ground::INCOMPATIBLE, + ground_ref: String::new(), + explanation: "Unsolicited promotion.".into(), + facts: "A link to a shop, posted three times.".into(), + } + } + + #[test] + fn a_statement_round_trips_and_its_rules_hold() { + let s = statement(); + let b = s.encode(); + assert_eq!(b.len(), STATEMENT_HEAD + 6 + s.ground_ref.len() + s.explanation.len() + s.facts.len()); + assert_eq!(Statement::parse(&b), Ok(s.clone())); + let bad = Err(Reason::StatementMalformed); + assert_eq!(Statement::parse(&b[..b.len() - 1]), bad); + for broken in [ + Statement { target_type: 3, ..s.clone() }, + Statement { target_type: target_type::OBJECT, ..s.clone() }, + Statement { basis: basis::NOTICE, ..s.clone() }, + Statement { notice: [1; 32], ..s.clone() }, + Statement { automated: 0b110, ..s.clone() }, + Statement { automated: 0b1000, ..s.clone() }, + Statement { basis: basis::FALLBACK, automated: 0b010, ..s.clone() }, + Statement { ground: 0, ..s.clone() }, + ] { + assert_eq!(Statement::parse(&broken.encode()), bad, "{broken:?}"); + } + assert!(Statement::parse(&Statement { basis: basis::FALLBACK, automated: 0b100, ..s }.encode()).is_ok()); + } + + #[test] + fn a_notice_round_trips_and_its_rules_hold() { + let k = SigningKey::from_bytes(&[5; 32]); + let n = Notice { + room: [7; 32], + ntype: notice_type::NOTICE, + target_type: target_type::EVENT, + target: [8; 32], + t: 9, + ground: ground::ILLEGAL, + good_faith: 1, + ground_ref: "Regulation (EU) 2016/679, Article 6(1)".into(), + statement: "It discloses a private phone number.".into(), + contact: "someone@example.org".into(), + submitter: ZERO, + sig: [0; 64], + } + .sign(&k); + assert_eq!(Notice::parse(&n.to_bytes()), Ok(n.clone())); + assert!(verify_sig(&n.submitter, NOTICE_DOMAIN, &n.body(), &n.sig).is_ok()); + for broken in [Notice { ntype: 3, ..n.clone() }, Notice { ground: 0, ..n.clone() }, Notice { good_faith: 2, ..n.clone() }, Notice { ntype: 2, ..n.clone() }] { + assert_eq!(Notice::parse(&broken.to_bytes()), Err(Reason::NoticeMalformed)); + } + } + + #[test] + fn strings_are_written_as_section_9_2_has_them() { + assert_eq!(json_string("a\"b\\c\n\u{1}é"), "\"a\\\"b\\\\c\\n\\u0001é\""); + assert_eq!(json_string("\u{8}\u{c}\r\t\u{1f}"), "\"\\b\\f\\r\\t\\u001f\""); + } + + #[test] + fn dates_are_utc_days() { + assert_eq!(date(0, 0).as_deref(), Some("1970-01-01")); + assert_eq!(date(1_792_108_800_000_000, 86_399_999_999).as_deref(), date(1_792_108_800_000_000, 0).as_deref()); + assert_eq!(date(u64::MAX, 1), None); + } + + #[test] + fn content_types_follow_the_table() { + assert_eq!(content_type(target_type::EVENT, kind::CHAT), ("CONTENT_TYPE_TEXT", None)); + assert_eq!(content_type(target_type::EVENT, kind::REACTION), ("CONTENT_TYPE_OTHER", Some("reaction"))); + assert_eq!(content_type(target_type::OBJECT, 1), ("CONTENT_TYPE_AUDIO", None)); + assert_eq!(content_type(target_type::OBJECT, 3), ("CONTENT_TYPE_VIDEO", None)); + } + + #[test] + fn the_states_that_show_an_item() { + let shown: Vec<&str> = + [State::Shown, State::Held, State::Pending, State::Allowed, State::Denied, State::Redacted, State::FallbackAllow, State::FallbackDeny, State::FallbackHold] + .iter() + .filter(|s| s.visible()) + .map(|s| s.name()) + .collect(); + assert_eq!(shown, ["shown", "pending", "allowed", "fallback_allow"]); + } +} diff --git a/wai/wai-rs/src/live_moderation/corpus.rs b/wai/wai-rs/src/live_moderation/corpus.rs new file mode 100644 index 000000000..636a79687 --- /dev/null +++ b/wai/wai-rs/src/live_moderation/corpus.rs @@ -0,0 +1,1339 @@ +//! The conformance corpus of extensions/live-moderation.md §11: `live-conformance/moderation/`. +//! +//! [`generate`] writes it from fixed seeds: every key of the chat rooms is SHA-256 of this +//! corpus's label and an index, every time is a constant, every text is written here, and +//! Ed25519 signing is deterministic (RFC 8032), so every file is the same bytes on every +//! machine. The recorded take is live-recording's lesson session, written by that corpus's own +//! rules, so its room, its chains and its chunks are that corpus's byte for byte; this corpus +//! adds a moderator's decisions to the director's chain. Each vector states the outcome it was +//! written to have, and the generator asserts that this module reaches it before writing it, +//! and that the corpus gives every reason of §10. +//! +//! [`verify`] checks a corpus directory's files against this module. +//! `live-conformance/live_moderation_verify.py` checks the same files from the extension's +//! text, sharing no code with this module. + +use super::*; +use crate::capture_take::corpus as ct; +use crate::live_events::{Policy as EventPolicy, Reaction}; +use crate::live_record::corpus::{lesson_written, Written}; +use crate::live_record::{cut_clip, cut_part, mapped_span, resolve_bytes, split_chain, TakeSource}; +use crate::live_room::{media, Caps, Detail, Grant, Limits, Recording, Review, Role, NO_CEILING}; +use serde_json::{json, Map, Value}; + +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 AUTHORITY: u8 = 0; +const CLOCK: u8 = 1; +const HOST: u8 = 2; +const MODERATOR: u8 = 3; +const VIEWER_A: u8 = 4; +const VIEWER_B: u8 = 5; +const SUBMITTER: u8 = 6; +const FLAGGER: u8 = 7; +const PRINCIPALS: [(&str, u8); 8] = [ + ("authority", AUTHORITY), + ("clock", CLOCK), + ("host", HOST), + ("moderator", MODERATOR), + ("viewer_a", VIEWER_A), + ("viewer_b", VIEWER_B), + ("submitter", SUBMITTER), + ("flagger", FLAGGER), +]; +/// The lesson room's principals this corpus names (live-recording's, under capture binding's +/// key label). +const LESSON_PRINCIPALS: [(&str, u8); 5] = + [("authority", ct::AUTHORITY), ("relay", ct::RELAY), ("director", ct::DIRECTOR), ("device", ct::DEVICE), ("performer", ct::PERFORMER)]; + +fn sha(parts: &[&[u8]]) -> [u8; 32] { + sha256(parts) +} + +fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&sha(&[b"wai:live-moderation/corpus/key\x00", &[i]])) +} + +fn pk(i: u8) -> [u8; 32] { + key(i).verifying_key().to_bytes() +} + +/// A digest naming nothing of any room. +fn nothing(label: &str) -> [u8; 32] { + sha(&[b"wai:live-moderation/corpus/nothing\x00", label.as_bytes()]) +} + +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 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 d32(s: &str) -> Option<[u8; 32]> { + unhex(s)?.try_into().ok() +} + +// ---- rooms ---- + +/// A principal's chain being written. +struct Author { + pk: [u8; 32], + seq: u64, + prev: [u8; 32], + records: Vec>, +} + +/// A room being written: its descriptor, grants and key-log head, and its chains. +#[derive(Default)] +struct Room { + descriptor: Vec, + id: [u8; 32], + grants: Vec>, + head: Option, + authors: Vec, + /// Each `join` the clock wrote, by its subject. + joins: BTreeMap, +} + +impl Clone for Room { + fn clone(&self) -> Self { + Room { + descriptor: self.descriptor.clone(), + id: self.id, + grants: self.grants.clone(), + head: self.head.clone(), + authors: self.authors.iter().map(|a| Author { pk: a.pk, seq: a.seq, prev: a.prev, records: a.records.clone() }).collect(), + joins: self.joins.clone(), + } + } +} + +impl Room { + fn raw(&mut self, k: &SigningKey, t: u64, kind: u8, payload: Vec) -> [u8; 32] { + let me = k.verifying_key().to_bytes(); + let i = match self.authors.iter().position(|a| a.pk == me) { + Some(i) => i, + None => { + self.authors.push(Author { pk: me, seq: 0, prev: ZERO, records: vec![] }); + self.authors.len() - 1 + } + }; + let a = &mut self.authors[i]; + let e = Event::sign(k, self.id, a.seq, a.prev, t, None, kind, payload); + a.seq += 1; + a.prev = e.digest(); + a.records.push(e.to_bytes()); + a.prev + } + + fn emit(&mut self, k: &SigningKey, t: u64, p: &Payload) -> [u8; 32] { + self.raw(k, t, p.kind(), p.encode()) + } + + /// A decision, and its statement right after it when it has one. + fn decide(&mut self, k: &SigningKey, t: u64, v: u8, target: [u8; 32], reason: u16, st: Option<&Statement>) -> [u8; 32] { + let d = self.emit(k, t, &Payload::Decision { verdict: v, target, reason }); + if let Some(s) = st { + self.raw(k, t, kind::META, s.encode()); + } + d + } + + fn chains(&self) -> Vec>> { + self.authors.iter().map(|a| a.records.clone()).collect() + } + + fn event(&self, digest: &[u8; 32]) -> Event { + self.authors.iter().flat_map(|a| a.records.iter()).map(|r| Event::parse(r).expect("a corpus record")).find(|e| e.digest() == *digest).expect("a record of the room") + } + + /// The `prev` of an event of the room, for a statement's `target_prev`. + fn prev_of(&self, digest: &[u8; 32]) -> [u8; 32] { + self.event(digest).prev + } + + /// The room as a subscriber sees it when these records are withheld from it. + fn without(&self, digests: &[[u8; 32]]) -> Room { + let mut r = self.clone(); + for a in r.authors.iter_mut() { + a.records.retain(|b| !digests.contains(&Event::parse(b).expect("a corpus record").digest())); + } + r + } +} + +fn role(name: &str, powers: u8, events: &[u8]) -> Role { + Role { name: name.into(), caps: Caps { publish: 0, subscribe: true, max_layer: 1, powers }, events: bits(events) } +} + +fn chat(s: &str) -> Payload { + Payload::Chat { text: s.into() } +} + +fn emoji(target: Option<[u8; 32]>) -> Payload { + Payload::Reaction(Reaction { rtype: 1, value: 1, target, remove: false }) +} + +/// The chat room: a host and a moderator with the moderate power, two viewers, and the +/// descriptor's review field holding every chat message five seconds, then denying it. +fn chat_room() -> Room { + use kind::*; + let d = Descriptor { + authority: pk(AUTHORITY), + clock: pk(CLOCK), + t0_us: T0_US, + tick_us: S, + origin: String::new(), + limits: Limits { max_present: 16, max_publishers: 4, reval_s: 0, ceiling: EventPolicy::default() }, + roles: vec![ + role("host", power::MODERATE, &[META, CHAT, REACTION, DECISION]), + role("moderator", power::MODERATE, &[META, CHAT, DECISION]), + role("audience", 0, &[CHAT, REACTION]), + ], + slots: vec![], + profiles: vec![], + review: Review { kinds: bits(&[CHAT]), deadline_ms: 5_000, fallback: fallback::DENY }, + recording: Recording { mode: 0, retention_days: 0, commit_interval_ms: 0, jitter_ms: 0, regions: vec![] }, + sig: [0; 64], + } + .sign(&key(AUTHORITY)); + let id = d.room_id(); + let grant = |who: u8, r: usize| { + let role = &d.roles[r]; + let kinds: Vec = (0..=255u8).filter(|&k| has_kind(&role.events, k)).collect(); + Grant { + room: id, + principal: pk(who), + prev: ZERO, + effective: 0, + nbf: T0_S - 3_600, + exp: T0_S + 86_400, + role: r as u8, + caps: role.caps, + precedence: 0, + once: [0; 16], + viewer: [0; 16], + policy: EventPolicy::with_kinds(&kinds), + joules_ceiling: NO_CEILING, + funds_ceiling: NO_CEILING, + currency: [0; 3], + profiles: vec![], + origins: vec!["https://relay.rooms.example".into()], + attrs: vec![], + sig: [0; 64], + } + .sign(&key(AUTHORITY)) + }; + let gs = [grant(HOST, 0), grant(MODERATOR, 1), grant(VIEWER_A, 2), grant(VIEWER_B, 2)]; + let mut room = Room { descriptor: d.to_bytes(), id, grants: gs.iter().map(Grant::to_bytes).collect(), ..Default::default() }; + for (who, g) in [HOST, MODERATOR, VIEWER_A, VIEWER_B].into_iter().zip(&gs) { + let j = Detail::Join { grant: g.digest() }; + let digest = room.emit(&key(CLOCK), 0, &Payload::Lifecycle { kind: j.kind(), subject: pk(who), detail: j.encode() }); + room.joins.insert(who, digest); + } + room +} + +/// The chat rooms' vocabulary. +fn vocabulary() -> Vec { + let rc = |code, ground, category, reference: &str, url: &str| ReasonCode { code, ground, category, reference: reference.into(), url: url.into() }; + vec![ + rc(101, ground::INCOMPATIBLE, 10, "Room terms, clause 4.2: no unsolicited promotion", "https://rooms.example/terms#4.2"), + rc(102, ground::INCOMPATIBLE, 3, "Room terms, clause 4.1: no harassment of participants", "https://rooms.example/terms#4.1"), + rc(201, ground::ILLEGAL, 5, "Regulation (EU) 2016/679, Article 6(1)", ""), + rc(301, ground::ILLEGAL, 7, "Directive 2001/29/EC, Article 3(1)", ""), + rc(900, ground::INCOMPATIBLE, 10, "Room terms, clause 6: a message held for review and not reviewed by its deadline is not shown", "https://rooms.example/terms#6"), + ] +} + +const REDRESS: &str = "A participant whose message is restricted can complain within six months by a signed complaint naming the decision; out-of-court dispute settlement and judicial redress remain open."; + +const CHAT_ENTRY: Entry = Entry { scope: scope::KIND, code: kind::CHAT, mode: mode::PRE, deadline_ms: 5_000, fallback: fallback::DENY, fallback_reason: 900 }; +const REACTION_ENTRY: Entry = Entry { scope: scope::KIND, code: kind::REACTION, mode: mode::POST, deadline_ms: 10_000, fallback: fallback::HOLD, fallback_reason: 900 }; + +fn chat_policy(room: [u8; 32], prev: [u8; 32], effective: u64, entries: Vec) -> ReviewPolicy { + ReviewPolicy { + room, + prev, + effective, + reviewers: vec![pk(MODERATOR)], + flaggers: vec![pk(FLAGGER)], + entries, + reasons: vocabulary(), + territory: TERRITORY.iter().map(|c| <[u8; 2]>::try_from(c.as_bytes()).expect("two letters")).collect(), + redress: REDRESS.into(), + sig: [0; 64], + } + .sign(&key(AUTHORITY)) +} + +#[allow(clippy::too_many_arguments)] +fn said(tt: u8, target_prev: [u8; 32], supersedes: [u8; 32], b: u8, notice: [u8; 32], automated: u8, g: u8, explanation: &str, facts: &str) -> Statement { + Statement { target_type: tt, target_prev, supersedes, basis: b, notice, automated, ground: g, ground_ref: String::new(), explanation: explanation.into(), facts: facts.into() } +} + +#[allow(clippy::too_many_arguments)] +fn notice(room: [u8; 32], ntype: u8, tt: u8, target: [u8; 32], t: u64, g: u8, ground_ref: &str, statement: &str, contact: &str, by: &SigningKey) -> Notice { + Notice { + room, + ntype, + target_type: tt, + target, + t, + ground: g, + good_faith: 1, + ground_ref: ground_ref.into(), + statement: statement.into(), + contact: contact.into(), + submitter: ZERO, + sig: [0; 64], + } + .sign(by) +} + +// ---- vectors ---- + +/// What a vector was written to do. +#[derive(Clone, Copy, Debug)] +enum Intent { + Accept, + /// Accepted, with a decision's export refused `sor_incomplete` at this member. + Incomplete(&'static str), + Gap, + /// Refused, at a place of this kind (`room`, `policy`, `notice`, `record`), with this reason. + Refuse(&'static str, Reason), +} + +struct Vector { + name: &'static str, + about: &'static str, + room: Room, + policies: Vec>, + notices: Vec>, + objects: Vec, + intent: Intent, +} + +impl Vector { + fn input<'a>(&'a self, chains: &'a [Vec>]) -> Input<'a> { + Input { + descriptor: &self.room.descriptor, + grants: &self.room.grants, + head: self.room.head.as_deref(), + chains, + policies: &self.policies, + notices: &self.notices, + objects: &self.objects, + } + } +} + +const ALLOW_M1: &str = "The message is a greeting; it promotes nothing."; +const FACTS_M1: &str = "Reviewed while held: a greeting to the room."; +const DENY_M2: &str = "The message advertises a paid service to the room's participants, which clause 4.2 of the room's terms does not allow."; +const FACTS_M2: &str = "Held for review at 11.5 s of the session; a classifier flagged its link, and a reviewer read the message and denied it at 12.5 s."; +const FALLBACK_M3: &str = "No reviewer decided on the message within the room's five-second deadline, and clause 6 of the room's terms withholds such a message."; +const FACTS_M3: &str = "Held for review at 12 s of the session; no decision by 17 s."; + +/// The chat room's first messages: viewer A's three, held for review under the first policy. +struct Base { + room: Room, + p1: ReviewPolicy, + m1: [u8; 32], + m2: [u8; 32], + m3: [u8; 32], +} + +fn base() -> Base { + let mut room = chat_room(); + let p1 = chat_policy(room.id, ZERO, 0, vec![CHAT_ENTRY]); + let a = key(VIEWER_A); + let m1 = room.emit(&a, 10 * S, &chat("hello everyone, glad to be here")); + let m2 = room.emit(&a, 11 * S + 500 * MS, &chat("cheap followers at shop.example, today only")); + let m3 = room.emit(&a, 12 * S, &chat("cheap followers at shop.example, last chance")); + Base { room, p1, m1, m2, m3 } +} + +fn allow_m1(b: &mut Base) -> [u8; 32] { + let s = said(target_type::EVENT, b.room.prev_of(&b.m1), ZERO, basis::OWN, ZERO, 0, ground::INCOMPATIBLE, ALLOW_M1, FACTS_M1); + b.room.decide(&key(MODERATOR), 11 * S, verdict::ALLOW, b.m1, 101, Some(&s)) +} + +fn deny_m2_statement(b: &Base) -> Statement { + said(target_type::EVENT, b.room.prev_of(&b.m2), ZERO, basis::OWN, ZERO, 0b001, ground::INCOMPATIBLE, DENY_M2, FACTS_M2) +} + +fn fallback_m3_statement(b: &Base) -> Statement { + said(target_type::EVENT, b.room.prev_of(&b.m3), ZERO, basis::FALLBACK, ZERO, 0b100, ground::INCOMPATIBLE, FALLBACK_M3, FACTS_M3) +} + +/// The pre-moderated chat room and its policies, with viewer A's first three messages. +type Premoderated = (Room, Vec>, [u8; 32], [u8; 32], [u8; 32]); + +/// The pre-moderated chat room, whole: what a reviewer holds. +fn premoderated() -> Premoderated { + let mut b = base(); + allow_m1(&mut b); + let s2 = deny_m2_statement(&b); + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s2)); + b.room.emit(&key(VIEWER_A), 13 * S, &emoji(None)); + let s3 = fallback_m3_statement(&b); + b.room.decide(&key(CLOCK), 17 * S, verdict::DENY, b.m3, 900, Some(&s3)); + let p2 = chat_policy(b.room.id, b.p1.digest(), 20 * S, vec![CHAT_ENTRY, REACTION_ENTRY]); + b.room.emit(&key(VIEWER_B), 25 * S, &emoji(None)); + let m4 = b.room.emit(&key(VIEWER_B), 26 * S, &chat("is the next session on Friday?")); + b.room.decide(&key(MODERATOR), 28 * S, verdict::ALLOW, m4, 101, None); + b.room.emit(&key(HOST), 30 * S, &chat("welcome, everyone")); + (b.room, vec![b.p1.to_bytes(), p2.to_bytes()], b.m1, b.m2, b.m3) +} + +fn vector(name: &'static str, about: &'static str, room: Room, policies: Vec>, notices: Vec>, objects: Vec, intent: Intent) -> Vector { + Vector { name, about, room, policies, notices, objects, intent } +} + +fn chat_vectors() -> Vec { + let mut out = Vec::new(); + // A pre-moderated chat room, whole and as a subscriber that is not a reviewer sees it. + let (room, policies, m1, m2, m3) = premoderated(); + out.push(vector( + "premoderated_chat", + "chat held five seconds under the room's review field: one message allowed, one denied, one denied by the fallback the clock signs; a second policy reviews reactions after delivery, and one is held at its deadline", + room.clone(), + policies.clone(), + vec![], + vec![], + Intent::Accept, + )); + out.push(vector( + "subscriber_view", + "the same room as a subscriber that is not a reviewer receives it: the denied message and the fallback's are withheld, and the gap they leave is explained by the decisions", + room.without(&[m2, m3]), + policies.clone(), + vec![], + vec![], + Intent::Accept, + )); + out.push(vector( + "unexplained_gap", + "the same room with the allowed message withheld: no restriction explains the gap, which remains a delivery gap", + room.without(&[m1]), + policies, + vec![], + vec![], + Intent::Gap, + )); + // A notice and its decision; a trusted flagger's notice and its redaction. + { + let mut room = chat_room(); + let p1 = chat_policy(room.id, ZERO, 0, vec![CHAT_ENTRY]); + let (m, v) = (key(MODERATOR), key(VIEWER_B)); + let m5 = room.emit(&v, 10 * S, &chat("for extra lessons, ring the teacher at home on 555 0100")); + let s = said(target_type::EVENT, ZERO, ZERO, basis::OWN, ZERO, 0, ground::INCOMPATIBLE, "The message promotes no paid service.", "Reviewed while held: an offer of lessons."); + let a5 = room.decide(&m, 11 * S, verdict::ALLOW, m5, 101, Some(&s)); + let n1 = notice( + room.id, + notice_type::NOTICE, + target_type::EVENT, + m5, + 40 * S, + ground::ILLEGAL, + "Regulation (EU) 2016/679, Article 6(1)", + "The message publishes the private phone number of someone who is not in the room, without their consent.", + "notifier@example.org", + &key(SUBMITTER), + ); + let s = said( + target_type::EVENT, + ZERO, + a5, + basis::NOTICE, + n1.digest(), + 0, + ground::ILLEGAL, + "The message discloses a private phone number of a person outside the room, with no ground for processing it.", + "A notice received at 40 s named the message; a reviewer confirmed the number is a private one and disabled access at 45 s.", + ); + room.decide(&m, 45 * S, verdict::DENY, m5, 201, Some(&s)); + let m6 = room.emit(&key(VIEWER_A), 50 * S, &chat("the whole concert recording is up at files.example/concert")); + let s = said(target_type::EVENT, ZERO, ZERO, basis::FALLBACK, ZERO, 0b100, ground::INCOMPATIBLE, FALLBACK_M3, "Held for review at 50 s of the session; no decision by 55 s."); + let f6 = room.decide(&key(CLOCK), 55 * S, verdict::DENY, m6, 900, Some(&s)); + let n2 = notice( + room.id, + notice_type::NOTICE, + target_type::EVENT, + m6, + 60 * S, + ground::ILLEGAL, + "Directive 2001/29/EC, Article 3(1)", + "The link offers a full recording of a commercial concert without the rightholders' authorisation.", + "rights-desk@flagger.example", + &key(FLAGGER), + ); + let s = said( + target_type::EVENT, + ZERO, + f6, + basis::NOTICE, + n2.digest(), + 0, + ground::ILLEGAL, + "The message links a recording communicated to the public without authorisation.", + "A trusted flagger's notice received at 60 s named the message; a reviewer opened the link and removed the message at 62 s.", + ); + room.decide(&m, 62 * S, verdict::REDACT, m6, 301, Some(&s)); + out.push(vector( + "notice_and_decision", + "an allowed message, then a notice that it is illegal and the decision that answers it; and a trusted flagger's notice on a message the fallback denied, answered by a redaction", + room, + vec![p1.to_bytes()], + vec![n1.to_bytes(), n2.to_bytes()], + vec![], + Intent::Accept, + )); + } + // An appeal that reverses a decision. + { + let mut room = chat_room(); + let p1 = chat_policy(room.id, ZERO, 0, vec![CHAT_ENTRY]); + let m = key(MODERATOR); + room.emit(&key(HOST), 2 * S, &chat("the band will tell you about their shirts later")); + let m7 = room.emit(&key(VIEWER_A), 10 * S, &chat("giveaway: pick up a free shirt at shop.example")); + let s = said( + target_type::EVENT, + ZERO, + ZERO, + basis::OWN, + ZERO, + 0b011, + ground::INCOMPATIBLE, + DENY_M2, + "A classifier matched the message to a promotion pattern and proposed denial; a reviewer confirmed it at 10.4 s.", + ); + let d7 = room.decide(&m, 10 * S + 400 * MS, verdict::DENY, m7, 101, Some(&s)); + let c1 = notice( + room.id, + notice_type::COMPLAINT, + target_type::EVENT, + d7, + 30 * S, + 0, + "", + "The shirts are the band's own, and the host invited the band to mention them during the session.", + "", + &key(VIEWER_A), + ); + let s = said( + target_type::EVENT, + ZERO, + d7, + basis::COMPLAINT, + c1.digest(), + 0, + ground::INCOMPATIBLE, + "On review the mention was invited by the host, so it is not unsolicited promotion under clause 4.2.", + "The complaint pointed to the host's invitation at 2 s of the session; the reviewer read the session's chat, confirmed it, and allowed the message at 40 s.", + ); + room.decide(&m, 40 * S, verdict::ALLOW, m7, 101, Some(&s)); + out.push(vector( + "appeal_reverses", + "a message denied with automated means, a complaint from its author, and the decision on the complaint that allows it", + room, + vec![p1.to_bytes()], + vec![c1.to_bytes()], + vec![], + Intent::Accept, + )); + } + out.extend(refused_vectors()); + out +} + +/// A refused vector over the base room: its name, what it is about, the defect written into +/// the room, and the reason it is refused with. +type Defect = (&'static str, &'static str, Box, Reason); + +/// One refused vector for each reason a room's moderation raises, each a control of one +/// defect over the base room. +fn refused_vectors() -> Vec { + let mut out = Vec::new(); + let refuse = |place, r| Intent::Refuse(place, r); + let m = key(MODERATOR); + let at = 12 * S + 500 * MS; + // A decision by a principal without the moderate power: the room refuses it. + { + let mut b = base(); + b.room.decide(&key(VIEWER_B), at, verdict::DENY, b.m2, 101, None); + out.push(vector("not_moderator", "a viewer, without the moderate power, sends a decision: the room refuses it", b.room, vec![b.p1.to_bytes()], vec![], vec![], refuse("room", Reason::Room(room::Reason::Events(events::Reason::KindNotPermitted))))); + } + // The policies. + { + let b = base(); + let p = ReviewPolicy { entries: vec![Entry { fallback: 4, ..CHAT_ENTRY }], ..b.p1.clone() }.sign(&key(AUTHORITY)); + out.push(vector("policy_malformed", "a policy entry whose fallback is none of allow, deny and hold", b.room, vec![p.to_bytes()], vec![], vec![], refuse("policy", Reason::PolicyMalformed))); + } + { + let b = base(); + let p2 = chat_policy(b.room.id, ZERO, 20 * S, vec![CHAT_ENTRY]); + out.push(vector("policy_unlinked", "a second policy that does not name the first", b.room, vec![b.p1.to_bytes(), p2.to_bytes()], vec![], vec![], refuse("policy", Reason::PolicyUnlinked))); + } + { + let b = base(); + let p = chat_policy(b.room.id, ZERO, 0, vec![Entry { deadline_ms: 4_000, ..CHAT_ENTRY }]); + out.push(vector("policy_conflicts_room", "a policy that reviews chat with another deadline than the room descriptor's", b.room, vec![p.to_bytes()], vec![], vec![], refuse("policy", Reason::PolicyConflictsRoom))); + } + { + let b = base(); + let mut p = b.p1.to_bytes(); + let n = p.len(); + p[n - 10] ^= 1; + out.push(vector("policy_bad_signature", "a policy whose signature does not verify", b.room, vec![p], vec![], vec![], refuse("policy", Reason::Room(room::Reason::Events(events::Reason::BadSignature))))); + } + { + let b = base(); + let p = chat_policy(nothing("another room"), ZERO, 0, vec![CHAT_ENTRY]); + out.push(vector("policy_wrong_room", "a policy of another room", b.room, vec![p.to_bytes()], vec![], vec![], refuse("policy", Reason::Room(room::Reason::Events(events::Reason::WrongRoom))))); + } + // The notices. + { + let b = base(); + let n = Notice { ntype: 3, ..notice(b.room.id, 1, 1, b.m2, 20 * S, ground::ILLEGAL, "", "spam", "", &key(SUBMITTER)) }.sign(&key(SUBMITTER)); + out.push(vector("notice_malformed", "a notice of a type this revision does not define", b.room, vec![b.p1.to_bytes()], vec![n.to_bytes()], vec![], refuse("notice", Reason::NoticeMalformed))); + } + { + let b = base(); + let mut n = notice(b.room.id, 1, 1, b.m2, 20 * S, ground::INCOMPATIBLE, "", "This is advertising.", "", &key(SUBMITTER)).to_bytes(); + let len = n.len(); + n[len - 1] ^= 0x40; + out.push(vector("notice_bad_signature", "a notice whose signature does not verify", b.room, vec![b.p1.to_bytes()], vec![n], vec![], refuse("notice", Reason::Room(room::Reason::Events(events::Reason::BadSignature))))); + } + // The statements. + { + let mut b = base(); + b.room.emit(&m, at, &chat("noted")); + let s = deny_m2_statement(&b); + b.room.raw(&m, at, kind::META, s.encode()); + out.push(vector("statement_misplaced", "a statement that follows a chat message, not a decision", b.room, vec![b.p1.to_bytes()], vec![], vec![], refuse("record", Reason::StatementMisplaced))); + } + { + let mut b = base(); + b.room.emit(&m, at, &Payload::Decision { verdict: verdict::DENY, target: b.m2, reason: 101 }); + let mut s = deny_m2_statement(&b).encode(); + s[70] = 5; + b.room.raw(&m, at, kind::META, s); + out.push(vector("statement_malformed", "a statement whose basis is none this revision defines", b.room, vec![b.p1.to_bytes()], vec![], vec![], refuse("record", Reason::StatementMalformed))); + } + // The decisions. + let decision_vectors: Vec = vec![ + ( + "reason_not_in_policy", + "a decision whose reason code the policy's vocabulary does not hold", + Box::new(|b: &mut Base| { + let s = deny_m2_statement(b); + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 555, Some(&s)); + }), + Reason::ReasonNotInPolicy, + ), + ( + "target_unknown", + "a decision on a digest that names no event of the room, which the verifier holds whole", + Box::new(|b: &mut Base| { + let s = Statement { target_prev: ZERO, ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, nothing("an event"), 101, Some(&s)); + }), + Reason::TargetUnknown, + ), + ( + "target_not_decidable", + "a decision on the clock's join of a viewer", + Box::new(|b: &mut Base| { + let join = b.room.joins[&VIEWER_A]; + let s = Statement { target_prev: b.room.prev_of(&join), ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, join, 101, Some(&s)); + }), + Reason::TargetNotDecidable, + ), + ( + "target_prev_mismatch", + "a statement whose target_prev is not its target's prev", + Box::new(|b: &mut Base| { + let s = Statement { target_prev: ZERO, ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s)); + }), + Reason::TargetPrevMismatch, + ), + ( + "not_reviewer", + "the host, with the moderate power but not among the policy's reviewers, denies a held message", + Box::new(|b: &mut Base| { + let s = deny_m2_statement(b); + b.room.decide(&key(HOST), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s)); + }), + Reason::NotReviewer, + ), + ( + "supersede_gap", + "a second decision on a message that supersedes nothing while the first stands", + Box::new(|b: &mut Base| { + allow_m1(b); + let s = said(target_type::EVENT, ZERO, ZERO, basis::OWN, ZERO, 0, ground::INCOMPATIBLE, DENY_M2, FACTS_M2); + b.room.decide(&key(MODERATOR), 13 * S, verdict::DENY, b.m1, 101, Some(&s)); + }), + Reason::SupersedeGap, + ), + ( + "supersede_unknown", + "a decision that supersedes a digest naming no decision of the room", + Box::new(|b: &mut Base| { + let s = Statement { supersedes: nothing("a decision"), ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s)); + }), + Reason::SupersedeUnknown, + ), + ( + "supersede_mismatch", + "a decision on one message that supersedes the decision on another", + Box::new(|b: &mut Base| { + let a1 = allow_m1(b); + let s = Statement { supersedes: a1, ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s)); + }), + Reason::SupersedeMismatch, + ), + ( + "notice_unknown", + "a decision answering a notice the verifier is not given", + Box::new(|b: &mut Base| { + let s = Statement { basis: basis::NOTICE, notice: nothing("a notice"), ..deny_m2_statement(b) }; + b.room.decide(&key(MODERATOR), 12 * S + 500 * MS, verdict::DENY, b.m2, 101, Some(&s)); + }), + Reason::NoticeUnknown, + ), + ( + "fallback_not_in_policy", + "the clock signs a fallback that allows a message the policy's fallback denies", + Box::new(|b: &mut Base| { + let s = fallback_m3_statement(b); + b.room.decide(&key(CLOCK), 17 * S, verdict::ALLOW, b.m3, 900, Some(&s)); + }), + Reason::FallbackNotInPolicy, + ), + ( + "fallback_early", + "the clock signs a fallback two seconds before the message's deadline", + Box::new(|b: &mut Base| { + let s = fallback_m3_statement(b); + b.room.decide(&key(CLOCK), 15 * S, verdict::DENY, b.m3, 900, Some(&s)); + }), + Reason::FallbackEarly, + ), + ]; + for (name, about, f, r) in decision_vectors { + let mut b = base(); + f(&mut b); + out.push(vector(name, about, b.room, vec![b.p1.to_bytes()], vec![], vec![], refuse("record", r))); + } + { + let mut b = base(); + let n = notice(b.room.id, notice_type::NOTICE, target_type::EVENT, b.m1, 11 * S, ground::INCOMPATIBLE, "", "This is advertising.", "", &key(SUBMITTER)); + let s = Statement { basis: basis::NOTICE, notice: n.digest(), ..deny_m2_statement(&b) }; + b.room.decide(&m, at, verdict::DENY, b.m2, 101, Some(&s)); + out.push(vector("notice_mismatch", "a decision on one message answering a notice about another", b.room, vec![b.p1.to_bytes()], vec![n.to_bytes()], vec![], refuse("record", Reason::NoticeMismatch))); + } + // An export that cannot be written. + { + let mut b = base(); + let s = Statement { facts: String::new(), ..deny_m2_statement(&b) }; + b.room.decide(&m, at, verdict::DENY, b.m2, 101, Some(&s)); + out.push(vector("sor_incomplete", "a denial whose statement states no facts: the room accepts it, and its export cannot be written", b.room, vec![b.p1.to_bytes()], vec![], vec![], Intent::Incomplete("decision_facts"))); + } + out +} + +// ---- the recorded take ---- + +const REDACT_EXPLANATION: &str = "The segment plays a recording protected by copyright, which the room holds no licence to communicate to the public."; +const REDACT_FACTS: &str = "An audio match flagged a commercial recording playing behind the performer during chunk 3 of the take; the director listened to it and removed the chunk at 20 s."; + +/// The lesson session as a room, with its chains as live-recording gives a room verifier them +/// (in the order of their files' paths), and the director's decisions added. +fn lesson_room(w: &Written) -> Room { + let files = &w.files; + let mut grants = Vec::new(); + for k in 0.. { + match files.get(&format!("room/grant-{k:04}.wrg")) { + Some(g) => grants.push(g.clone()), + None => break, + } + } + let head = files.get("room/key-log.json").map(|b| String::from_utf8(b.clone()).expect("a JSON key log")); + let mut authors = Vec::new(); + for (path, body) in files.range("events/".to_string()..) { + let Some(name) = path.strip_prefix("events/").and_then(|n| n.strip_suffix(".wev")) else { break }; + let records = split_chain(body).expect("a chain file"); + let last = Event::parse(records.last().expect("a chain with a record")).expect("a corpus record"); + authors.push(Author { pk: d32(name).expect("a key's hex"), seq: last.seq + 1, prev: last.digest(), records }); + } + Room { descriptor: w.descriptor.clone(), id: w.room, grants, head, authors, joins: BTreeMap::new() } +} + +/// The performer's take's chunks as objects under moderation: each its leaf, video, and the +/// `t` of the commitment that adds it (§7.1). +fn take_objects(w: &Written) -> Vec { + let t = &w.takes[0]; + t.chunks + .iter() + .map(|c| { + let k = t.payloads.iter().position(|p| p.first <= c.index && c.index < p.size).expect("a committed chunk"); + Object { digest: c.leaf(), media: media::VIDEO, t: Event::parse(&t.commits[k]).expect("a commitment").t } + }) + .collect() +} + +fn lesson_policy(room: [u8; 32]) -> ReviewPolicy { + ReviewPolicy { + room, + prev: ZERO, + effective: 0, + reviewers: vec![], + flaggers: vec![], + entries: vec![Entry { scope: scope::MEDIA, code: media::VIDEO, mode: mode::POST, deadline_ms: 60_000, fallback: fallback::ALLOW, fallback_reason: 0 }], + reasons: vec![ReasonCode { code: 301, ground: ground::ILLEGAL, category: 7, reference: "Directive 2001/29/EC, Article 3(1)".into(), url: String::new() }], + territory: vec![*b"AT", *b"DE", *b"FR"], + redress: REDRESS.into(), + sig: [0; 64], + } + .sign(&ct::key(ct::AUTHORITY)) +} + +/// The chunk the director redacts. +const REDACTED: usize = 3; + +/// The redacted room and, with `reversed`, the same room after the performer's complaint and +/// the director's decision on it. +fn recorded(w: &Written, reversed: bool) -> (Room, Vec>, Vec) { + let mut room = lesson_room(w); + let director = ct::key(ct::DIRECTOR); + let leaf = w.takes[0].chunks[REDACTED].leaf(); + let s = said(target_type::OBJECT, ZERO, ZERO, basis::OWN, ZERO, 0b001, ground::ILLEGAL, REDACT_EXPLANATION, REDACT_FACTS); + let r = room.decide(&director, 20 * S, verdict::REDACT, leaf, 301, Some(&s)); + let mut notices = Vec::new(); + if reversed { + let c = notice( + room.id, + notice_type::COMPLAINT, + target_type::EVENT, + r, + 30 * S, + 0, + "", + "The recording in the background is a practice track licensed to the performer for lessons and their recordings.", + "", + &ct::key(ct::PERFORMER), + ); + let s = said( + target_type::OBJECT, + ZERO, + r, + basis::COMPLAINT, + c.digest(), + 0, + ground::ILLEGAL, + "The licence covers communicating the track to the public in the performer's lessons, so the segment infringes nothing.", + "The complaint gave the licence; the director checked its terms and restored the chunk at 40 s.", + ); + room.decide(&director, 40 * S, verdict::ALLOW, leaf, 301, Some(&s)); + notices.push(c.to_bytes()); + } + (room, notices, take_objects(w)) +} + +fn recorded_vectors(w: &Written) -> Vec { + let p = vec![lesson_policy(w.room).to_bytes()]; + let (room, notices, objects) = recorded(w, false); + let (room2, notices2, objects2) = recorded(w, true); + vec![ + vector( + "redacted_segment", + "live-recording's lesson session, its video reviewed after delivery: the director redacts chunk 3 of the performer's take", + room, + p.clone(), + notices, + objects, + Intent::Accept, + ), + vector("redaction_reversed", "the same room after the performer's complaint and the director's decision restoring the chunk", room2, p, notices2, objects2, Intent::Accept), + ] +} + +// ---- clips ---- + +struct ClipVector { + name: &'static str, + about: &'static str, + /// The room vector whose standing restrictions apply. + room: &'static str, + descriptor: Vec, + record: Vec, + device: [u8; 32], + commits: Vec>, + bytes: Vec>>, + intent: Intent, +} + +fn clip_vectors(w: &Written) -> Vec { + let t = &w.takes[0]; + let n = t.commits.len() - 1; + let src = TakeSource { device: ct::pk(t.device), take: t.take, chunks: &t.chunks, head: Event::parse(&t.commits[n]).expect("a commitment").digest(), head_commit: &t.payloads[n], offset: t.offset }; + let cutter = ct::key(ct::AUTHORITY); + let clip = |first: u64, count: usize, trim_in: u64, trim_out: u64| { + let p = cut_part(&src, first, count, trim_in, trim_out).expect("a range within the head"); + let (a, z) = mapped_span(&p.chunks, t.offset); + cut_clip(w.room, a as u64, z as u64, vec![p], &cutter).to_bytes() + }; + let bytes = |first: usize, count: usize, absent: Option| -> Vec>> { + (first..first + count).map(|i| (Some(i) != absent).then(|| t.bytes[i].clone())).collect() + }; + let whole = clip(2, 4, 0, 0); + let at = |i: usize| t.chunks[..i].iter().map(|c| c.len).sum::(); + let (first, count, trim_in, trim_out) = resolve_bytes(&t.chunks, at(REDACTED) + 10, at(6) - 20).expect("a byte range of the master"); + let trimmed = clip(first, count, trim_in, trim_out); + let cv = |name, about, room, record: &Vec, bytes, intent| ClipVector { + name, + about, + room, + descriptor: w.descriptor.clone(), + record: record.clone(), + device: ct::pk(t.device), + commits: t.commits[..=n].to_vec(), + bytes, + intent, + }; + vec![ + cv("clip_withheld", "chunks 2 to 5 of the performer's take, the redacted chunk 3 withheld: the range proof verifies over all four", "redacted_segment", &whole, bytes(2, 4, Some(REDACTED)), Intent::Accept), + cv( + "clip_trimmed_withheld", + "a byte range from inside the redacted chunk 3 to inside chunk 5: the trim at the withheld chunk is not applied", + "redacted_segment", + &trimmed, + bytes(first as usize, count, Some(REDACTED)), + Intent::Accept, + ), + cv("clip_redaction_not_applied", "the same chunks with the redacted chunk's bytes given", "redacted_segment", &whole, bytes(2, 4, None), Intent::Refuse("chunk", Reason::RedactionNotApplied)), + cv( + "clip_restored_missing", + "after the appeal restores chunk 3, a clip that still leaves it out", + "redaction_reversed", + &whole, + bytes(2, 4, Some(REDACTED)), + Intent::Refuse("chunk", Reason::Record(record::Reason::ClipChunkMissing)), + ), + cv("clip_restored_whole", "after the appeal, the clip with every chunk's bytes", "redaction_reversed", &whole, bytes(2, 4, None), Intent::Accept), + ] +} + +// ---- JSON ---- + +fn opt_hex(d: &[u8; 32]) -> Value { + if *d == ZERO { + Value::Null + } else { + json!(hex(d)) + } +} + +fn verdict_name(v: u8) -> &'static str { + match v { + verdict::ALLOW => "allow", + verdict::DENY => "deny", + _ => "redact", + } +} + +fn place_json(at: &At) -> Value { + match at { + At::Room(room::At::Descriptor) => json!(["room", "descriptor"]), + At::Room(room::At::KeyLog) => json!(["room", "key_log"]), + At::Room(room::At::Grant(i)) => json!(["room", "grant", i]), + At::Room(room::At::Record { chain, record }) => json!(["room", "record", chain, record]), + At::Policy(i) => json!(["policy", i]), + At::Notice(i) => json!(["notice", i]), + At::Record { chain, record } => json!(["record", chain, record]), + } +} + +fn clip_place_json(p: &ClipPlace) -> Value { + match p { + ClipPlace::Descriptor => json!(["descriptor"]), + ClipPlace::Clip => json!(["clip"]), + ClipPlace::Part(k) => json!(["part", k]), + ClipPlace::Commit { part, index } => json!(["commit", part, index]), + ClipPlace::Chunk { part, index } => json!(["chunk", part, index]), + } +} + +fn gap_json(g: &events::Gap) -> Value { + json!({"principal": hex(&g.principal), "first": g.first, "last": g.last}) +} + +fn entry_json(e: &Option) -> Value { + match e { + None => Value::Null, + Some(e) => json!({ + "mode": if e.mode == mode::PRE { "pre" } else { "post" }, + "deadline_ms": e.deadline_ms, + "fallback": (["", "allow", "deny", "hold"][e.fallback as usize]), + }), + } +} + +/// The name of an export file: the vector's name and the decision's position (§11). +pub fn export_file(vector: &str, k: usize) -> String { + format!("{vector}.d{k}.sor.json") +} + +/// The outcome of a room vector, as the corpus states it. +fn run_json(name: &str, run: &Run) -> Map { + let mut o = Map::new(); + let gaps = match &run.outcome { + Outcome::Refuse { at, reason } => { + o.insert("outcome".into(), json!("refuse")); + o.insert("reason".into(), json!(reason.code())); + o.insert("at".into(), place_json(at)); + return o; + } + Outcome::Gap(g) => { + o.insert("outcome".into(), json!("gap")); + g.clone() + } + Outcome::Accept => { + o.insert("outcome".into(), json!("accept")); + vec![] + } + }; + o.insert("room_outcome".into(), json!(if matches!(run.room_outcome, Some(room::RoomOutcome::Gap(_))) { "gap" } else { "accept" })); + o.insert("gaps".into(), Value::Array(gaps.iter().map(gap_json).collect())); + o.insert( + "explained".into(), + Value::Array( + run.explained + .iter() + .map(|e| json!({"principal": hex(&e.principal), "first": e.first, "last": e.last, "decisions": e.decisions.iter().map(|d| hex(d)).collect::>()})) + .collect(), + ), + ); + o.insert( + "decisions".into(), + Value::Array( + run.decisions + .iter() + .map(|x| { + json!({ + "digest": hex(&x.digest), + "decider": hex(&x.decider), + "t": x.t, + "target": hex(&x.target), + "target_type": if x.target_type == target_type::EVENT { "event" } else { "object" }, + "verdict": verdict_name(x.verdict), + "reason": x.reason, + "statement": match x.statement { Said::Known(_) => "known", Said::None => "none", Said::Unknown => "unknown" }, + "basis": if x.statement == Said::Unknown { Value::Null } else { json!(["", "own", "notice", "complaint", "fallback"][x.basis() as usize]) }, + "supersedes": opt_hex(&x.supersedes()), + "notice": opt_hex(&x.notice()), + "standing": x.standing, + }) + }) + .collect(), + ), + ); + o.insert( + "items".into(), + Value::Array( + run.items + .iter() + .map(|i| { + let (tt, what) = if i.target_type == target_type::EVENT { + ("event", events::kind_name(i.code).expect("a kind")) + } else { + ("object", room::media_name(i.code).expect("a media kind")) + }; + json!({ + "digest": hex(&i.digest), + "target_type": tt, + "kind": what, + "t": i.t, + "entry": entry_json(&i.entry), + "timeline": i.timeline.iter().map(|(t, s, d)| json!({"t": t, "state": s.name(), "decision": d.map(|d| hex(&d)), "visible": s.visible()})).collect::>(), + }) + }) + .collect(), + ), + ); + o.insert( + "exports".into(), + Value::Array( + run.exports + .iter() + .enumerate() + .map(|(k, e)| { + let d = hex(&run.decisions[k].digest); + match e { + Export::None => json!({"decision": d, "file": null}), + Export::Record(_) => json!({"decision": d, "file": export_file(name, k)}), + Export::Incomplete(m) => json!({"decision": d, "file": null, "refuse": "sor_incomplete", "member": m}), + } + }) + .collect(), + ), + ); + o +} + +fn clip_json(out: &ClipRun) -> Map { + let mut o = Map::new(); + match out { + ClipRun::Refuse { at, reason } => { + o.insert("outcome".into(), json!("refuse")); + o.insert("reason".into(), json!(reason.code())); + o.insert("at".into(), clip_place_json(at)); + } + ClipRun::Accept { facts: f, withheld } => { + o.insert("outcome".into(), json!("accept")); + o.insert("clip".into(), json!(hex(&f.digest))); + o.insert("signer".into(), json!(hex(&f.signer))); + o.insert("window".into(), json!([f.window.0, f.window.1])); + o.insert("bound_us".into(), json!(f.bound_us)); + let parts: Vec = f + .parts + .iter() + .zip(withheld) + .map(|(p, w)| { + json!({ + "take": hex(&p.take), + "first": p.first, + "count": p.count, + "offset": p.offset, + "span": [p.span.0 as i64, p.span.1 as i64], + "device_window": [p.device_window.0 as i64, p.device_window.1 as i64], + "bytes": p.bytes, + "sha256": hex(&p.sha256), + "withheld": w.iter().map(|(i, d)| json!({"index": i, "decision": hex(d)})).collect::>(), + }) + }) + .collect(); + o.insert("facts".into(), Value::Array(parts)); + } + } + o +} + +fn reached(intent: Intent, run: &Run) -> bool { + match (intent, &run.outcome) { + (Intent::Accept, Outcome::Accept) => true, + (Intent::Incomplete(m), Outcome::Accept) => run.exports.contains(&Export::Incomplete(m)), + (Intent::Gap, Outcome::Gap(_)) => true, + (Intent::Refuse(k, r), Outcome::Refuse { at, reason }) => place_json(at)[0] == k && *reason == r, + _ => false, + } +} + +fn clip_reached(intent: Intent, out: &ClipRun) -> bool { + match (intent, out) { + (Intent::Accept, ClipRun::Accept { .. }) => true, + (Intent::Refuse(k, r), ClipRun::Refuse { at, reason }) => clip_place_json(at)[0] == k && *reason == r, + _ => false, + } +} + +fn hexes(v: &[Vec]) -> Vec { + v.iter().map(|b| hex(b)).collect() +} + +fn vector_json(v: &Vector, run: &Run) -> Value { + let chains: Vec> = v.room.chains().iter().map(|c| hexes(c)).collect(); + 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.room.descriptor))); + o.insert("grants".into(), json!(hexes(&v.room.grants))); + o.insert("key_log".into(), json!(v.room.head)); + o.insert("chains".into(), json!(chains)); + o.insert("policies".into(), json!(hexes(&v.policies))); + o.insert("notices".into(), json!(hexes(&v.notices))); + o.insert("objects".into(), Value::Array(v.objects.iter().map(|x| json!({"digest": hex(&x.digest), "media": x.media, "t": x.t})).collect())); + o.extend(run_json(v.name, run)); + Value::Object(o) +} + +fn clip_vector_json(v: &ClipVector, out: &ClipRun) -> Value { + let mut o = Map::new(); + o.insert("name".into(), json!(v.name)); + o.insert("about".into(), json!(v.about)); + o.insert("room".into(), json!(v.room)); + o.insert("descriptor".into(), json!(hex(&v.descriptor))); + o.insert("record".into(), json!(hex(&v.record))); + o.insert( + "parts".into(), + json!([{"device": hex(&v.device), "commits": hexes(&v.commits), "bytes": v.bytes.iter().map(|b| b.as_ref().map(|b| hex(b))).collect::>()}]), + ); + o.extend(clip_json(out)); + Value::Object(o) +} + +/// Every room vector with its run, and every clip with its outcome. +type Built = (Vec<(Vector, Run)>, Vec<(ClipVector, ClipRun)>); + +/// Every vector of the corpus, its run, and its clips' outcomes; asserting each reaches its +/// intent. +fn build() -> Built { + let w = lesson_written(); + let mut rooms = Vec::new(); + for v in chat_vectors().into_iter().chain(recorded_vectors(&w)) { + let chains = v.room.chains(); + let run = super::verify(&v.input(&chains)); + assert!(reached(v.intent, &run), "vector {} does not reach {:?}: {:?}", v.name, v.intent, run.outcome); + rooms.push((v, run)); + } + let mut clips = Vec::new(); + for c in clip_vectors(&w) { + let (_, run) = rooms.iter().find(|(v, _)| v.name == c.room).expect("the clip's room"); + let parts = [PartInputs { device: c.device, commits: &c.commits, bytes: &c.bytes }]; + let out = super::verify_clip(&c.descriptor, &c.record, &parts, &run.restricted_objects()); + assert!(clip_reached(c.intent, &out), "clip {} does not reach {:?}: {:?}", c.name, c.intent, out); + clips.push((c, out)); + } + (rooms, clips) +} + +/// The reasons the corpus gives: every refusal, every export refused, every clip refused. +fn reasons_given(rooms: &[(Vector, Run)], clips: &[(ClipVector, ClipRun)]) -> BTreeSet<&'static str> { + let mut seen = BTreeSet::new(); + for (_, run) in rooms { + if let Outcome::Refuse { reason, .. } = run.outcome { + seen.insert(reason.code()); + } + if run.exports.iter().any(|e| matches!(e, Export::Incomplete(_))) { + seen.insert(Reason::SorIncomplete.code()); + } + } + for (_, out) in clips { + if let ClipRun::Refuse { reason, .. } = out { + seen.insert(reason.code()); + } + } + seen +} + +/// The corpus's files: `vectors.json` and each export (§11). +pub fn generate() -> Vec<(String, String)> { + let (rooms, clips) = build(); + let seen = reasons_given(&rooms, &clips); + for r in Reason::ALL { + assert!(seen.contains(r.code()), "no vector gives {}", r.code()); + } + let mut files = Vec::new(); + for (v, run) in &rooms { + for (k, e) in run.exports.iter().enumerate() { + if let Export::Record(b) = e { + files.push((export_file(v.name, k), String::from_utf8(b.clone()).expect("an export is UTF-8"))); + } + } + } + let names = |ps: &[(&str, u8)], f: &dyn Fn(u8) -> [u8; 32]| ps.iter().map(|(n, i)| (n.to_string(), json!(hex(&f(*i))))).collect::>(); + let doc = json!({ + "about": "extensions/live-moderation.md §11: rooms under review policies, their decisions and statements, notices and complaints, explained gaps, the items' timelines, each decision's statement-of-reasons export, and clips of a redacted take", + "categories": CATEGORIES, + "principals": names(&PRINCIPALS, &pk), + "lesson_principals": names(&LESSON_PRINCIPALS, &ct::pk), + "vectors": rooms.iter().map(|(v, run)| vector_json(v, run)).collect::>(), + "clips": clips.iter().map(|(c, out)| clip_vector_json(c, out)).collect::>(), + }); + let mut body = serde_json::to_string_pretty(&doc).expect("JSON"); + body.push('\n'); + files.push(("vectors.json".into(), body)); + files.sort(); + files +} + +/// The objects a vector states. +fn objects_of(v: &Value) -> Option> { + v["objects"] + .as_array()? + .iter() + .map(|o| Some(Object { digest: d32(o["digest"].as_str()?)?, media: o["media"].as_u64()? as u8, t: o["t"].as_u64()? })) + .collect() +} + +fn hex_list(v: &Value) -> Option>> { + v.as_array()?.iter().map(|h| unhex(h.as_str()?)).collect() +} + +/// Check a corpus's files against this module: every room, export and clip gets the outcome +/// and everything else it states. Returns the failures. +pub fn verify(files: &BTreeMap) -> Vec { + let mut fails = Vec::new(); + let Some(doc) = files.get("vectors.json").and_then(|s| serde_json::from_str::(s).ok()) else { + return vec!["vectors.json does not read".into()]; + }; + let mut runs: BTreeMap = BTreeMap::new(); + for v in doc["vectors"].as_array().into_iter().flatten() { + let name = v["name"].as_str().unwrap_or("?").to_string(); + let parsed = (|| { + let chains: Vec>> = v["chains"].as_array()?.iter().map(hex_list).collect::>()?; + Some((unhex(v["descriptor"].as_str()?)?, hex_list(&v["grants"])?, v["key_log"].as_str().map(String::from), chains, hex_list(&v["policies"])?, hex_list(&v["notices"])?, objects_of(v)?)) + })(); + let Some((descriptor, grants, head, chains, policies, notices, objects)) = parsed else { + fails.push(format!("vector {name}: its inputs do not read")); + continue; + }; + let run = super::verify(&Input { descriptor: &descriptor, grants: &grants, head: head.as_deref(), chains: &chains, policies: &policies, notices: ¬ices, objects: &objects }); + for (k, want) in run_json(&name, &run) { + if v.get(&k) != Some(&want) { + fails.push(format!("vector {name}: {k} is {}, the corpus states {}", want, v.get(&k).unwrap_or(&Value::Null))); + } + } + for (k, e) in run.exports.iter().enumerate() { + if let Export::Record(b) = e { + let f = export_file(&name, k); + if files.get(&f).map(String::as_bytes) != Some(b.as_slice()) { + fails.push(format!("vector {name}: the export {f} differs from the record")); + } + } + } + runs.insert(name, run); + } + for c in doc["clips"].as_array().into_iter().flatten() { + let name = c["name"].as_str().unwrap_or("?"); + let parsed = (|| { + let p = &c["parts"][0]; + let bytes: Vec>> = p["bytes"].as_array()?.iter().map(|b| if b.is_null() { Some(None) } else { unhex(b.as_str()?).map(Some) }).collect::>()?; + Some((c["room"].as_str()?.to_string(), unhex(c["descriptor"].as_str()?)?, unhex(c["record"].as_str()?)?, d32(p["device"].as_str()?)?, hex_list(&p["commits"])?, bytes)) + })(); + let Some((room_name, descriptor, rec, device, commits, bytes)) = parsed else { + fails.push(format!("clip {name}: its inputs do not read")); + continue; + }; + let Some(run) = runs.get(&room_name) else { + fails.push(format!("clip {name}: no room vector {room_name}")); + continue; + }; + let out = super::verify_clip(&descriptor, &rec, &[PartInputs { device, commits: &commits, bytes: &bytes }], &run.restricted_objects()); + for (k, want) in clip_json(&out) { + if c.get(&k) != Some(&want) { + fails.push(format!("clip {name}: {k} is {want}, the corpus states {}", c.get(&k).unwrap_or(&Value::Null))); + } + } + } + fails +} diff --git a/wai/wai-rs/src/live_record.rs b/wai/wai-rs/src/live_record.rs index 545168d45..3be7ef3d1 100644 --- a/wai/wai-rs/src/live_record.rs +++ b/wai/wai-rs/src/live_record.rs @@ -1173,6 +1173,9 @@ pub struct PartFacts { pub bytes: u64, pub sha256: [u8; 32], pub fetch: FetchRange, + /// The indexes of the chunks step (k) passed over as exempt (see [`verify_clip_exempting`]); + /// always empty under [`verify_clip`]. + pub exempt: Vec, } /// What a verified clip states (§5.4, §6.2). @@ -1212,7 +1215,8 @@ struct Held { } /// §5.4 step 3 for part `k`: the facts, or the refusal. -fn verify_part(k: usize, p: &ClipPart, i: &PartInputs, room_id: &[u8; 32], clip: &Clip, interval: i128, jitter: i128) -> Result { +#[allow(clippy::too_many_arguments)] +fn verify_part(k: usize, p: &ClipPart, i: &PartInputs, room_id: &[u8; 32], clip: &Clip, interval: i128, jitter: i128, exempt: &dyn Fn(&Chunk) -> bool) -> Result { let at_part = |r: Reason| (ClipPlace::Part(k), r); let at_commit = |j: usize, r: Reason| (ClipPlace::Commit { part: k, index: j }, r); // a. The device. @@ -1305,9 +1309,22 @@ fn verify_part(k: usize, p: &ClipPart, i: &PartInputs, room_id: &[u8; 32], clip: if !covers || (trimmed && (wi, wo) != (span_in, span_out)) { return Err(at_part(Reason::ClipWindowInvalid)); } - // k. The bytes. + // k. The bytes. A chunk the caller exempts is passed over: its bytes are neither required + // nor checked nor presented (live-moderation §8.3); none is exempt under `verify_clip`. let mut presented = Vec::new(); + let mut passed = Vec::new(); + let (mut trim_in, mut trim_out) = (p.trim_in as usize, p.trim_out as usize); for (j, c) in ch.iter().enumerate() { + if exempt(c) { + passed.push(c.index); + if j == 0 { + trim_in = 0; + } + if j == ch.len() - 1 { + trim_out = 0; + } + continue; + } let at = (ClipPlace::Chunk { part: k, index: j }, Reason::ClipChunkMissing); let b = i.bytes.get(j).and_then(Option::as_ref).ok_or(at)?; if !c.is(b) { @@ -1319,7 +1336,7 @@ fn verify_part(k: usize, p: &ClipPart, i: &PartInputs, room_id: &[u8; 32], clip: if i.bytes.len() > ch.len() { return Err((ClipPlace::Chunk { part: k, index: ch.len() }, take::Reason::ChunkExtra.into())); } - let shown = &presented[p.trim_in as usize..presented.len() - p.trim_out as usize]; + let shown = &presented[trim_in..presented.len() - trim_out]; Ok(PartFacts { take: p.take, first: p.first, @@ -1330,12 +1347,21 @@ fn verify_part(k: usize, p: &ClipPart, i: &PartInputs, room_id: &[u8; 32], clip: bytes: shown.len() as u64, sha256: sha256(&[shown]), fetch: fetch_range(room_id, &p.device, &p.take, p.first, count), + exempt: passed, }) } /// Verify a clip (§5.4): the room descriptor, the clip record, and for each of its parts in /// order what [`PartInputs`] holds. pub fn verify_clip(descriptor: &[u8], record: &[u8], parts: &[PartInputs]) -> ClipOutcome { + verify_clip_exempting(descriptor, record, parts, &|_| false) +} + +/// [`verify_clip`] with step (k) passing over every chunk `exempt` names: its bytes are neither +/// required nor checked nor presented, and a trim at a chunk passed over is not applied. This +/// is the first change live-moderation §8.3 makes for a clip whose chunks a decision +/// restricts; the second, refusing bytes given for such a chunk, is that extension's. +pub fn verify_clip_exempting(descriptor: &[u8], record: &[u8], parts: &[PartInputs], exempt: &dyn Fn(&Chunk) -> bool) -> ClipOutcome { let refuse = |at, reason| ClipOutcome::Refuse { at, reason }; // 1. The descriptor. let d = match Descriptor::parse(descriptor) { @@ -1359,7 +1385,7 @@ pub fn verify_clip(descriptor: &[u8], record: &[u8], parts: &[PartInputs]) -> Cl let jitter = d.recording.jitter_ms as i128 * 1000; let mut facts = Vec::with_capacity(parts.len()); for (k, (p, i)) in clip.parts.iter().zip(parts).enumerate() { - match verify_part(k, p, i, &room_id, &clip, interval, jitter) { + match verify_part(k, p, i, &room_id, &clip, interval, jitter, exempt) { Ok(f) => facts.push(f), Err((at, r)) => return refuse(at, r), } diff --git a/wai/wai-rs/src/live_record/corpus.rs b/wai/wai-rs/src/live_record/corpus.rs index 50ec188ff..b9ec45733 100644 --- a/wai/wai-rs/src/live_record/corpus.rs +++ b/wai/wai-rs/src/live_record/corpus.rs @@ -214,26 +214,26 @@ impl Chains { /// A take as written: what a cutter holds of it. #[derive(Clone)] -struct WrittenTake { - device: u8, - take: [u8; 32], +pub(crate) struct WrittenTake { + pub(crate) device: u8, + pub(crate) take: [u8; 32], /// The chunks its manifest lists. - chunks: Vec, + pub(crate) chunks: Vec, /// The bytes of each chunk its manifest lists. - bytes: Vec>, + pub(crate) bytes: Vec>, /// Every commitment the device signed, in order, a dropped one included, and each /// one's payload. - commits: Vec>, - payloads: Vec, - offset: i64, + pub(crate) commits: Vec>, + pub(crate) payloads: Vec, + pub(crate) offset: i64, } /// A session written out: the package's files before it is sealed, and its takes. -struct Written { - descriptor: Vec, - room: [u8; 32], - files: BTreeMap>, - takes: Vec, +pub(crate) struct Written { + pub(crate) descriptor: Vec, + pub(crate) room: [u8; 32], + pub(crate) files: BTreeMap>, + pub(crate) takes: Vec, } fn write(s: &Scene) -> Written { @@ -495,6 +495,12 @@ fn lesson_session() -> Scene { scene(vec![performer_take("lesson"), accompanist_take()]) } +/// The lesson session as written: the room, its chains and both takes. The moderation corpus +/// (extensions/live-moderation.md §11) redacts a chunk of the performer's take and clips over it. +pub(crate) fn lesson_written() -> Written { + write(&lesson_session()) +} + /// Recompute `LISTING` after a file changed. fn relist(mut files: BTreeMap>) -> BTreeMap> { files.remove(LISTING); diff --git a/wai/wai-rs/tests/int_kernels_vectors.rs b/wai/wai-rs/tests/int_kernels_vectors.rs index d25b21aa4..edae21727 100644 --- a/wai/wai-rs/tests/int_kernels_vectors.rs +++ b/wai/wai-rs/tests/int_kernels_vectors.rs @@ -223,7 +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, takes, compositions, recordings, captions, metering and steering: signed records, commitments, packages, clips, cues and their renderings, per-hop records, ledgers and session receipts with their units and joules recomputed, steering policies and decisions with each pathway's evidence and the steering manifests recomputed byte for byte, and their verdicts, and layouts and mixes stated in full, rectangle for rectangle and sample for sample; nothing decoded against a parameter set"), + ("live-conformance", "live events, rooms, takes, compositions, recordings, captions, metering, steering and moderation: signed records, commitments, packages, clips, cues and their renderings, per-hop records, ledgers and session receipts with their units and joules recomputed, steering policies and decisions with each pathway's evidence and the steering manifests recomputed byte for byte, review policies, decisions, notices and the items' timelines with each statement-of-reasons export written byte for byte, and their verdicts, and layouts and mixes stated in full, rectangle for rectangle and sample for sample; nothing decoded against a parameter set"), ("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_moderation.rs b/wai/wai-rs/tests/live_moderation.rs new file mode 100644 index 000000000..984e08feb --- /dev/null +++ b/wai/wai-rs/tests/live_moderation.rs @@ -0,0 +1,53 @@ +//! `wai.live.moderation` (extensions/live-moderation.md): the committed corpus +//! `live-conformance/moderation/` regenerates byte for byte from its fixed seeds, holds no +//! other file, every case in it gets the outcome it states, and the extension's §10 lists +//! exactly the reasons the reference reports. The generator itself asserts that the corpus +//! gives every one of them. +#![cfg(feature = "live_moderation")] + +use std::collections::BTreeMap; +use std::path::PathBuf; +use wai::live_moderation::{corpus, Reason}; + +fn wai_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} + +fn committed() -> BTreeMap { + let dir = wai_dir().join("live-conformance/moderation"); + std::fs::read_dir(&dir) + .expect("the committed corpus") + .flatten() + .map(|e| (e.file_name().to_string_lossy().into_owned(), e.path())) + .filter(|(n, _)| n != "README.md") + .map(|(n, p)| (n, std::fs::read_to_string(p).expect("a text file"))) + .collect() +} + +#[test] +fn the_committed_corpus_regenerates_from_its_seeds() { + let files = committed(); + let generated: BTreeMap = corpus::generate().into_iter().collect(); + let extra: Vec<&String> = files.keys().filter(|k| !generated.contains_key(*k)).collect(); + let missing: Vec<&String> = generated.keys().filter(|k| !files.contains_key(*k)).collect(); + let differ: Vec<&String> = generated.iter().filter(|(k, v)| files.get(*k).is_some_and(|f| f != *v)).map(|(k, _)| k).collect(); + assert!(extra.is_empty() && missing.is_empty() && differ.is_empty(), "extra {extra:?}, missing {missing:?}, differ {differ:?}: run `wai_live_moderation_vectors gen`"); +} + +#[test] +fn every_case_gets_its_stated_outcome() { + let fails = corpus::verify(&committed()); + assert!(fails.is_empty(), "{}", fails.join("\n")); +} + +/// §10 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-moderation.md")).expect("the extension"); + let at = text.find("\n## 10. Reasons").expect("a §10"); + 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, "§10's table and Reason::ALL differ"); +}