116 lines
7.7 KiB
Markdown
116 lines
7.7 KiB
Markdown
# 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.
|