From 00bbc69536fa5d8489e93752601beab62ef20439 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Wed, 21 Oct 2026 12:13:31 -0400 Subject: [PATCH 1/4] wai.access.services: caption quality from the signed revisions, audio description, sign language and a completeness claim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The extension (extensions/access-services.md), the access_services module of wai-rs behind its own feature, and the corpus live-conformance/access/ written from fixed seeds by wai_access_services_vectors: three accepted sessions and a negative control for every reason of §10, and the DAPT document of each description. Co-Authored-By: Claude Opus 5.5 --- wai/extensions/access-services.md | 843 ++++++++++ wai/live-conformance/access/lesson.dapt.ttml | 13 + .../access/reviewed.dapt.ttml | 13 + wai/live-conformance/access/vectors.json | 1116 +++++++++++++ wai/wai-rs/Cargo.toml | 18 + wai/wai-rs/src/access_services.rs | 1483 +++++++++++++++++ wai/wai-rs/src/access_services/corpus.rs | 718 ++++++++ .../src/bin/wai_access_services_vectors.rs | 75 + wai/wai-rs/src/lib.rs | 8 + wai/wai-rs/tests/access_services.rs | 69 + 10 files changed, 4356 insertions(+) create mode 100644 wai/extensions/access-services.md create mode 100644 wai/live-conformance/access/lesson.dapt.ttml create mode 100644 wai/live-conformance/access/reviewed.dapt.ttml create mode 100644 wai/live-conformance/access/vectors.json create mode 100644 wai/wai-rs/src/access_services.rs create mode 100644 wai/wai-rs/src/access_services/corpus.rs create mode 100644 wai/wai-rs/src/bin/wai_access_services_vectors.rs create mode 100644 wai/wai-rs/tests/access_services.rs diff --git a/wai/extensions/access-services.md b/wai/extensions/access-services.md new file mode 100644 index 000000000..ebd137c48 --- /dev/null +++ b/wai/extensions/access-services.md @@ -0,0 +1,843 @@ +# WAI Extension: Access Services + +> Status: Draft. Registers the record `wai.access.services`: the access services of a room +> session, and figures about them that any verifier recomputes from signed records. Captions +> are [timed-text](timed-text.md)'s, unchanged. This extension adds a **quality figure** for a +> caption track: its **latency**, the room-clock instant a cue was first shown less the +> capture instant of the speech it carries; its **stability**, the revisions after first +> display and the words they changed; and its **accuracy**, the word errors of the first +> revision shown against a reviewed final revision or a signed reference transcript. Each is +> defined in integer arithmetic over the signed revisions, so two verifiers reach the same +> numbers, and a figure a vendor states is checked by recomputing it. **Audio description** is +> a signed description track, a script of timed descriptions with their mixing instructions +> (the programme audio ducked under each) and their voicing, a separate audio track or a voice +> the sink synthesizes, each labelled human or machine; it maps onto a document of the Dubbing +> and Audio description Profiles of TTML2. **Sign language** is a signing track, a +> `wai.avatar.pose` stream or the video of a person signing, whose objects are bound by digest +> to the caption revisions they translate, with a reviewer's optional sign-off. A +> **completeness claim** states, for a room session, that each access track it declares was +> delivered complete and in sync, measured from signed times against the tolerances the texts +> below state; a verifier checks it against the records. No new transport. The reference +> implementation is the `access_services` module of `wai-rs` (feature `access_services`); the +> corpus is [`live-conformance/access/`](../live-conformance/access/), and its second +> implementation is `live-conformance/access_services_verify.py`. +> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174. +> +> Texts read for this revision, each pinned to the version named: Directive (EU) 2019/882, +> Annex I, Section IV, point (b)(ii), and Article 31(2), from a reproduction of the text as +> adopted (the Official Journal could not be fetched for this revision); EN 301 549 V4.1.1 +> (2026-09), clauses 4.2.4, 6.5.2, 6.5.3, 7.1.2, 7.1.5, 7.2.1 to 7.2.3, 7.3, 12.4 and 12.5; +> Web Content Accessibility Guidelines (WCAG) 2.2, Success Criteria 1.2.2 to 1.2.7; 47 CFR +> 79.1(j)(2), (j)(3) and (k)(2), and 47 CFR 79.3(a)(3), as in force on 2026-10-01; Dubbing and +> Audio description Profiles of TTML2 (DAPT), W3C Candidate Recommendation Draft of +> 2026-06-26 (`CRD-dapt-20260626`), §4.1 to §4.10, §5.2, §5.3, §5.5 to §5.7 and Appendix +> H.2.2; EBU Tech 3370, EBU-TT Part 3, version 1.0 (May 2017), §2.3.2 and §2.3.3; and two +> statements of the United Kingdom's communications regulator, *Measuring the quality of live +> subtitling* (16 October 2013), §1.3, §3.65 to §3.67 and footnote 21, and *Ensuring the +> quality of TV and on-demand services* (15 April 2024), §3.3, §5.17, §5.23, §5.25, §5.29, +> §6.2 and §6.14. A section number of one of those texts in this extension is that version's, +> and is written with the text's name; a bare section number is this extension's. DAPT is a +> Candidate Recommendation Draft, whose features may change before it is a Recommendation, +> and one that §5.5 uses is at risk there. + +## 1. Scope + +In scope: the records and their encoding (§2); words, and the alignment of two lists of words +(§3); the quality figure of a caption track: the sources that place its words on the room +clock, a reference transcript, latency, stability, accuracy, and the figure record (§4); +audio description: the description record, its script, mixing and voicing, its +synchronisation, its DAPT document, and what a player owes its listeners (§5); sign language: +the signing record, its binding to caption revisions, and a review (§6); the completeness +claim (§7); verification (§8); and what each figure measures in the texts above (§9). + +Out of scope: a transport; recognising speech, writing descriptions, translating into a sign +language and synthesizing speech, which produce the content; grading the severity of an +error, which needs a person (§9); decoding a voicing track or a signing track, whose objects +this extension names by digest; spoken subtitles and extended audio description, which pause +or lengthen the programme; how a sink renders a description or a signer; and what any law +requires. + +Relationship to the core spec: `wai.access.services` 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 [timed-text](timed-text.md): captions are its live captions, verified as its +§4.3 verifies them, and this extension changes nothing in them. The audio description that +timed-text §1 leaves out of its scope is this extension's §5. + +Relationship to [avatars](avatars.md) and [capture-binding](capture-binding.md): a signing +track in pose form is a `wai.avatar.pose` world, whose op batches are its objects (avatars +§5); a source on a take is placed on the room clock by the take's clock mapping +(capture-binding §9.3). + +Duties this extension supports: the access services of Directive (EU) 2019/882, Annex I, +Section IV(b)(ii) ("subtitles for the deaf and hard of hearing, audio description, spoken +subtitles and sign language interpretation … fully transmitted with adequate quality for +accurate display, and synchronised with sound and video, while allowing for user control of +their display and use"); EN 301 549 V4.1.1 clauses 7.2.1 to 7.2.3, 7.3 and 12.4, beside the +caption clauses timed-text §11 answers; WCAG 2.2 Success Criteria 1.2.3, 1.2.5 and 1.2.6, +beside the caption criteria 1.2.2 and 1.2.4; and the caption quality standards of 47 CFR +79.1(j). WAI states what its records carry and what a verifier checks. It makes no statement +about any regime, and a deployment confirms what a regime asks of it against that regime's +text. + +## 2. Records + +Every record of this extension is a JSON object (RFC 8259), read as +[jwp-receipts](jwp-receipts.md) §3.1 step 1 reads a claim: RFC 8259's grammar, no byte-order +mark, no member named twice in one object, no `\u` escape that leaves a surrogate unpaired, +and at most 32 levels of nesting. Its values use the encodings of jwp-receipts §2.4.3: byte +strings in lowercase hexadecimal; integers unsigned, at most 2^53 − 1, in plain decimal; no +other number and no boolean. The types in this extension's tables are: + +- `hex32`, `hex64`: 64 or 128 lowercase hexadecimal digits; +- `int`: such an integer; +- `sint`: a **signed integer**, written as a JSON string: `0`, or an optional `-` then a + digit 1 to 9 then any digits, whose value lies in −2^63 to 2^63 − 1; +- `string`: a JSON string; `tag`: a string that live-events §4.10 reads as a language tag + (checked by the rules of the record's section); +- a list of quoted values: a string equal to one of them; +- `object`, `array`: as the table under it says; `null`, written where a member may be null. + +A record has exactly the members its table lists, at every level, none missing and none +added, each of its type, and a `kind` that names it. One that is not JSON, or does not have +that shape, is `record_malformed`. + +Every record carries `signer_pubkey` (`hex32`, the Ed25519 key of RFC 8032 that signs it) and +`sig` (`hex64`): + +``` +sig = Ed25519(signer_key, "wai:access\x01" || JCS(record without "sig")) +record id = SHA-256(JCS(record)) +``` + +JCS is RFC 8785, which on these values reduces to what jwp-receipts §2.4.3 states. The +signature is verified strictly ([SPEC](../SPEC.md) §7 *Signatures*): a key that fails step 1 +or 2 is `bad_key`, and a signature that fails a later step `bad_signature`. A record is named +by its record id wherever another names it. A member `room` names the room by its id +(live-events §2); a record whose `room` is not the verifier's room is `wrong_room`. + +Which signers a verifier trusts for each kind of record is its policy. This extension checks +what each record states against the events and the other records; a figure's weight comes +from its recomputation (§4.7), not from its signer. + +## 3. Words and their alignment + +### 3.1 Words + +The **words** of a text are found in two steps: + +1. The text is split at every U+0020 and U+000A, and empty pieces are dropped. +2. In each piece, every code point from U+0041 to U+005A is replaced by the one 0x20 above + it (ASCII letters to lower case), and code points of the set *P* are removed from its + start and its end, repeatedly, until it neither starts nor ends with one. A piece left + empty is dropped; the rest are the words, in order. + +*P* is U+0021 `!`, U+0022 `"`, U+0027 `'`, U+0028 `(`, U+0029 `)`, U+002C `,`, U+002D `-`, +U+002E `.`, U+003A `:`, U+003B `;`, U+003F `?`, U+005B `[`, U+005D `]`, U+00A1 `¡`, U+00AB +`«`, U+00BB `»`, U+00BF `¿`, U+2013 `–`, U+2014 `—`, U+2018 `‘`, U+2019 `’`, U+201C `“`, +U+201D `”` and U+2026 `…`. + +No other normalisation is made: letters outside ASCII keep their case, and two words are +equal when their code points are. The words so found ignore the case of ASCII letters and +the punctuation at a word's edges, so an error of capitalisation or of such punctuation is +not a word error here (§9). + +### 3.2 Alignment + +The alignment of a **hypothesis** *H* (words *h*₁ … *h*ₘ) to a **reference** *R* (words +*r*₁ … *r*ₙ) is the table *D* of integers, for 0 ≤ *i* ≤ *m* and 0 ≤ *j* ≤ *n*: + +- *D*[0][*j*] = *j*, and *D*[*i*][0] = *i*; +- *D*[*i*][*j*] = the least of *D*[*i* − 1][*j* − 1] + *c*, *D*[*i* − 1][*j*] + 1 and + *D*[*i*][*j* − 1] + 1, where *c* is 0 when *h*ᵢ = *r*ⱼ and 1 otherwise. + +Its **end** is a column *j*\*: + +- a **full** alignment ends at *j*\* = *n*; +- a **prefix** alignment ends at the greatest *j* for which *D*[*m*][*j*] is the least + value in row *m*: the reference is read as far as the hypothesis reaches, and no further. + +Its **errors** are *E* = *D*[*m*][*j*\*] and its **reference words** *N* = *j*\*. They are +split into substitutions, deletions and insertions by walking back from (*m*, *j*\*) to +(0, 0), taking at each step the first of these that holds: + +1. *i* > 0, *j* > 0 and *D*[*i*][*j*] = *D*[*i* − 1][*j* − 1] + *c*: to (*i* − 1, *j* − 1), + a **substitution** when *c* is 1; +2. *i* > 0 and *D*[*i*][*j*] = *D*[*i* − 1][*j*] + 1: to (*i* − 1, *j*), an **insertion** + (a hypothesis word the reference does not have); +3. otherwise: to (*i*, *j* − 1), a **deletion** (a reference word the hypothesis does not + have). + +The substitutions, deletions and insertions add up to *E*. + +## 4. Caption quality + +### 4.1 The caption track and its cues + +A **caption track** is the caption events of one principal *P* in a room's stream, verified +as [timed-text](timed-text.md) §4.3 verifies them. Its **cues** are the chains of its +revisions (timed-text §2): each from its first revision *r*₀ to its last *r*ₖ. A cue is named +by the digest of *r*₀'s `caption` event (live-events §3.2). + +*P*'s captions are **whole** when *P* has at least one cue, the verifier holds every `seq` of +*P* from 0 to the last it holds (no delivery gap of *P*, live-events §6.2), and, for every +cue, *r*ₖ is final and its annotation is not unknown (timed-text §4.3). They are +**resolved** when they are whole and every *r*ₖ has a `duration_ms` above 0, so that each cue +resolves (timed-text §4.5). A figure is computed only over whole captions. + +The **events digest** of *P* is SHA-256 over the digests of *P*'s `caption` events the +verifier holds, 32 bytes each, in `seq` order. + +### 4.2 Sources + +A **sources** record places the words of each cue on the room clock: where the speech the cue +carries was captured. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-caption-sources"` | | +| `room` | `hex32` | the room | +| `principal` | `hex32` | *P*, whose cues it places | +| `sources` | array | one entry per cue it places, each an object below | +| `signer_pubkey`, `sig` | | §2 | + +| member of an entry | type | meaning | +|---|---|---| +| `cue` | `hex32` | the cue, by the digest of its first revision | +| `basis` | `"take"`, `"room"` | what `start` and `end` are measured on | +| `take` | `hex32` or `null` | for `take`, the take id (capture-binding §3.2); `null` for `room` | +| `start`, `end` | `int` | the capture of the cue's first word and of its last: device-clock microseconds of the take, or room-clock microseconds | + +Its signer is whoever aligned the words to the media: the captioner, or anyone holding the +media afterwards. The alignment of a word to the media is the signer's statement; the +media's own time is not. On the basis `take`, the instants are positions in the master of a +take, and the take's clock mapping places them on the room clock: the offset *o* of the +take's opening commitment (capture-binding §9.3), which the capturing device signed while it +captured. A **source instant** *d* maps to the room-clock instant *d* + *o*. On the basis +`room`, the instants are on the room clock as stated. + +Rules, in order: + +1. `room` is the verifier's: otherwise `wrong_room`. +2. No sources record of *P* comes before it in the order given: otherwise + `record_conflict`. +3. Each entry: `take` is a `hex32` exactly when `basis` is `take`, and `start` ≤ `end`; + no cue is named twice: otherwise `record_malformed`. +4. *P*'s captions are whole (§4.1): otherwise `stream_incomplete`. +5. Each entry's `cue` names a cue of *P*'s captions: otherwise `source_unknown`. +6. Each entry on the basis `take`: among the events the verifier accepted there is a + `take_commit` event whose payload capture-binding §5.2 reads, whose `take` is the entry's + take, and which is an opening commitment (`n` 0, `phase` 1, capture-binding §5.3); the + first such in stream order is the take's opening commitment, its author *A* and its + offset *o*. The take is **derived**: an accepted `control` event whose command is + `record_start` and whose `target` is *A* has a digest *s* for which SHA-256 of + `wai:capture-take`, 0x01, the room id, *A* and *s* is the take (capture-binding §3.2). + And `start` + *o* is not below 0. Otherwise `source_take_unknown`. + +*P*'s **sources record** is the first sources record of *P* in the order given, and its +**reference record** the first reference record (§4.3); a later one of either is +`record_conflict`. Who may start a take, and which device captures for which principal, are +live-rooms' and capture-binding's checks; this extension uses the take's mapping as +capture-binding §9.3 defines it, and its bound, *J*, holds where a take verifier gives the +take `single-take` and `aligned` (capture-binding §9.4, §10). + +### 4.3 The reference transcript + +A **reference** record gives, for each cue of *P*, the text a reviewer holds correct. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-caption-reference"` | | +| `room` | `hex32` | the room | +| `principal` | `hex32` | *P* | +| `entries` | array | one per cue, each `{"cue": hex32, "text": string}` | +| `signer_pubkey`, `sig` | | §2 | + +Rules, in order: `room` is the verifier's (`wrong_room`); no reference record of *P* comes +before it in the order given (`record_conflict`); no cue is named twice (`record_malformed`); +each text meets timed-text §3.2 rules 1 to 3 (`text_not_in_subset`); *P*'s captions are whole +(`stream_incomplete`); each entry names a cue of *P* (`reference_unknown`); and every cue of +*P* has an entry (`reference_incomplete`). + +### 4.4 Latency + +The latency of a cue that a sources entry places is *L* = `t`(*r*₀) − *S*, in microseconds, +where `t`(*r*₀) is the room-clock instant its first revision was shown from (timed-text +§4.1) and *S* is its entry's `start` on the room clock (§4.2). *L* is negative when the +caption was shown before the speech began. + +Over the cues of *P* that the sources record places, *n* of them, with their latencies in +ascending order *L*₁ ≤ … ≤ *L*ₙ: + +- `min` = *L*₁, `max` = *L*ₙ; +- `mean` = ⌊(*L*₁ + … + *L*ₙ) / *n*⌋, rounded toward negative infinity; +- `p50` and `p95`: the latency at rank ⌈50 × *n* / 100⌉ and ⌈95 × *n* / 100⌉, counting + from 1. + +Each is `null` when *n* is 0. The **class** of the latency is `none` when *n* is 0; +otherwise `capture` when every entry is on the basis `take`, and `stated` when any is on the +basis `room`. + +### 4.5 Stability + +For one cue, its **revisions** are *k*, the revisions after the first, and its **words +changed** the sum, over each revision *r*ᵢ and the one that supersedes it *r*ᵢ₊₁, of the +substitutions and insertions of the full alignment of the words of *r*ᵢ (the hypothesis) to +the words of *r*ᵢ₊₁ (the reference): the words a viewer saw that the next revision did not +keep. A word added at the end, as a partial grows, is a deletion there and is not counted. + +The track's figures are the sums over its cues of revisions and of words changed, and +`cues_corrected`, the number of cues whose words changed is above 0. + +### 4.6 Accuracy + +The reference of a cue is its entry's text in *P*'s reference record, when *P* has one; +otherwise the text of *r*ₖ, the cue's final revision. The **class** of the accuracy is: + +- `transcript` when *P* has a reference record; +- `reviewed` when it has none and every cue's *r*ₖ has origin 1 (human) or 3 + (machine-reviewed): a person wrote or reviewed the reference; +- `self` otherwise: the reference is the machine's own final text, and the figure measures + how far its first display was from its own last. + +Two figures, each the sums over the cues of the counts of §3.2: + +- `first`: the prefix alignment of the words of *r*₀ to the words of the reference. It counts + the errors in what the viewer first saw, against as much of the reference as that revision + reaches, so the words a partial has not reached yet are not errors. +- `final`: the full alignment of the words of *r*ₖ to the words of the reference, when the + class is `transcript`; `null` otherwise. + +Each is `{"words", "errors", "substitutions", "deletions", "insertions"}`: *N*, *E* and its +three parts. + +### 4.7 The figure + +A **quality** record states the figures of *P*'s track. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-caption-quality"` | | +| `room` | `hex32` | the room | +| `principal` | `hex32` | *P* | +| `events` | `hex32` | *P*'s events digest (§4.1) | +| `sources` | `hex32` or `null` | the record id of *P*'s sources record, or `null` when there is none | +| `reference` | `hex32` or `null` | likewise, of its reference record | +| `cues` | `int` | the number of *P*'s cues | +| `latency` | object | `{"class", "n", "min", "max", "mean", "p50", "p95"}`: a string of §4.4, an `int`, and five `sint` or `null` | +| `stability` | object | `{"revisions", "words_changed", "cues_corrected"}`, each an `int` | +| `accuracy` | object | `{"class", "first", "final"}`: a string of §4.6, an object of §4.6, and one or `null` | +| `signer_pubkey`, `sig` | | §2 | + +Rules, in order: + +1. `room` is the verifier's: otherwise `wrong_room`. +2. *P*'s captions are whole (§4.1): otherwise `stream_incomplete`. +3. `events`, `sources` and `reference` are as the table says: otherwise + `figure_inputs_mismatch`. +4. Every other member but `kind`, `signer_pubkey` and `sig` equals the figure the verifier + computes from §4.4 to §4.6: otherwise `figure_mismatch`. + +A figure that passes is the figure of exactly those revisions, placed by exactly those +sources and measured against exactly that reference. A verifier needs no record of its own to +compute a figure: the **figure** of a whole track is the object a quality record would carry, +without `kind`, `signer_pubkey` and `sig`. + +## 5. Audio description + +### 5.1 The description record + +A **description** record is an audio description track: a script of timed descriptions of +what is seen, the mixing of each into the programme audio, and its voicing. Times are media +time in milliseconds, on the timeline of the media the descriptions accompany, as +timed-text §2 defines it. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-description"` | | +| `lang` | `tag` | the language of the descriptions | +| `script` | object | `{"origin", "model"}`: who wrote the descriptions | +| `voicing` | object | `{"form", "origin", "model", "track"}`: who or what speaks them | +| `events` | array | the descriptions, each an object below | +| `signer_pubkey`, `sig` | | §2 | + +`origin` is `"human"`, `"machine"` or `"machine-reviewed"`, the names timed-text §10.5 gives +the origins of a caption, and `model` is a `hex32` naming the model that wrote or spoke the +text, or `null`. `form` is `"track"`, the voicing is a separate audio track named by `track` +(a `hex32`, the track's digest, live-rooms §6.2), or `"sink"`, the sink synthesizes the +voice from the text with the model `model`, and `track` is `null`. + +| member of an event | type | meaning | +|---|---|---| +| `id` | `string` | its identifier | +| `begin`, `end` | `int` | the interval it describes, the description's time slot | +| `represents` | `"visual"`, `"visual.nonText"`, `"visual.text"`, `"visual.text.title"`, `"visual.text.credit"`, `"visual.text.location"`, `"visual.dialogue"` | what of the image it describes: DAPT's content descriptors of the visual image (DAPT §4.7 and Appendix H.2.2) | +| `text` | `string` | the description | +| `duck` | object | `{"gain", "ramp"}`, each an `int`: the programme audio's gain under the description in thousandths, and the milliseconds it takes to fall to it and to rise back | +| `voice` | object or `null` | `{"begin", "end"}`, each an `int`: where the voicing track speaks it; `null` when the form is `sink`, or when the track has not voiced it | + +### 5.2 Rules + +In order; the first that fails names the refusal: + +1. `lang` reads as live-events §4.10 reads a tag: otherwise `description_malformed`. +2. `script.model` is a `hex32` exactly when `script.origin` is `machine` or + `machine-reviewed`; likewise `voicing.model` for `voicing.origin`; `voicing.track` is a + `hex32` exactly when `form` is `track`; and when `form` is `sink`, `voicing.origin` is not + `human`: otherwise `description_malformed`. +3. There is at least one event; each `id` is one of `A`–`Z`, `a`–`z` or `_`, then up to 63 + of those, `0`–`9`, `.` and `-`; no `id` twice; each `begin` < `end` ≤ 359 999 999; each + event's `begin` is at or after the `end` of the event before it (one voice describes one + thing at a time): otherwise `description_malformed`. +4. Each `text` meets timed-text §3.2 rules 1 to 3: otherwise `text_not_in_subset`. +5. Each `duck`: `gain` ≤ 1000; `ramp` is 0 when `gain` is 1000 and above 0 otherwise; and + 2 × `ramp` ≤ `end` − `begin`. Each `voice`: `null` when the form is `sink`, and otherwise + `null` or within its event, the event's `begin` ≤ `voice.begin` < `voice.end` ≤ the + event's `end`, since a Script Event's audio is truncated at its end (DAPT §4.9.1): + otherwise `description_malformed`. +6. The synchronisation of §5.3: otherwise `description_out_of_sync`. + +### 5.3 Synchronisation + +The programme audio falls to the event's gain over [`begin`, `begin` + `ramp`) and rises back +over [`end` − `ramp`, `end`). The description is **spoken** over the interval between, from +*a* = `begin` + `ramp` to *z* = `end` − `ramp`. Of a voiced event (its `voice` not `null`): + +- `voice.begin` ≥ *a* − 35 and `voice.begin` ≤ *a* + 45; +- `voice.end` ≤ *z* + 45. + +These are DAPT §5.5's bounds on a presentation processor: audio presentation changes no more +than 35 ms before the time a document specifies and no more than 45 ms after it, which DAPT +derives from EBU R 37's bounds on audio relative to image. A voice that starts before the +programme audio has fallen, or runs on after it has risen, is out of those bounds. EN 301 549 +V4.1.1 clause 7.2.2 requires the synchronisation to be preserved and states no figure. + +The **offset** of a voiced event is `voice.begin` − *a*, a signed number of milliseconds; +an unvoiced event has none. + +### 5.4 Description over dialogue + +A description is spoken in the pauses of the dialogue (47 CFR 79.3(a)(3): "into natural +pauses between the program's dialogue"), though the regulator's 2024 statement accepts +describing over dialogue where what is seen matters more (§6.14 there). So this is a figure, +not a refusal. Against the dialogue of one or more caption tracks, whose resolved cues +(timed-text §4.5) cover the union *U* of their intervals [`start`, `end`), an event's +**overlap** is the milliseconds of its spoken interval, [`voice.begin`, `voice.end`) when it is +voiced and [*a*, *z*) otherwise, that lie in *U*. The figure is the sum of the overlaps and the +number of events whose overlap is above 0. + +### 5.5 The DAPT document + +A description record maps onto one DAPT document, given, for the form `track`, the voicing +track's URI `U` and media type `T`, each one to 2048 of the ASCII characters `!` to `~` +other than `"`, `&`, `<` and `>` (otherwise `parameter_malformed`). It is written as UTF-8 +with U+000A line ends: + +``` + + + +EVENTS + + +``` + +- `LANG` is `lang`. `REPS` is each `represents` value of the events once, in the order each + first appears, joined by U+0020: every event's value is then one of them (DAPT §4.1.1). + `TYPE` is `asRecorded` for the form `track` and `preRecording` for the form `sink`. +- `SO` and `VO` are the script's and the voicing's origins. After `wai:script="SO"` comes + ` wai:script-model="M"` when the script has a model, and after `wai:voice="VO"`, + ` wai:voice-model="M"` when the voicing has one, `M` the digest in lowercase hexadecimal. +- `EVENTS` is, for each event in order: + + ``` +
+ + +

CONTENT

+
+ ``` + + `B` and `E` are `begin` and `end` written `HH:MM:SS.mmm` (timed-text §5.1); `RAMP`, `FALL` + and `DUR` are `ramp`, `end` − `begin` − `ramp` and `end` − `begin`, written the same way; + `G` is the gain: `0` for 0, and otherwise `0.` and its three decimal digits with trailing + zeros removed. The two `animate` lines are written only when the gain is below 1000. +- `CONTENT` is the text, its lines separated by `
` and `&`, `<` and `>` written `&`, + `<` and `>`: + - for the form `track` and a voiced event, + ``, + with `VB` = `voice.begin` − `begin`, `VE` = `voice.end` − `begin`, `CB` = `voice.begin` + and `CE` = `voice.end`, each written `HH:MM:SS.mmm`. The voicing track is on the + programme's timeline (an audio description stem), so the event's audio is the interval + of it that the event's voice states; + - for the form `track` and an event not yet voiced, the text alone; + - for the form `sink`, `TEXT`. + +The document's features are DAPT's: a Script Event per description, a `div` with `xml:id`, +`begin`, `end` and `daptm:represents` (DAPT §4.3); its Mixing Instructions as `animate` +children of the Script Event, which adjust the programme audio during it (DAPT §4.3, §4.10); +an Audio Recording by `src` and `type` with `clipBegin` and `clipEnd` (DAPT §4.9.1); and +Synthesized Audio by `tta:speak` (DAPT §4.9.2). `ttp:contentProfiles` names the DAPT content +profile, and no `ttp:profile` is written (DAPT §5.6). The document's time base is media time, +times are clock times without frames (DAPT §5.7), and `daptm:langSrc` is `zxx`, content +without an inherent language (DAPT §4.5). Two choices are this extension's: + +- `src` on `audio`, for an external resource, is at risk in the Candidate Recommendation + (its Issue 218). If it does not stay, a later revision of this mapping names the voicing + track another way DAPT §4.9.1 keeps. +- For the form `sink`, DAPT says a pre-recording script SHOULD NOT contain Audio objects, and + an as-recorded script SHOULD NOT contain Synthesized Audio. There is no recording: the + sink's voice is the recording. The document is the script it speaks, marked as one, with + `tta:speak` saying that it is to be spoken. + +The attributes in the namespace `tag:transaction.science,2026:wai/access` are foreign +vocabulary, which DAPT §5.2 has a processor keep or prune. They carry the origin labels of +§5.6, which DAPT has no field for. + +### 5.6 Obligations of a WAI player + +These are requirements on a WAI player that plays audio description or shows sign language. +Each cites the provision it answers by identifier; they are engineering requirements, and +meeting them is not a statement about any law. + +1. **Description can be played.** A player of video with synchronised audio MUST let the + listener select an available description track and play it to the default audio output + (EN 301 549 V4.1.1 clause 7.2.1; WCAG 2.2 Success Criteria 1.2.3 and 1.2.5, which ask + content to provide it). +2. **In sync.** A player that mixes a description MUST apply its mixing instructions and play + each voice at the times its event states, within §5.3's bounds (EN 301 549 V4.1.1 clause + 7.2.2). +3. **Preserved.** A player or converter that transmits, converts or records a description MUST + keep every event's timing, text, mixing instructions, voicing and labels (EN 301 549 V4.1.1 + clause 7.2.3): §5.5's document keeps them all. +4. **One operation.** A player whose purpose is video MUST offer turning description on and + off as a single operation, at the same level as the volume control (EN 301 549 V4.1.1 + clause 7.3), as timed-text §11 item 5 has it for captions. +5. **Labelled.** A player MUST show, with a description whose voicing is `machine` or + `machine-reviewed`, that the voice is synthesized, in a way the listener perceives without + turning on another feature, as timed-text §11 item 7 has it for a machine caption, and + SHOULD let the listener learn whether the script was machine-written. The script's origin + and the voicing's are the description's labels, as a caption's origin is its label + (timed-text §10.1); a synthesized voice's origin, with the model's digest, is the statement + a synthesized object's origin claim makes of it. +6. **Signing under the viewer's control.** A player that shows a signing track MUST let the + viewer choose to show it, and SHOULD let the viewer choose its size and position (Directive + (EU) 2019/882 Annex I Section IV(b)(ii), "user control of their display"); a pose stream + leaves both to the sink (§6.1). It MUST show, with a signing track whose origin is + `machine` or `machine-reviewed`, that the signing is generated. + +## 6. Sign language + +### 6.1 The signing record + +A **signing** record is a sign language track: a `wai.avatar.pose` stream (avatars §1), or a +video track of a person signing. Its objects are bound, by digest, to the caption revisions +they translate. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-signing"` | | +| `room` | `hex32` | the room | +| `lang` | `tag` | the sign language | +| `source` | `hex32` | the principal of the caption track it translates | +| `form` | `"pose"`, `"video"` | an avatar pose stream, or a video of a signer | +| `track` | `hex32` | the track's digest (live-rooms §6.2) | +| `origin`, `model` | | as §5.1: `human` for a person signing (filmed, or motion-captured into the pose stream), `machine` for signing a model generated | +| `video` | object or `null` | for `video`, `{"width", "height", "rate_num", "rate_den"}`, each an `int`: its picture size and frame rate; `null` for `pose` | +| `segments` | array | each an object below | +| `signer_pubkey`, `sig` | | §2 | + +| member of a segment | type | meaning | +|---|---|---| +| `object` | `hex32` | the content hash of an object of the track (jwp-receipts §2.1): an op batch of the pose world, or a video object | +| `start`, `end` | `int` | room-clock microseconds the signing of the object spans | +| `revisions` | array of `hex32` | the caption revisions it translates, by the digest of each `caption` event | + +Pose-equivalence (avatars §4) makes the motion every sink shows the motion in the bound +objects, while the appearance is the sink's: a viewer may choose the signer's size, place +and appearance, which Directive (EU) 2019/882 Annex I Section IV(b)(ii) calls user control of +display, and the binding still holds. + +### 6.2 Rules + +In order: + +1. `room` is the verifier's: otherwise `wrong_room`. +2. `lang` reads as a tag; `model` is a `hex32` exactly when `origin` is `machine` or + `machine-reviewed`; `video` is `null` exactly for `pose`, and its four numbers are above 0; + there is at least one segment, each with `start` < `end` and at least one revision, each + segment's `start` at or after the `end` of the segment before it; and no revision is + named twice in the record: otherwise `signing_malformed`. +3. `source`'s captions are whole (§4.1): otherwise `stream_incomplete`. +4. Each named revision is a `caption` event of `source` that the verifier holds: otherwise + `sign_revision_unknown`. +5. Each named revision is the last of its cue and final, its annotation not unknown: otherwise + `sign_revision_not_final`. Signing translates the text a cue resolves to; a partial that a + later revision changed is not what the captions say. + +### 6.3 Figures + +- The **offset** of a segment is its `start` less *S* (§4.4) of the earliest cue, by its + first revision's `t`, among those whose final revisions it names, when `source`'s sources + record places that cue; it has none otherwise. It is a signed number of microseconds: the + delay of the signing behind the speech it interprets. +- For the form `video`, the **video floor** is `meets` when the picture is at least 320 by 240 + in either orientation (the smaller side at least 240 and the larger at least 320) and the + frame rate at least 20 a second (`rate_num` ≥ 20 × `rate_den`), and `below` otherwise: the + resolution and frame rate EN 301 549 V4.1.1 clauses 6.5.2 and 6.5.3 require of real-time + video communication, which its clause 4.2.4 NOTE 3 names for sign language that accompanies + audiovisual content. For the form `pose` it is `null`: the sink renders the signer at the + size it chooses. + +### 6.4 Review + +A person who reviews the translation signs a **review**: + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-signing-review"` | | +| `signing` | `hex32` | the record id of the signing record it reviews | +| `scope` | `"translation"` | what was reviewed: the signing against the caption revisions it is bound to | +| `verdict` | `"approved"`, `"approved-with-notes"`, `"rejected"` | | +| `notes` | `hex32` or `null` | the digest of the reviewer's notes; `null` exactly for `approved` | +| `signer_pubkey`, `sig` | | §2 | + +Rules: `notes` is `null` exactly when the verdict is `approved` (`record_malformed`), and +`signing` is the record id of a signing record the verifier holds (`review_subject_unknown`). +The review binds the objects by their digests, so, for a pose stream, every viewer whose sink +is pose-equivalent sees the motion the reviewer approved. + +## 7. The completeness claim + +### 7.1 The record + +A **completeness** claim states, for a room session, which access tracks it carried, and that +each was delivered complete and in sync. + +| member | type | meaning | +|---|---|---| +| `kind` | `"wai-access-completeness"` | | +| `room` | `hex32` | the room | +| `from`, `to` | `int` | the session, room-clock microseconds [`from`, `to`) | +| `pt0` | `int` | the media time of the room's `t0`, in milliseconds (timed-text §2) | +| `tracks` | array | the access tracks it declares, each an object below | +| `signer_pubkey`, `sig` | | §2 | + +| service | its members besides `service` | +|---|---| +| `"captions"` | `principal` (`hex32`), `lang` (`tag`), `latency_mean_max` and `latency_max` (each `int` or `null`, microseconds) | +| `"audio-description"` | `record` (`hex32`, a description record's id), `lang` (`tag`) | +| `"sign-language"` | `record` (`hex32`, a signing record's id), `lang` (`tag`), `review` (`hex32` or `null`, a review's id), `offset_max` (`int` or `null`, microseconds) | + +The tracks a claim declares are the availability of access services an electronic programme +guide states (EN 301 549 V4.1.1 clauses 12.4 and 12.5), made checkable. + +A cue of *P* is **in the session** when its first revision's `t` is in [`from`, `to`). The +session's media interval is from `pt0` + ⌊`from` / 1000⌋ to `pt0` + ⌊`to` / 1000⌋. + +### 7.2 Checking the claim + +1. `room` is the verifier's: otherwise `wrong_room`. +2. `from` < `to`; at least one track; each track's `lang` reads; no principal is named by two + caption tracks, and no record by two tracks: otherwise `claim_malformed`. + +Then each track in order, the first failure naming the refusal: + +**Captions**, of principal *P*: + +1. *P* has a cue in the session: otherwise `track_missing`. +2. *P*'s captions are resolved (§4.1): otherwise `track_incomplete`. A delivery gap is an + event not delivered, and a cue that does not resolve was not finished. +3. Every revision of every cue of *P* in the session has the track's `lang`: otherwise + `track_mismatch`. +4. When `latency_mean_max` or `latency_max` is not `null`: *P*'s sources record places every + cue of *P* in the session, otherwise `sync_unmeasured`; and over those cues the mean + latency (§4.4) is at most `latency_mean_max`, and each latency at most `latency_max`, where + each is given: otherwise `out_of_sync`. + +**Audio description**, of record *D*: + +1. *D* is a description record the verifier holds: otherwise `track_missing`. +2. Its `lang` is the track's, and each of its events lies in the session's media interval: + otherwise `track_mismatch`. +3. For the form `track`, every event is voiced: otherwise `track_incomplete`. (Each voice is + already in sync, §5.3.) + +**Sign language**, of record *G*: + +1. *G* is a signing record the verifier holds: otherwise `track_missing`. +2. Its `lang` is the track's, and its `source` is the principal of a caption track of this + claim: otherwise `track_mismatch`. +3. Every cue of `source` in the session has its final revision named by a segment of *G*: + otherwise `track_incomplete`. +4. When `review` is not `null`: it is the id of a review the verifier holds (otherwise + `review_missing`), which names *G* (otherwise `review_mismatch`) and whose verdict is not + `rejected` (otherwise `review_rejected`). +5. When `offset_max` is not `null`: every segment of *G* has an offset (§6.3), otherwise + `sync_unmeasured`; and each offset's absolute value is at most `offset_max`, otherwise + `out_of_sync`. + +A claim that passes is **held**. Its **dialogue overlap** is, for each audio description +track, §5.4's figure against the resolved cues of the claim's caption tracks, their media +times as timed-text §4.5 gives them with the claim's `pt0`. + +### 7.3 The tolerances + +| track | measured from | tolerance | stated by | +|---|---|---|---| +| captions, live | each cue's first display and its source (§4.4) | a mean of at most 4.5 s across live programming: a recommendation, not a limit per programme | the regulator's 2024 statement, §5.17 and §5.25; its 2013 statement (§3.65 to §3.67) recorded the earlier guidance of at most 3 s | +| captions, shown by a player | a cue's time | within 100 ms of it, 20 ms as good practice | EN 301 549 V4.1.1 clause 7.1.2: the player's, timed-text §11 item 2 | +| audio description | each voice and its event (§5.3) | 35 ms early to 45 ms late | DAPT §5.5, from EBU R 37 | +| sign language | each segment and its source (§6.3) | none stated | no text read for this revision gives a figure; EN 301 549 V4.1.1 clause 4.2.4 NOTE 3 asks only that it be "well synchronized with the spoken content" | + +A claim states the caption and sign tolerances it is held to (`latency_mean_max`, +`latency_max`, `offset_max`); the description tolerance is fixed by §5.3. The captions' +mean is computed over the session, while the 2024 statement's is over a provider's live +programming taken together; a claim that states 4 500 000 holds one session to it. + +## 8. Verification + +### 8.1 Inputs + +A verifier is given the room id; the records of the room's event stream, in stream order +(live-events §6); and the records of this extension, as JSON texts, in the order given. + +### 8.2 Steps + +1. **Events.** Each event record is offered, in stream order, to a verifier of captions + ([timed-text](timed-text.md) §4.3), which verifies it as live-events §6 does and the + captions in it as timed-text §4.3 does. A refusal is the outcome, at `events` and the + record's index, with that extension's reason. At the end of the stream the captions are + finished (timed-text §4.3), and the gaps, which are not refusals, are noted. +2. **Reading.** Each record is read (§2), its signature verified and its record id computed, + in the order given: a failure is the outcome, at `record` and the record's index. +3. **Rules.** Then each record is checked by its section's rules, kind by kind in this + order, and the records of one kind in the order given: sources (§4.2), references + (§4.3), descriptions (§5.2), signings (§6.2), reviews (§6.4), quality records (§4.7) and + claims (§7.2). So a record that another names has been checked before it. The first + failure is the outcome, at `record` and the failing record's index. +4. **Figures.** With no refusal, the outcome is **accept**, with: the figure (§4.7) of every + principal whose captions are whole, in the order of each one's first `caption` event in + the stream; for + each description record, its number of events, the number voiced and each event's offset + (§5.3); for each signing record, its number of segments and of revisions named, each + segment's offset and its video floor (§6.3); and for each claim, its dialogue overlap + (§7.2). + +## 9. What the figures measure + +| figure | what it measures | in the texts read | +|---|---|---| +| latency: per cue, its mean, its range (`min`, `max`) and two ranks | first display on the room clock, less the capture of the first word the cue carries | the 2013 statement's "average latency of the subtitling (the delay between speech and live subtitling), and the range of latencies" (§1.3(b)); the 2024 statement's mean (§5.17, §5.25); 47 CFR 79.1(k)(2)(vi), "lag between the spoken word supplied by the program origination point and when captions are received at the same program origination point", which the room clock's `t`, stamped as the caption leaves its author, measures; 79.1(j)(2)(ii) and (j)(3)(ii); EBU Tech 3370 §2.3.2's authoring delay, from the subtitler hearing the audio to the tool's output, and its §2.3.3 `ebuttm:authoringDelay`, which a producer may state and this figure measures | +| stability: revisions after first display, words changed, cues corrected | what the viewer saw that a later revision changed | the 2024 statement's research finding that subtitles corrected live on air distract (§5.23) | +| accuracy: words, errors, and their kinds | word errors against a reference a person wrote or reviewed | 47 CFR 79.1(k)(2)(iv): accuracy is the total words less the errors, over the total words, which is (*N* − *E*) / *N* here, and (k)(2)(v)'s kinds of error, of which this figure counts incorrect and missing words; 79.1(j)(2)(i); the 2013 statement's "number and type of errors" (§1.3(c)); the 2024 statement sets no minimum accuracy (§5.29) | +| dialogue overlap | description spoken over captioned dialogue | 47 CFR 79.3(a)(3); the 2024 statement §6.2 and §6.14 | +| completeness | every declared track present, every cue finished, every event voiced and every cue signed | Directive (EU) 2019/882 Annex I Section IV(b)(ii), "fully transmitted … synchronised"; 47 CFR 79.1(j)(2)(iii), captioning "from the beginning to the end of the program", which this claim checks over the cues the session holds, not over the speech it does not hold | + +Not computed here: + +- the severity of an error, which the error-classification model the 2013 statement's + measurement used (its footnote 21) grades minor, standard or serious: that grading needs a + person. The alignment gives the errors and the reference words a grader starts from; +- errors of capitalisation and of punctuation at a word's edge, which §3.1 removes, and which + 47 CFR 79.1(j)(2)(i) counts; +- the speed of the captions, and their placement (79.1(j)(2)(iv)); +- the quality of a description, of a voice or of a signing, which a person judges, and + whose judgement a review records. + +## 10. Reasons + +| reason | raised at | +|---|---| +| `record_malformed` | §2, §4.2, §4.3, §6.4 | +| `bad_key` | §2 | +| `bad_signature` | §2 | +| `wrong_room` | §2, §4.2, §4.3, §4.7, §6.2, §7.2 | +| `record_conflict` | §4.2, §4.3 | +| `source_unknown` | §4.2 | +| `source_take_unknown` | §4.2 | +| `text_not_in_subset` | §4.3, §5.2 | +| `reference_unknown` | §4.3 | +| `reference_incomplete` | §4.3 | +| `stream_incomplete` | §4.2, §4.3, §4.7, §6.2 | +| `figure_inputs_mismatch` | §4.7 | +| `figure_mismatch` | §4.7 | +| `description_malformed` | §5.2 | +| `description_out_of_sync` | §5.2, §5.3 | +| `parameter_malformed` | §5.5 | +| `signing_malformed` | §6.2 | +| `sign_revision_unknown` | §6.2 | +| `sign_revision_not_final` | §6.2 | +| `review_subject_unknown` | §6.4 | +| `claim_malformed` | §7.2 | +| `track_missing` | §7.2 | +| `track_incomplete` | §7.2 | +| `track_mismatch` | §7.2 | +| `sync_unmeasured` | §7.2 | +| `out_of_sync` | §7.2 | +| `review_missing` | §7.2 | +| `review_mismatch` | §7.2 | +| `review_rejected` | §7.2 | + +An event record that [live-events](live-events.md) or [timed-text](timed-text.md) refuses +keeps that extension's reason. + +## 11. Conformance + +[`live-conformance/access/`](../live-conformance/access/) holds the corpus, written from fixed +seeds by `wai_access_services_vectors gen`: `vectors.json`, and each description record's DAPT +document as a file of its own, `NAME.dapt.ttml`. Each vector is a room's event stream and the +records of this extension, with the outcome §8 gives them and, when accepted, every figure. It +has: + +- **accepted sessions**: a lesson with a human captioner, a machine captioner whose partials + are revised to final, a capture take placing the machine captions' words, a reference + transcript, a quality record for each track, a description voiced on a separate track, a + motion-captured signer bound to the human captions with an approved review, and a claim over + all of them held to the 2024 statement's mean; a session whose machine captions a person + reviews, with a description the sink voices by a pinned model, the video of a signer, and a + claim without latency bounds; and a session with no sources, whose latency class is `none`; +- **negative controls**, each a copy of an accepted session with one defect, and each refused + with its reason: a latency figure misstated, a broken revision chain, a sign track bound to a + revision a later one superseded and to a revision the stream does not hold, a description + spoken late and one spoken early, a claim over a track the verifier does not hold, and one + for every other reason of §10. + +A conforming verifier gives every vector the outcome, the reason, the place and every figure +the corpus states, and writes every DAPT document byte for byte. `wai_access_services_vectors +verify` and the test `tests/access_services.rs` check that every file regenerates byte for +byte, that no other file is there, that `wai-rs` gives every vector its outcome, that every +reason of §10 refuses a vector, and that §10 lists exactly the reference's codes. +`live-conformance/access_services_verify.py` is the second implementation, written from this +text: it shares no code with `wai-rs`; it verifies events and captions with the timed-text +corpus's second implementation (`timed_text_verify.py`) and signatures with WAI's strict rule +(`claim-conformance/_ed25519.py`); it computes every figure, writes every DAPT document and +parses each with an XML parser; and it requires every mutated copy of the corpus to fail. + +## 12. Security and privacy considerations + +- Every figure is recomputed from signed records. A figure states nothing a verifier takes on + trust; a quality record's signer vouches only that it computed the figure, and a verifier + that recomputes it needs no trust in the signer. +- A source places words on the room clock as its signer states. On a take, the media's time is + the device's signed commitment and cannot be moved; where a word lies in the media is the + aligner's statement, attributable to it by its signature, and checkable by anyone holding the + master. A source on the basis `room` places the words by the signer's word alone, and the + latency's class says so (`stated`). +- A take's opening commitment is the device's, but a principal that is not a capturing device + can sign one too. This extension requires the take to be derived from a `record_start` + addressed to the commitment's author; that the author was permitted to capture, and for + whom, is what a take verifier and a room verifier check (capture-binding §9, live-rooms §9). +- `t` is its author's statement of the room clock (live-events §11). A captioner who stamps + its captions early lowers its latency, and the stamp is signed: the room's relays see when + each event arrived, and a later extension's per-hop receipts witness it. +- A reference transcript is its reviewer's. The accuracy's class names what the reference is; + a verifier's policy decides whose transcripts it accepts. +- Labels are their producers' statements, as timed-text §14 says of captions. A description + or a signing labelled human that a model produced misleads its audience, and the signature + makes that attributable. +- A signing track's binding names caption revisions by digest. It shows what the signing + translates; it does not show that the translation is correct, which a review states. +- A sources record ties a cue to a position in a recording, and a signing record ties a track + to a person who signs. Both persist with the session's records, as the events do. diff --git a/wai/live-conformance/access/lesson.dapt.ttml b/wai/live-conformance/access/lesson.dapt.ttml new file mode 100644 index 000000000..5b4cb484a --- /dev/null +++ b/wai/live-conformance/access/lesson.dapt.ttml @@ -0,0 +1,13 @@ + + + +
+ + +

+
+
+

+
+ +
diff --git a/wai/live-conformance/access/reviewed.dapt.ttml b/wai/live-conformance/access/reviewed.dapt.ttml new file mode 100644 index 000000000..cc2e3fb0f --- /dev/null +++ b/wai/live-conformance/access/reviewed.dapt.ttml @@ -0,0 +1,13 @@ + + + +
+ + +

Divers swim over a reef.

+
+
+

Title:
Reef Tour & Co.

+
+ +
diff --git a/wai/live-conformance/access/vectors.json b/wai/live-conformance/access/vectors.json new file mode 100644 index 000000000..d249804a9 --- /dev/null +++ b/wai/live-conformance/access/vectors.json @@ -0,0 +1,1116 @@ +{ + "corpus": "wai.access.services", + "extension": "extensions/access-services.md", + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "pt0_ms": 10000, + "principals": { + "captioner": "87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe", + "asr": "56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001", + "host": "2d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b20", + "device": "ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de14", + "aligner": "263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956", + "reviewer": "e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9", + "describer": "b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444", + "interpreter": "95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f", + "vendor": "52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130", + "authority": "fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23" + }, + "streams": { + "chain_broken": [ + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e741872d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b200000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de1401000000001bffa56183c4c3aa97a2efae0fb726f5322628352afe12e0d346d554d93ccb6d4cc4ef90c7f9ed4098a797b7498479b66709cb243341c025a37486aac56bd803", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de140000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000c7e00494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba100000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040dd41e2ffffffff0053293b4096015ced35fe84239caa53bd71864059d94a4e7d49a548f9a263250cc33370ead2513c9643f35e8510df5d2054251919abe863809ef87f8d5429510f", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2100c40900000102656e1700476f6f64206d6f726e696e672c2065766572796f6e652e7d43e0501c1ab0e8fafc847be4edf8352de639398bc68aa34319fac45def7f32c457c3162a0569549219bf3358f72dda5ef5247b374a09f24990e0b78936060a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010000000000000000000000000000000000000000000000000000000000000000000000000000000000d4300000000000000a380000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0e00746865206d6f6f6e2070756c6c73bcdad8c7cda10259d3b21876a5e85511a20c613854622c7681822c10a3ea0430f48ca9a4bbffc1913153996cc676b0eefe17e9ae1825da8f303cf328fdbe2600", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010100000000000000076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da00d430000000000000012a00575458310100000000000000000000000000000000000000000000000000000000000000000009000000b25055afbe85cb2bb0563be564e2343dddd9bb9a5538549124d3b4ca650745bdd62e8c50cfcd89e7feb3243a7fdaa7571735ff07472640b39d5f00a6781be503", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010200000000000000df93cbf05a4c8d2bfcfea2eda806e07c3cdbf377aaf4b6459d41c28fa1170f9d60823b0000000000000a400000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1600746865206d6f6f6e2070756c6c732074686520736565a1ac615baae4448ac132e82f6d24d20607f78ed74863e848bbd67e8b2381e3a3acbb36153982d823aa26bf144233b74019dc1e7f5a2b6d4ac46683514b04760d", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010300000000000000bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d509360823b000000000000012a005754583101076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da000f0000008d3f0faa28b92a0c85a4888b39eb6a0030ec8d1f8727901e1bdcb05fc25c47379185885303875678a4a1f19572829e04effdeb6a849481aeaed17f86933d7201", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700104000000000000000b42be0829c954d2a313b5c9c0fd19dbd20012e43b3a50a6fdcde4dda4963655c030460000000000000a4100d0070000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1700746865206d6f6f6e2070756c6c7320746865207365612e522f8c4ee1498325a43177c3cce3c3f083dc21ed13f43f6f92a126b501fcc500d166f11c1db04079b17002a6cf2adfb34fc869a00ca4b293d35a8ac95975f009", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001050000000000000088a03d93fa1d1e5f9eda11ecb62d1b03bbbc80bd1aa4b9526931cdd6a62875b9c03046000000000000012a005754583101bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d50930117000000441f7dee8fbbe83309090d229ea934de89b5551808889f975cd7b888c472f951f1878704dd5d4a7c1518001448090ff7928837ba12ab762822cbe0d89279790b", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe01000000000000003b3948279cf4349c5cbe8fc6d49b398f8c731bfc8fc47876f64825e0da69dbe3404b4c0000000000000a2100b80b00000102656e1700546f646179207765206c6f6f6b2061742074696465732e6f1fa1aa7d06b9b589eb56d29348eaf6fea623f4f37f5d911f6874b5e4d335dbf3c69cd854964ca1bc3d74d3eea59b24bb0077092bbe702fd44cff65b561bc04", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010600000000000000fa9977b9737d0835c88d156f44a699568cbb60fb61c1dc3c5a4c9c147e685de1a02e630000000000000a330000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0900686967682074696564495d060c3135c4695890e63112797c5be0099fa4d7c397a14c4b6712f149b6714b19eaa59c80adf572ea0f6e1345ec0b004459b969412326577d6981ed62770a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010700000000000000bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19caa02e63000000000000012a0057545831010000000000000000000000000000000000000000000000000000000000000000000500000052a2878e6f0749e6c54c991e8b32260020e70fa93200047f01b92568b4776fc446848afe37df28be7e2000bcbb52e19c94a9f4a0bcbc0ed08503d63ceaf66505", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010800000000000000a1bb6304755037a3b06c15fa5af33f4ab4a0647c206f6f42fa8f7ca1db8ecccba0636f0000000000000a4400c4090000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1a0068696768207469646520636f6d6573207477696365206461792e112b3fb121643b611cc3a9f51b25ff9983fa9fa90a98cd550552f292b226ce9703f32d19c9927d0049b49426b27628693fcbbef50440f62b483cdb9f0501e90c", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010900000000000000f19c0555d3beb81e6d96ec16202dcdebb62574e7a13d28188a51937984d8830aa0636f000000000000012a005754583101bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca011a000000265536e452291b0aeba65d37f41f488781ae4648eee419ca9fb5b4fba2dc14a5c4d14a05975eb184430124a9c110736055085c993e196d5d61622fcedf434108", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0200000000000000ec01cf8ff09fa503dff54f1228f58b30bb8c31c622559bbbd0e1d480241003474054890000000000000a1700d00700000102656e0d005b57617665732063726173685d6ab7c8d2458cf20a4a603922387616a7e38dc36d2ddea9a5086784ffafe1cb358b77bc6da3c75083ff2422c806db1bf75d3f8de2b05c582b53a1d41ddf0d4a0f" + ], + "gap": [ + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e741872d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b200000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de1401000000001bffa56183c4c3aa97a2efae0fb726f5322628352afe12e0d346d554d93ccb6d4cc4ef90c7f9ed4098a797b7498479b66709cb243341c025a37486aac56bd803", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de140000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000c7e00494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba100000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040dd41e2ffffffff0053293b4096015ced35fe84239caa53bd71864059d94a4e7d49a548f9a263250cc33370ead2513c9643f35e8510df5d2054251919abe863809ef87f8d5429510f", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2100c40900000102656e1700476f6f64206d6f726e696e672c2065766572796f6e652e7d43e0501c1ab0e8fafc847be4edf8352de639398bc68aa34319fac45def7f32c457c3162a0569549219bf3358f72dda5ef5247b374a09f24990e0b78936060a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010000000000000000000000000000000000000000000000000000000000000000000000000000000000d4300000000000000a380000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0e00746865206d6f6f6e2070756c6c73bcdad8c7cda10259d3b21876a5e85511a20c613854622c7681822c10a3ea0430f48ca9a4bbffc1913153996cc676b0eefe17e9ae1825da8f303cf328fdbe2600", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010100000000000000076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da00d430000000000000012a00575458310100000000000000000000000000000000000000000000000000000000000000000009000000b25055afbe85cb2bb0563be564e2343dddd9bb9a5538549124d3b4ca650745bdd62e8c50cfcd89e7feb3243a7fdaa7571735ff07472640b39d5f00a6781be503", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010200000000000000df93cbf05a4c8d2bfcfea2eda806e07c3cdbf377aaf4b6459d41c28fa1170f9d60823b0000000000000a400000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1600746865206d6f6f6e2070756c6c732074686520736565a1ac615baae4448ac132e82f6d24d20607f78ed74863e848bbd67e8b2381e3a3acbb36153982d823aa26bf144233b74019dc1e7f5a2b6d4ac46683514b04760d", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010300000000000000bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d509360823b000000000000012a005754583101076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da000f0000008d3f0faa28b92a0c85a4888b39eb6a0030ec8d1f8727901e1bdcb05fc25c47379185885303875678a4a1f19572829e04effdeb6a849481aeaed17f86933d7201", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700104000000000000000b42be0829c954d2a313b5c9c0fd19dbd20012e43b3a50a6fdcde4dda4963655c030460000000000000a4100d0070000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1700746865206d6f6f6e2070756c6c7320746865207365612e522f8c4ee1498325a43177c3cce3c3f083dc21ed13f43f6f92a126b501fcc500d166f11c1db04079b17002a6cf2adfb34fc869a00ca4b293d35a8ac95975f009", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001050000000000000088a03d93fa1d1e5f9eda11ecb62d1b03bbbc80bd1aa4b9526931cdd6a62875b9c03046000000000000012a005754583101bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d50930117000000441f7dee8fbbe83309090d229ea934de89b5551808889f975cd7b888c472f951f1878704dd5d4a7c1518001448090ff7928837ba12ab762822cbe0d89279790b", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0100000000000000790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5404b4c0000000000000a2100b80b00000102656e1700546f646179207765206c6f6f6b2061742074696465732e3b8611e89a4a6dae4ddecb1421d580e0da739dcd908a7f0d9b46197da88d8294edffc1c784b0b35e6b2a08ef4acea31595f68d9e8dac793c9fbc0f971b53b801", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010800000000000000a1bb6304755037a3b06c15fa5af33f4ab4a0647c206f6f42fa8f7ca1db8ecccba0636f0000000000000a4400c4090000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1a0068696768207469646520636f6d6573207477696365206461792e112b3fb121643b611cc3a9f51b25ff9983fa9fa90a98cd550552f292b226ce9703f32d19c9927d0049b49426b27628693fcbbef50440f62b483cdb9f0501e90c", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010900000000000000f19c0555d3beb81e6d96ec16202dcdebb62574e7a13d28188a51937984d8830aa0636f000000000000012a005754583101bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca011a000000265536e452291b0aeba65d37f41f488781ae4648eee419ca9fb5b4fba2dc14a5c4d14a05975eb184430124a9c110736055085c993e196d5d61622fcedf434108", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe020000000000000032ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c2614054890000000000000a1700d00700000102656e0d005b57617665732063726173685d963dd3dfe86c43c0849a267f171d5c4279529ac46feaca4914dfeb5c659316b71be6cede5c3a4d39e043313d2794cbcf99b9297156112998070ec1b2b7a38509" + ], + "lesson": [ + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e741872d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b200000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de1401000000001bffa56183c4c3aa97a2efae0fb726f5322628352afe12e0d346d554d93ccb6d4cc4ef90c7f9ed4098a797b7498479b66709cb243341c025a37486aac56bd803", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de140000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000c7e00494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba100000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040dd41e2ffffffff0053293b4096015ced35fe84239caa53bd71864059d94a4e7d49a548f9a263250cc33370ead2513c9643f35e8510df5d2054251919abe863809ef87f8d5429510f", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2100c40900000102656e1700476f6f64206d6f726e696e672c2065766572796f6e652e7d43e0501c1ab0e8fafc847be4edf8352de639398bc68aa34319fac45def7f32c457c3162a0569549219bf3358f72dda5ef5247b374a09f24990e0b78936060a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010000000000000000000000000000000000000000000000000000000000000000000000000000000000d4300000000000000a380000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0e00746865206d6f6f6e2070756c6c73bcdad8c7cda10259d3b21876a5e85511a20c613854622c7681822c10a3ea0430f48ca9a4bbffc1913153996cc676b0eefe17e9ae1825da8f303cf328fdbe2600", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010100000000000000076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da00d430000000000000012a00575458310100000000000000000000000000000000000000000000000000000000000000000009000000b25055afbe85cb2bb0563be564e2343dddd9bb9a5538549124d3b4ca650745bdd62e8c50cfcd89e7feb3243a7fdaa7571735ff07472640b39d5f00a6781be503", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010200000000000000df93cbf05a4c8d2bfcfea2eda806e07c3cdbf377aaf4b6459d41c28fa1170f9d60823b0000000000000a400000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1600746865206d6f6f6e2070756c6c732074686520736565a1ac615baae4448ac132e82f6d24d20607f78ed74863e848bbd67e8b2381e3a3acbb36153982d823aa26bf144233b74019dc1e7f5a2b6d4ac46683514b04760d", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010300000000000000bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d509360823b000000000000012a005754583101076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da000f0000008d3f0faa28b92a0c85a4888b39eb6a0030ec8d1f8727901e1bdcb05fc25c47379185885303875678a4a1f19572829e04effdeb6a849481aeaed17f86933d7201", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700104000000000000000b42be0829c954d2a313b5c9c0fd19dbd20012e43b3a50a6fdcde4dda4963655c030460000000000000a4100d0070000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1700746865206d6f6f6e2070756c6c7320746865207365612e522f8c4ee1498325a43177c3cce3c3f083dc21ed13f43f6f92a126b501fcc500d166f11c1db04079b17002a6cf2adfb34fc869a00ca4b293d35a8ac95975f009", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001050000000000000088a03d93fa1d1e5f9eda11ecb62d1b03bbbc80bd1aa4b9526931cdd6a62875b9c03046000000000000012a005754583101bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d50930117000000441f7dee8fbbe83309090d229ea934de89b5551808889f975cd7b888c472f951f1878704dd5d4a7c1518001448090ff7928837ba12ab762822cbe0d89279790b", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0100000000000000790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5404b4c0000000000000a2100b80b00000102656e1700546f646179207765206c6f6f6b2061742074696465732e3b8611e89a4a6dae4ddecb1421d580e0da739dcd908a7f0d9b46197da88d8294edffc1c784b0b35e6b2a08ef4acea31595f68d9e8dac793c9fbc0f971b53b801", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010600000000000000fa9977b9737d0835c88d156f44a699568cbb60fb61c1dc3c5a4c9c147e685de1a02e630000000000000a330000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0900686967682074696564495d060c3135c4695890e63112797c5be0099fa4d7c397a14c4b6712f149b6714b19eaa59c80adf572ea0f6e1345ec0b004459b969412326577d6981ed62770a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010700000000000000bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19caa02e63000000000000012a0057545831010000000000000000000000000000000000000000000000000000000000000000000500000052a2878e6f0749e6c54c991e8b32260020e70fa93200047f01b92568b4776fc446848afe37df28be7e2000bcbb52e19c94a9f4a0bcbc0ed08503d63ceaf66505", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010800000000000000a1bb6304755037a3b06c15fa5af33f4ab4a0647c206f6f42fa8f7ca1db8ecccba0636f0000000000000a4400c4090000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1a0068696768207469646520636f6d6573207477696365206461792e112b3fb121643b611cc3a9f51b25ff9983fa9fa90a98cd550552f292b226ce9703f32d19c9927d0049b49426b27628693fcbbef50440f62b483cdb9f0501e90c", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010900000000000000f19c0555d3beb81e6d96ec16202dcdebb62574e7a13d28188a51937984d8830aa0636f000000000000012a005754583101bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca011a000000265536e452291b0aeba65d37f41f488781ae4648eee419ca9fb5b4fba2dc14a5c4d14a05975eb184430124a9c110736055085c993e196d5d61622fcedf434108", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe020000000000000032ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c2614054890000000000000a1700d00700000102656e0d005b57617665732063726173685d963dd3dfe86c43c0849a267f171d5c4279529ac46feaca4914dfeb5c659316b71be6cede5c3a4d39e043313d2794cbcf99b9297156112998070ec1b2b7a38509" + ], + "reviewed": [ + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010000000000000000000000000000000000000000000000000000000000000000000000000000000060e3160000000000000a380000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0e0077656c636f6d6520746f2074686585dde124e88591d3a5fd0cf10fee9d6b9f3b4982c0779afb175c5f631962296b533ee85ebab376a305fe0b9abdcf3f9143e87296517b2429e35c671a41041c0a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010100000000000000c718cf034cb47537cddb3e30febd1dc7c1e5d44d818e818e9067793f15e85ab960e316000000000000012a00575458310100000000000000000000000000000000000000000000000000000000000000000008000000da44827d4fb78a7424196b67e34625962c43690d43f9dcae1ce7b9844ff46e56f40bbfd0583a03fab93839fcb3acd421a8e518a7f2a9e87d359b686a01ef5a04", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010200000000000000dc38d285f1d2195458ad48110b257a42808dacb295fe2e305bb8ef7da1e0782e009f240000000000000a4300b80b0000032cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e190077656c636f6d6520746f20746865207265656620746f75722e99d190a2c32e5b5871f240fdb54e20812cd737b1f4e7ef086ac8e6a2f58f472beda65e949930b426ce146bb6190b37cf664cf507e5e5ad0709d856cc87743205", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010300000000000000a490a6ff974eba5f5e101a8cc6ebe555611fb6c8efc33649b38f1eb3eb157212009f24000000000000012a005754583101c718cf034cb47537cddb3e30febd1dc7c1e5d44d818e818e9067793f15e85ab901190000000a425619c8894d8e288ece43b9dcc467be6449cf4ac074076cdcce7f5e1621e3f8caefebcd3f87e17a2ee1eac5ac598d5482bd791b0c90d274509623215d6606", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010400000000000000e1c7e395b1673f544bb842e6c978750401d418a301165dece257e2cc9ef8ea6f808d5b0000000000000a3d00c4090000032cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1300436f72616c732061726520616e696d616c732e3352f378c055af98e998fee86f6e92b709b7549f8928943bb23c42d6ec3272fb43d85beaa4b832c6181340c381a008d547cb041b27c7120d6110b12f838a2c07" + ], + "supersede_unknown": [ + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e741872d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b200000000000000000000000000000000000000000000000000000000000000000000000000000000040420f000000000000092500ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de1401000000001bffa56183c4c3aa97a2efae0fb726f5322628352afe12e0d346d554d93ccb6d4cc4ef90c7f9ed4098a797b7498479b66709cb243341c025a37486aac56bd803", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187ab92805903180964e9625a4f13685fdc7c7cc50c64f7ed0bbebb4f2d7736de140000000000000000000000000000000000000000000000000000000000000000000000000000000040420f0000000000000c7e00494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba100000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040dd41e2ffffffff0053293b4096015ced35fe84239caa53bd71864059d94a4e7d49a548f9a263250cc33370ead2513c9643f35e8510df5d2054251919abe863809ef87f8d5429510f", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0000000000000000000000000000000000000000000000000000000000000000000000000000000080841e0000000000000a2100c40900000102656e1700476f6f64206d6f726e696e672c2065766572796f6e652e7d43e0501c1ab0e8fafc847be4edf8352de639398bc68aa34319fac45def7f32c457c3162a0569549219bf3358f72dda5ef5247b374a09f24990e0b78936060a", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010000000000000000000000000000000000000000000000000000000000000000000000000000000000d4300000000000000a380000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0e00746865206d6f6f6e2070756c6c73bcdad8c7cda10259d3b21876a5e85511a20c613854622c7681822c10a3ea0430f48ca9a4bbffc1913153996cc676b0eefe17e9ae1825da8f303cf328fdbe2600", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010100000000000000076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da00d430000000000000012a00575458310100000000000000000000000000000000000000000000000000000000000000000009000000b25055afbe85cb2bb0563be564e2343dddd9bb9a5538549124d3b4ca650745bdd62e8c50cfcd89e7feb3243a7fdaa7571735ff07472640b39d5f00a6781be503", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010200000000000000df93cbf05a4c8d2bfcfea2eda806e07c3cdbf377aaf4b6459d41c28fa1170f9d60823b0000000000000a400000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1600746865206d6f6f6e2070756c6c732074686520736565a1ac615baae4448ac132e82f6d24d20607f78ed74863e848bbd67e8b2381e3a3acbb36153982d823aa26bf144233b74019dc1e7f5a2b6d4ac46683514b04760d", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010300000000000000bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d509360823b000000000000012a00575458310197b9d97c548e2236196372fd6700eca90ad3bf46b328a1a3a685e6af9dd194ff000f000000bb526d859b7755d61ceb45663c236e8cf57158b2d2906efabac3e52acdae0d6ad6eb723a8db97a627e349069a28ff151d577b1d1728efe3f804752b531804407", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb70010400000000000000d0ec8d4a361190e44b90b2fe96998089356e2c7a2aa1a40d3fe29d307b39a8d2c030460000000000000a4100d0070000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1700746865206d6f6f6e2070756c6c7320746865207365612eb759798dd67b85038d52ee676b37cb2eeeeb8cb8fdf21bb9133e7f8d67944c5947831a7a50c0c6f8e1b4682e8f012f73b2a909b5d544cd60f6b3ad03eba57208", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001050000000000000020740e84d1a1b867bd3e12d32562d993e5d0c91b03046c4c90d26a8740eb1b9fc03046000000000000012a005754583101bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d509301170000008db41204f7e8b760c85ec07804014d6615c5f4b83e2f7ad2fa21834f50b61c07a64522fc37c3e980b34e92cd10faa1c8ed6735f250c8661dbc332fe0864b220e", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe0100000000000000790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5404b4c0000000000000a2100b80b00000102656e1700546f646179207765206c6f6f6b2061742074696465732e3b8611e89a4a6dae4ddecb1421d580e0da739dcd908a7f0d9b46197da88d8294edffc1c784b0b35e6b2a08ef4acea31595f68d9e8dac793c9fbc0f971b53b801", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700106000000000000001009299ee564b58d9dc69792d256fdf14ca0ab95e794f48d4bcdb891708c425fa02e630000000000000a330000000000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e0900686967682074696564cd90e00db0cec7699cd795717126f0cc2fb01c71b763b8532c300804478de3da4a70ca7a6824143e6e676b74a3281b600869fdf19167693160dd1eb47de0900c", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700107000000000000007a191da118dddd36de4095877037b5c77224cf87151479f611aac68f18814503a02e63000000000000012a0057545831010000000000000000000000000000000000000000000000000000000000000000000500000059f9d31a8643c62fb4f6d5cb4ea0b718dc7bd6586f94ecd15c7d7cbba0f5e30888a944fca0e4df341381a3faa9b8cc75736920d48b68ff235bc63d7c33a24301", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb700108000000000000007273cf746584690de9b733d65146279676d2492af5513c331cb63afae24a1aada0636f0000000000000a4400c4090000022cfd2eb4f48001e56cfce21d33ee16194939fe36c966991377e956426b1e408902656e1a0068696768207469646520636f6d6573207477696365206461792ef3205c303bb9f858e6c866282d1e3bdbf3fb3e504d4b8edd24ecbf67e9dc8eb2de6c861eccda286610698ac776a96a39ee3a9fc149fcb44fb730ea14c7fb490e", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418756fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001090000000000000099f10e3b7a2633faf15ed3c2a5b5e2d5bdfddd85d1c883e6662438b2fc210e7ba0636f000000000000012a0057545831017a191da118dddd36de4095877037b5c77224cf87151479f611aac68f18814503011a000000f5249fbf0e9bb494d43f868283394c5c6c7c3221b7a19e0c74dc7055515bda5502f16e298ff9712026460e6220417d074252d8051ccc56e8a474da1919332a05", + "574556310110cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e7418787af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe020000000000000032ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c2614054890000000000000a1700d00700000102656e0d005b57617665732063726173685d963dd3dfe86c43c0849a267f171d5c4279529ac46feaca4914dfeb5c659316b71be6cede5c3a4d39e043313d2794cbcf99b9297156112998070ec1b2b7a38509" + ] + }, + "vectors": [ + { + "name": "lesson", + "note": "a human captioner, machine captions revised to final and placed by a take, a reference transcript, a quality record for each track, a description voiced on a track by a synthesized voice, a motion-captured signer bound to the human captions with an approved review, and a claim held to the 2024 statement's mean", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "accept", + "figures": { + "captions": [ + { + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "principal": "87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe", + "events": "cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357", + "sources": "30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a", + "reference": null, + "cues": 3, + "latency": { + "class": "stated", + "n": 3, + "min": "500000", + "max": "1100000", + "mean": "733333", + "p50": "600000", + "p95": "1100000" + }, + "stability": { + "revisions": 0, + "words_changed": 0, + "cues_corrected": 0 + }, + "accuracy": { + "class": "reviewed", + "first": { + "words": 10, + "errors": 0, + "substitutions": 0, + "deletions": 0, + "insertions": 0 + }, + "final": null + } + }, + { + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "principal": "56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001", + "events": "b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184", + "sources": "e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663", + "reference": "44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47", + "cues": 2, + "latency": { + "class": "capture", + "n": 2, + "min": "800000", + "max": "900000", + "mean": "850000", + "p50": "800000", + "p95": "900000" + }, + "stability": { + "revisions": 3, + "words_changed": 2, + "cues_corrected": 2 + }, + "accuracy": { + "class": "transcript", + "first": { + "words": 5, + "errors": 1, + "substitutions": 1, + "deletions": 0, + "insertions": 0 + }, + "final": { + "words": 11, + "errors": 1, + "substitutions": 0, + "deletions": 1, + "insertions": 0 + } + } + } + ], + "descriptions": [ + { + "record": "b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d", + "events": 2, + "voiced": 2, + "offsets": [ + "20", + "10" + ] + } + ], + "signings": [ + { + "record": "53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f", + "segments": 3, + "revisions": 3, + "offsets": [ + "1200000", + "1800000", + "800000" + ], + "video_floor": null + } + ], + "claims": [ + { + "record": "e048da94e1c88181d4e2660e7e200cb894e8447f10e8c27bfca08986d0ebc49a", + "overlap": [ + { + "track": 2, + "ms": 780, + "events": 1 + } + ] + } + ] + } + }, + { + "name": "reviewed", + "note": "machine captions a person reviews before they are final, a description the sink voices with a pinned model, the video of a generated signer, and a claim without latency bounds", + "stream": "reviewed", + "records": [ + "{\"events\":[{\"begin\":11000,\"duck\":{\"gain\":500,\"ramp\":150},\"end\":12200,\"id\":\"r1\",\"represents\":\"visual.nonText\",\"text\":\"Divers swim over a reef.\",\"voice\":null},{\"begin\":14000,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":15000,\"id\":\"r2\",\"represents\":\"visual.text.title\",\"text\":\"Title:\\nReef Tour & Co.\",\"voice\":null}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":\"cd01c4b4a40ca82e51f554a0d17cba629c8e828c960c3f3f396b232419bcedb2\",\"origin\":\"machine\"},\"sig\":\"72a89943dfa20e184f574c63ab0c51257da815dced6fe7eb459e53c590863ba0693958d673542a28b1427afd5b65dfaafc77305c5ae08b69cf64f96a1b05bf04\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"sink\",\"model\":\"78735f2962641be6afd75736236889f0fb4eab577c9b29d4c6e0c1de32ee7879\",\"origin\":\"machine-reviewed\",\"track\":null}}", + "{\"form\":\"video\",\"kind\":\"wai-signing\",\"lang\":\"ase\",\"model\":\"3978c5b3911274bc05898b55b7231ed8b2c333cf9cea930ad28414983baafacc\",\"origin\":\"machine\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":5000000,\"object\":\"1150c555c08fef06ef997f730bea23e3789b05712cf1a143070e53dbfbf4f33e\",\"revisions\":[\"a490a6ff974eba5f5e101a8cc6ebe555611fb6c8efc33649b38f1eb3eb157212\"],\"start\":3000000},{\"end\":8200000,\"object\":\"eaee76d570d9135f2d935ea86c72508d5bf12a857fecadb61db66eecc5bba415\",\"revisions\":[\"692449658943f2343ceed5f7acecc70c454e00d688fe027f5d882ad9ea403eaf\"],\"start\":6500000}],\"sig\":\"0a3f86fae6da5138e81e8419cc290bef1ea8669ec2d1d0b8cc970f68ecea07ff94224e846ec1919b95eba9751dcf90ebb66df9bb71c39f4239da5eaaf30bc706\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"track\":\"1a90b39e6fc282ee2e5e8a2136e1586219fca76c8e0c35ce294e452a1eca25fe\",\"video\":{\"height\":360,\"rate_den\":1,\"rate_num\":25,\"width\":640}}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":6}},\"cues\":2,\"events\":\"7f6cc36bf6e2b663a53ecdc52a30db1b4882c3d4415b4bee6034d6ab6bcf4127\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"none\",\"max\":null,\"mean\":null,\"min\":null,\"n\":0,\"p50\":null,\"p95\":null},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"ece138c262789855e0836b0000fa7ef9ed336dee529fdd438f6e0271098023d9dae2b0b17e7752b323e7e6c49f92eca5664be774c7a7f8362a434051f1a94c0d\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":null,\"stability\":{\"cues_corrected\":0,\"revisions\":1,\"words_changed\":0}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"0736700737348bf4d6d103aa22ee105f26c7bc1a468d4828027d72635c04b35529c1bb86369099d94b1d41c282d350b683d4fd4ff99f563f7383176552dfe90b\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":10000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":null,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"bdb2f87aa1b43ff97c23edc8c7adb13d28b2f161d8863fe71eba71507c62e67d\",\"service\":\"audio-description\"},{\"lang\":\"ase\",\"offset_max\":null,\"record\":\"0f40a4a72dd8d04b012920ba1d01d670f27c11e5d7f2e3404c87094830236ec4\",\"review\":null,\"service\":\"sign-language\"}]}" + ], + "outcome": "accept", + "figures": { + "captions": [ + { + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "principal": "56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001", + "events": "7f6cc36bf6e2b663a53ecdc52a30db1b4882c3d4415b4bee6034d6ab6bcf4127", + "sources": null, + "reference": null, + "cues": 2, + "latency": { + "class": "none", + "n": 0, + "min": null, + "max": null, + "mean": null, + "p50": null, + "p95": null + }, + "stability": { + "revisions": 1, + "words_changed": 0, + "cues_corrected": 0 + }, + "accuracy": { + "class": "reviewed", + "first": { + "words": 6, + "errors": 0, + "substitutions": 0, + "deletions": 0, + "insertions": 0 + }, + "final": null + } + } + ], + "descriptions": [ + { + "record": "bdb2f87aa1b43ff97c23edc8c7adb13d28b2f161d8863fe71eba71507c62e67d", + "events": 2, + "voiced": 0, + "offsets": [ + null, + null + ] + } + ], + "signings": [ + { + "record": "0f40a4a72dd8d04b012920ba1d01d670f27c11e5d7f2e3404c87094830236ec4", + "segments": 2, + "revisions": 2, + "offsets": [ + null, + null + ], + "video_floor": "meets" + } + ], + "claims": [ + { + "record": "1a76c6c5aa99b406bdeea15b90c3cd9fd84d9a50efc14799f97134753e6b6b1b", + "overlap": [ + { + "track": 1, + "ms": 1550, + "events": 2 + } + ] + } + ] + } + }, + { + "name": "unplaced", + "note": "no sources: the latency's class is none, and a claim with no latency bound holds", + "stream": "lesson", + "records": [ + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"none\",\"max\":null,\"mean\":null,\"min\":null,\"n\":0,\"p50\":null,\"p95\":null},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"1c72901275fe3cf2bb883751437676d8033639352c13c6098f6a96a000088434e22b2a46cb21071dcd3ccc89bb788d51e71e9c639f26081a69d6cf603fbd3f06\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":null,\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"8bd6493ac6c70cf1b23d9fa795e8a23e2d5f70d28d0d5935d45ba306b84edb26dc0a239acdad619cfe26a88277ecef66349be45a6b6d4c48878b2bd3f37b5306\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":null,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"}]}" + ], + "outcome": "accept", + "figures": { + "captions": [ + { + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "principal": "87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe", + "events": "cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357", + "sources": null, + "reference": null, + "cues": 3, + "latency": { + "class": "none", + "n": 0, + "min": null, + "max": null, + "mean": null, + "p50": null, + "p95": null + }, + "stability": { + "revisions": 0, + "words_changed": 0, + "cues_corrected": 0 + }, + "accuracy": { + "class": "reviewed", + "first": { + "words": 10, + "errors": 0, + "substitutions": 0, + "deletions": 0, + "insertions": 0 + }, + "final": null + } + }, + { + "room": "10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187", + "principal": "56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001", + "events": "b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184", + "sources": null, + "reference": null, + "cues": 2, + "latency": { + "class": "none", + "n": 0, + "min": null, + "max": null, + "mean": null, + "p50": null, + "p95": null + }, + "stability": { + "revisions": 3, + "words_changed": 2, + "cues_corrected": 2 + }, + "accuracy": { + "class": "self", + "first": { + "words": 5, + "errors": 1, + "substitutions": 1, + "deletions": 0, + "insertions": 0 + }, + "final": null + } + } + ], + "descriptions": [], + "signings": [], + "claims": [ + { + "record": "cd5df85648c3ca8eb0b01ca0f7427ab5f78b0a597f0d29d4045321a62455e133", + "overlap": [] + } + ] + } + }, + { + "name": "latency_misstated", + "note": "the machine captions' quality record states a mean latency one microsecond above the recomputed one", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850001\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"5e58d544d8819b85423238c00752d94ca18bee72112d2791a24fcb85551f7ceb4499d4901c9b9a63f979cc589cd2e744ae0e8f27a6ed0aa510e53f1788796002\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 7, + "reason": "figure_mismatch" + }, + { + "name": "description_late", + "note": "a description's voice starts 46 ms after the programme audio has fallen", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10746,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"a5f95c0b41efedb595b898401d359f582a9c48195b14206674c45da38874a39d5392a1c0a0213e5395293a7ae34dd86c0266b8af383c43557d6632dd0447510a\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d7871f966b0e596708743719c736dc800a8caa533682156d77ae59993c4f6ed7a632432cfe7ca8fa02d5c61b3a764770cb2ef62731fbb8756d9423564d225100\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"457b29d0d41d9e7013094e4f1b76310a8f5bad5ff41e2f745cb1c10857b4a61f\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 3, + "reason": "description_out_of_sync" + }, + { + "name": "description_early", + "note": "a description's voice starts 36 ms before the programme audio has fallen", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10664,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"9136b3dcd18354f3f1bf4604b11e2be9cf7a1605aa6814320470a7e72baf2f79e864ecb0c44e9f13ecc268f2a1d6d0700508332ca13f3fe13057524e3b715e04\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"ca0918c3e7a81e55c03d5a7dbb6f88b826badd2027a07b9b73b7388a18664e4bb8e0b10f84dcd20d62f81dc2b2e70ff23b57c1222d712805205821bf304f5b01\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"956ab6eab8ead7a3d9b0edcc8b06ee3dd2def0fa203d6f8efadae11163568d8d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 3, + "reason": "description_out_of_sync" + }, + { + "name": "description_runs_on", + "note": "a description's voice ends 46 ms after the programme audio has risen", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11746}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"18954aa7f0c78720fe3a3f73e223f54e592a00a55840939d13208e5aeb8acb72c552d2b612cbc1d5517d48f19611d94596646b88fab6198d33220df911e70509\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"85fbf6d5ae273e43ca344e6204b9d9c626344a8ccfa38b634f1a6191125c8ea5615041e5f2e5427ce4c60ff4e1f25a2881fe9e98038dd0f28e62b1d589500506\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"868df19fc5f591da792f4e46e6e3efca86ac4885834656d3eaeae48d62c88548\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 3, + "reason": "description_out_of_sync" + }, + { + "name": "sign_unknown_revision", + "note": "the signing names a caption revision the stream does not hold", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"aee1c9f15b1013cf5d795adb0a0c2059e0407ed9eeab1987916a3551bbb87048\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"f06852542ba9e3b3032558dc9bd1f23a8465701d779e7ff8401fff7129785b2274cbdc3071065260a34278c03e69aff4cf8070a33a8948d4e81a5eab69ae450a\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"ca190bf95e806b3fb4da59eb2e8a8dcd142f78f661de7c124c42a1ce9923c087662e1f989272b28ee25c34b6b51674ce1b3291ba01a82d486a184a5efd264a0e\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"0d2ff2511795e708a5f023205914763fb274fac67cdbde565c7ae4485abb0310\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"f1ee797728d3a7ecf2fb34185062c454385dd608fc2109bfd53f02e3b7df5585adea0e06d852ad0ae789c2b4597c2fd34119de7b68447695c47a55fc3956c708\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"0d2ff2511795e708a5f023205914763fb274fac67cdbde565c7ae4485abb0310\",\"review\":\"46cac835945ebf617ee04f8fb18863786f5fa617da5068da233b7da9dd5de755\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 4, + "reason": "sign_revision_unknown" + }, + { + "name": "claim_missing_track", + "note": "the claim declares a description the verifier does not hold", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 7, + "reason": "track_missing" + }, + { + "name": "duplicate_member", + "note": "the review names its verdict twice", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\",\"verdict\":\"rejected\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 5, + "reason": "record_malformed" + }, + { + "name": "negative_number", + "note": "a source's start is a negative number", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"9ee48ee893f3c47b74261b71b68496f65c9d472632a7480144f5894c80833b102892d848b6514fe6be56766eccd9bc0504070dd31f85d4f35bba2dd61d57840f\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":-1,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"2000000\",\"mean\":\"1200000\",\"min\":\"500000\",\"n\":3,\"p50\":\"1100000\",\"p95\":\"2000000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"9f85cfbb36b7ee6019ac978132b69efce2077aa5dddbc286bcb7086c1d32b5a70f08d56610df3edd590b6beff9d360f2546903af6403a0fc6d8ebac6f662b508\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"b09c60ffb5dbe46adead14021bececbba9948952fe06dfbf67eb436115e603e4\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 0, + "reason": "record_malformed" + }, + { + "name": "flipped_signature", + "note": "a bit of the review's signature is flipped", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a0300\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 5, + "reason": "bad_signature" + }, + { + "name": "weak_key", + "note": "the review's key is the identity point", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"0100000000000000000000000000000000000000000000000000000000000000\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 5, + "reason": "bad_key" + }, + { + "name": "wrong_room", + "note": "the captioner's sources name another room", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"6b47d9c6e7d43da4681779a7dcaca1f8071988b86bb5f2d40ae006ee9d264e96\",\"sig\":\"72ee1a317a3f43951d20198b4058451be95a7869d9b920363b8cf893ab2e2fe9a7b95a57df4b3d35066913b5aa83f2ff570a17ad3ad4131593a43a053620cb03\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 0, + "reason": "wrong_room" + }, + { + "name": "second_sources", + "note": "a second sources record for the machine captions", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"ceba40704a21eee4046016cd4ddce7e2b639c3c7274edba0c3c3f6685e02ad8c8d566f1a9241d2caeb88d61e80bf4cf84e4ef9a5fe65df7e8e768fa00abd5a0b\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 2, + "reason": "record_conflict" + }, + { + "name": "source_not_a_head", + "note": "a source names a later revision, not a cue's first", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"072b359ad3dee863bd51c748ad30770cd0fd3830dd69015878e7d9374653ef00b41d78c78d277ea0c141f34f0e50c3b1f909707188d548a97437997762b8ed00\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"bb845bf1e3cb29c966bfa99397e0acf6857e67d70b53d173103279c8853d5093\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 1, + "reason": "source_unknown" + }, + { + "name": "source_unknown_take", + "note": "a source names a take with no opening commitment", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"b633411e2df77a74a9eaa51a19ef0a8e294636c5faf0d9a1b7f64998986bce00d4ed1fec59b8f0510d9404a813ab0adbed5e13317779a1c0561dca9f3d287d00\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"3e87570db5d1c46a19e111a05e1a4bf845a59396521d23ab5b06750c8682c9e5\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"3e87570db5d1c46a19e111a05e1a4bf845a59396521d23ab5b06750c8682c9e5\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 1, + "reason": "source_take_unknown" + }, + { + "name": "reference_spaces", + "note": "a reference text holds two spaces in a row", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"6794a6a657c4cd5f747c12d106d9b568f9bf4552cccaeccf8a14d9e46c6d15220277d350635dcdb5f9e975b842b4a70b465a7b3e9817ed0f3d5402863a504b0b\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 2, + "reason": "text_not_in_subset" + }, + { + "name": "reference_unknown_cue", + "note": "the reference names a cue the stream does not hold", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"},{\"cue\":\"2be0f4ab253fea69bf3115cf70cb2c8851b49b45e6896d4d4aa56d30265ba6b0\",\"text\":\"Spring tides.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"238bc1a00e5d62ddc2434217f6987d915054d36ddb2a8ba8e3e17e389f3b675376b760be634a493c37c9534cbf6aed4c013b3507fb77c0dd138c2b719eba100e\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 2, + "reason": "reference_unknown" + }, + { + "name": "reference_missing_cue", + "note": "the reference leaves a cue out", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a4c1f33146ae0c11e92d40feb4aedb85048411d6c4d31ffa2b9f164eaaf2b2a228df8706b952707dc120be0a51ea7c3f385749f81f9570f450474e8b3b19650f\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 2, + "reason": "reference_incomplete" + }, + { + "name": "quality_without_reference", + "note": "the quality record names no reference while the track has one", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"17e64f6094a34eef004c1c2a7772b010db0a5b02d859546a7a048c7fde0da353fca3024e88cc4fe726e90ffb66448777da60e9fb5118b81b2deb952ad789f50a\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 7, + "reason": "figure_inputs_mismatch" + }, + { + "name": "description_overlap", + "note": "a description begins before the one before it ends", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":11800,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":null}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"177a6a8dac4444eadd303f50298e58471461a2ef978db6c22a721356a57baeecc71b0b78912faf734b39f7ce27e374451b0d925434d07d347f093a5e6bac5e08\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"6104a25b4ba7a28eba50b777a50c470805d542b032d3956103b7d80dfd30be32e97c34590cf717887301935cad011558b6dfbb0d6c140eb71b6a30459023b103\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"24644d506ab9a91d6d3fdb9bbd1475d52361ed3bca1ea46d3ca67df29fb0eeb9\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 3, + "reason": "description_malformed" + }, + { + "name": "signing_empty_segment", + "note": "a signing segment ends where it starts", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":2600000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"9b777b9c51fed6e95765e75fba9a3049ec232a312b2cd5e95db33257b62c70512414e3164cdaa49aae8092dac78ba0a8bb413903270f155fc582866a8c80dd0a\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"c43a20bd161be9d4c8699f9f6e426e209b68f59075b9efe54d156c570b1434ddf7c7308b6d7db6c3597817163b5677469b3f693e257d45fa086d6d4af7069b0f\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"308ccd08e1263d3c01278e295e9a3c343d8e3203bc3b905530301c3113b19ff1\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"48b4ec61c30a15aee5f48962ed187d75ffcffbb9a7c585f865947976d5f5eaa5b3e3c57837eb0c3308bed0c0e892ef35cf728374da61099d46302d549cc06802\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"308ccd08e1263d3c01278e295e9a3c343d8e3203bc3b905530301c3113b19ff1\",\"review\":\"2d349841c29b89e2b76a9032bb43a25e323d03b38ba0fb41263a6ff7b223aa1c\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 4, + "reason": "signing_malformed" + }, + { + "name": "review_unknown_signing", + "note": "the review names a signing record the verifier does not hold", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"a4e83912a560e1f31cde01cb814ebab9e78580def02f65f2fb30cb4e0104e2cb3686cdff6d3ceeb84898859710e2d8992847c1b687960d58cc2e9adaeff7420c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"a6f06406c35a53d5420b662ed936f55c86b77fd65e29f7b83c261888178368a5\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"43d6244af103b767cb29e60011322125c90b8b37470d22d4e2f8e6e4b8f546e6fd5e9d6050b2f1454cbc0d686f22789962d2016855bbbfde28f89403f7430d08\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"a126e627cd489341173c68a6c7ec1a9c88c98f9784a1bd58154b55c1a6e1fd7a\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 5, + "reason": "review_subject_unknown" + }, + { + "name": "claim_empty_session", + "note": "the claim's session ends where it starts", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":12000000,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"3e119d17fcf8645af9c5b739719db1e6b9a8a1317c9b161c900c93b79adb0afac7f65a4ecd27c36c2a012c9fc53ac7332bcea9a974632171b3090ff29c8d6d09\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "claim_malformed" + }, + { + "name": "description_unvoiced", + "note": "a description on a voicing track has an event the track does not voice", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":null}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"a644f88514d6c10cb6639a2c286cde20240a346b96a430afde898831f48906d3913541ab90ae7ffbed1fc142aaa5de46343677030249d71ebe98a6c35cd37303\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"b039268fa23faeafc57e70fc27397aa89f072d76a758149c9254cc61debf8f884c6102b16a27e585970b328cbb4b479257931138d987092718c4063bd81b1400\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"0cefb80c7eef1cab869e80ea6dc9e7be16844097fadafc5f93a494e748cc7753\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "track_incomplete" + }, + { + "name": "claim_wrong_language", + "note": "the claim declares the description in another language", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"26db8ddb8925181bf4cb332c4b2458798b55523e44c7e1564ba76be2749b490e6ee2853d052b109f001f953538e93fce11329a8bd687748be3016d6fdf274a0c\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"fr\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "track_mismatch" + }, + { + "name": "latency_above_bound", + "note": "the claim holds the machine captions to a latency of at most 850 ms; one cue's is 900 ms", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c5a863a3b728fc62a36d0b1cfc31c5c95ad26b79f4a30b5b992fc22026b907807b8807d15212d02503dea6efb0d26608caa6b6dff630bb2c41383b34bb840007\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":850000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "out_of_sync" + }, + { + "name": "review_not_given", + "note": "the claim names a review the verifier does not hold", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 7, + "reason": "review_missing" + }, + { + "name": "review_of_another", + "note": "the claim's review approves another signing record", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"679d1fdd222154d622a0a13e11e84bf479f4b50399f734d0bd248664d563051fd8f775cbc4f707eb2dc4c09944fd1e0754ec1512c0bfcaae5ef6de2ab55e450e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"e4a2c896d5f6bd3a47afe3a988de6436631102580dab44886c777ccec8316b5b\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"57048e8414aa12fb31822b762ea16cba1a8c3935c55f5f06f17077adebeb340f40d43292bb6e01e5d1de16719954e21e37889b2ede71437b2ce5f621d9e6c80e\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"28551a2c95c28e080f44bd223ee11195a8e80eb32682fb4ff3ee36675141f84f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"032903a43d5b210a14d07c5bf75ece88715be4b11b90acb2ac5facf1c53df21c6ac585d621c5c1dfabad7aab6f08fa555a9e7f44c73703d30ed9731a1112de0a\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"7d0727df54cb277642e56bb195504c2e5df41f888ec00bc9b624294b31c67d7c\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 9, + "reason": "review_mismatch" + }, + { + "name": "review_rejected", + "note": "the claim's review rejects the signing", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":\"4f539e300b399f5a00d446ad4d065e052ae1741e9e6a5a1dfdd5e2a533e8a8d9\",\"scope\":\"translation\",\"sig\":\"0eb83042836bade4157fc36c6f1ef5cebd13406620e7fff6a8afc338d8422b05808445c2099759d185a3519e011f2df1c8e2a685a19d204abbcd06ff35ff260e\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"rejected\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4ccd21554b8dcd4011ac475f5e214691052a5288fe51743ec0968246b51572ea17efeef2b815a5475713cfe1a890d0bd37f7c36bb405c53594bbbd247e9f4a02\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"de85ee615ef94af33c5ebeb5e23b6e1b1b6a49d45f9193804c3b5a7f6285ce06\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "review_rejected" + }, + { + "name": "captions_of_no_one", + "note": "the claim declares captions by a principal with none", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"5f9940df8026b2583ef03bdc4a1ddef43f6d390534531eb09e7384f0591cd990b405104e8e3f94b9a8a5a27df6a1512dc94c8fbe61d977414e65a1367c193a0a\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"2d3a54bbd6d60dc802d225efd0ac4fc7dc4f65825bbce115cd9da3b9b84f5b20\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "track_missing" + }, + { + "name": "sign_offset_above_bound", + "note": "the claim holds the signing to 1.5 s behind the speech; one segment is 1.8 s behind", + "stream": "lesson", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"7be1b355c143d8b9a3f0b1dcd0cd3fa2234b270e2aeef7cb5848720299d37ea482e2aad404e2e1e8d50b0b2aa4eeefb3d892cdc45a409e0d175821db2cc5c206\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":1500000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 8, + "reason": "out_of_sync" + }, + { + "name": "chain_broken", + "note": "the captioner's second caption names a prev that is not its first's", + "stream": "chain_broken", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "events", + "index": 9, + "reason": "chain_broken" + }, + { + "name": "supersede_unknown", + "note": "a machine revision supersedes a revision no one wrote", + "stream": "supersede_unknown", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "events", + "index": 6, + "reason": "supersede_unknown" + }, + { + "name": "undelivered_revisions", + "note": "the machine captions' second cue's partial and its annotation are not delivered, so the track is not whole", + "stream": "gap", + "records": [ + "{\"kind\":\"wai-caption-sources\",\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"226fc5e8e29590ed077810a146eddf5d12310ece24fe93dd4839b6820f25f1a60f18e29b8310c83316689abe8209dae456706ec1f1763e6abcb6e96383664306\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"room\",\"cue\":\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\",\"end\":1900000,\"start\":1400000,\"take\":null},{\"basis\":\"room\",\"cue\":\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\",\"end\":4800000,\"start\":3900000,\"take\":null},{\"basis\":\"room\",\"cue\":\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\",\"end\":8900000,\"start\":8500000,\"take\":null}]}", + "{\"kind\":\"wai-caption-sources\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"956e98ff2f08463eb526ec825eb4dcc233cdc2129d78ee5e30db933f0f2a585a764e63abee322387ef66ca30c8d34bc931c773322a6d4f7ee15b8b84dd98a50d\",\"signer_pubkey\":\"263a17b821ed45337377e8de5823caf19eed3894af1810899e1c43a278f75956\",\"sources\":[{\"basis\":\"take\",\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"end\":503400000,\"start\":501400000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"},{\"basis\":\"take\",\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"end\":506000000,\"start\":504600000,\"take\":\"494757238712c001b425851448d08b079fdf5c4a9c9a019dbc2ada68e878ba10\"}]}", + "{\"entries\":[{\"cue\":\"076b4b47442da680e3b4d0e3624d8742498bfc5cff300d23848659b2530bc7da\",\"text\":\"The moon pulls the sea.\"},{\"cue\":\"bc2a067467b1329eaf736b48a942af914befd65e7a3ca628e8dc4a04415b19ca\",\"text\":\"High tide comes twice a day.\"}],\"kind\":\"wai-caption-reference\",\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"4130281b58009afdee214515d9606f73f568b9c5c7d5b39ed0acba4aa38ab90cd76fded1f72990c8d01c68efae1018cfa0f56145874af37a367f67911982060a\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\"}", + "{\"events\":[{\"begin\":10500,\"duck\":{\"gain\":400,\"ramp\":200},\"end\":11900,\"id\":\"d1\",\"represents\":\"visual.nonText\",\"text\":\"A teacher stands beside a tide chart.\",\"voice\":{\"begin\":10720,\"end\":11690}},{\"begin\":15200,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":16000,\"id\":\"d2\",\"represents\":\"visual.text\",\"text\":\"On the board: HIGH TIDE 06:10.\",\"voice\":{\"begin\":15210,\"end\":15990}}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":null,\"origin\":\"human\"},\"sig\":\"445c80f37f10f4de0b8c815d2a6e46b1e1e2499eaf1600367971d50a0a43cb64dc98a49539f7f1364db88b119ff06e4c0a15a84a5ed369a07e9ad3e61476eb0b\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"track\",\"model\":\"1c1172ff98d71af4286f2a67fa50ccf58dedcfd642a1974ebbcc1cbaff53848f\",\"origin\":\"machine\",\"track\":\"8668cfc759b399873759f8643983c4e13aaf4e2a1f97dfc1a66e7b9bd1e06944\"}}", + "{\"form\":\"pose\",\"kind\":\"wai-signing\",\"lang\":\"bfi\",\"model\":null,\"origin\":\"human\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":4800000,\"object\":\"06670f00ecd484f864efc706e79f95175d86c1eb7aee4c0036243215086773a4\",\"revisions\":[\"790758c4ca08722f78232baa6f0c94a25607e2f816d5e741c34fcc4cb99b07a5\"],\"start\":2600000},{\"end\":8800000,\"object\":\"a9b239654f3097da5c2a105e33d35ad8627bbf9f7579a180320093e465fb9486\",\"revisions\":[\"32ed134d909d0bc3c0b6b1995e39ded65a4969d854e31206f8e584028306c261\"],\"start\":5700000},{\"end\":11000000,\"object\":\"493f42155eaed4c9da58726a2ab06a35227f5859468548d5ddf69b5ac87bffc0\",\"revisions\":[\"eef0936bdd7701cd5e44e0bc2329e8aa993e87dc893ecbbbedfc4c4417c69bec\"],\"start\":9300000}],\"sig\":\"26b39631b9c784551a86ebd0906cc9536bbd7089d4ba2aabd66613d15d999d4969ff56fe5556f480c52b8d8999ed82da55da05fa364a6348b754ebfa15afd90e\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"track\":\"eb74114d751c01d485f367cd3bf095d9123c617429b4cbac890c359a886229f7\",\"video\":null}", + "{\"kind\":\"wai-signing-review\",\"notes\":null,\"scope\":\"translation\",\"sig\":\"6c8dbf798896491d68cc6e95bf04d75cd6736b84ce8431aafa1358408608ccb60fa87185c16518b61c0d3c6cf8cdd9a3a0e9601c351fa649491089a3bc9a030c\",\"signer_pubkey\":\"e5ce9e9b473a9db90a3a9ca1a0490575357862fad16166b943a43ecf09c4a4e9\",\"signing\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"verdict\":\"approved\"}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":10}},\"cues\":3,\"events\":\"cfc6f5aecd3992ca9d94752cf34cb032f86ad6e8433470e07afa832f4bfd2357\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"stated\",\"max\":\"1100000\",\"mean\":\"733333\",\"min\":\"500000\",\"n\":3,\"p50\":\"600000\",\"p95\":\"1100000\"},\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"c746ead7a1904f7da5efb9d9a7b9d29bc9b5ed29a6e08800e3b621ac83ad6bd01345b5d4df301d0491dda9f327bfc1e0f939df04c3de6c050c6992004c6fd60e\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"30a32a63652daabd1018a056b145d9a0ec578b77f1479d79b06cc7412163070a\",\"stability\":{\"cues_corrected\":0,\"revisions\":0,\"words_changed\":0}}", + "{\"accuracy\":{\"class\":\"transcript\",\"final\":{\"deletions\":1,\"errors\":1,\"insertions\":0,\"substitutions\":0,\"words\":11},\"first\":{\"deletions\":0,\"errors\":1,\"insertions\":0,\"substitutions\":1,\"words\":5}},\"cues\":2,\"events\":\"b2cc0d56e41d4706d02430eab3f36dafab1fe432d7416d27c004de7be66f1184\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"capture\",\"max\":\"900000\",\"mean\":\"850000\",\"min\":\"800000\",\"n\":2,\"p50\":\"800000\",\"p95\":\"900000\"},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":\"44ad2474eaf102630f6a44ce80572fbc56248c71c23e7b87e489e74b0de97a47\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"a880ba855c5a3b22c9c767fcf27cbea6ee72432eda8ea0e9ba5539bd9eb7d7a015954963df6cf381379af10cd624ea90b6305d2062534b55910921c750c45203\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":\"e8aefd66ea08c8cf76c46960b622adc2785a3062ad6c7fd1fecaa5d00d662663\",\"stability\":{\"cues_corrected\":2,\"revisions\":3,\"words_changed\":2}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"d486fff83b14dd03226fa6778f3b0195e6369eb4b3d5e9fdcd56a7a678918964efc8a81b144ab42ab077beb73027ceffdda61b717211d536433e7be48ad39b03\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":12000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"87af91802eaf620fff36e32f2e4249dec47917281f908fb97e36d6105e586fbe\",\"service\":\"captions\"},{\"lang\":\"en\",\"latency_max\":3000000,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"b46e9700931e78208bd4c0916e59a0335527c33a436c4cf93e382bb0f53a912d\",\"service\":\"audio-description\"},{\"lang\":\"bfi\",\"offset_max\":4000000,\"record\":\"53ffaabaabeadbcbf550514dc7da80a624f7c3e4a5898d4e8984ab980af6907f\",\"review\":\"12005f72b3c75501e408758fc1317ca1a90f7f7570d72db9b21ef3aa3ee32073\",\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 1, + "reason": "stream_incomplete" + }, + { + "name": "sign_partial", + "note": "the signing is bound to a partial a later revision superseded", + "stream": "reviewed", + "records": [ + "{\"events\":[{\"begin\":11000,\"duck\":{\"gain\":500,\"ramp\":150},\"end\":12200,\"id\":\"r1\",\"represents\":\"visual.nonText\",\"text\":\"Divers swim over a reef.\",\"voice\":null},{\"begin\":14000,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":15000,\"id\":\"r2\",\"represents\":\"visual.text.title\",\"text\":\"Title:\\nReef Tour & Co.\",\"voice\":null}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":\"cd01c4b4a40ca82e51f554a0d17cba629c8e828c960c3f3f396b232419bcedb2\",\"origin\":\"machine\"},\"sig\":\"72a89943dfa20e184f574c63ab0c51257da815dced6fe7eb459e53c590863ba0693958d673542a28b1427afd5b65dfaafc77305c5ae08b69cf64f96a1b05bf04\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"sink\",\"model\":\"78735f2962641be6afd75736236889f0fb4eab577c9b29d4c6e0c1de32ee7879\",\"origin\":\"machine-reviewed\",\"track\":null}}", + "{\"form\":\"video\",\"kind\":\"wai-signing\",\"lang\":\"ase\",\"model\":\"3978c5b3911274bc05898b55b7231ed8b2c333cf9cea930ad28414983baafacc\",\"origin\":\"machine\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":5000000,\"object\":\"1150c555c08fef06ef997f730bea23e3789b05712cf1a143070e53dbfbf4f33e\",\"revisions\":[\"c718cf034cb47537cddb3e30febd1dc7c1e5d44d818e818e9067793f15e85ab9\"],\"start\":3000000},{\"end\":8200000,\"object\":\"eaee76d570d9135f2d935ea86c72508d5bf12a857fecadb61db66eecc5bba415\",\"revisions\":[\"692449658943f2343ceed5f7acecc70c454e00d688fe027f5d882ad9ea403eaf\"],\"start\":6500000}],\"sig\":\"bd605aacc77d89130a74425f90af1dc816a7b36ecd0221b129995eeb390658c0cb3eefb43e6925df2907c8f4a016b4f353bc188840a87f4849de4ac263d28d00\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"track\":\"1a90b39e6fc282ee2e5e8a2136e1586219fca76c8e0c35ce294e452a1eca25fe\",\"video\":{\"height\":360,\"rate_den\":1,\"rate_num\":25,\"width\":640}}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":6}},\"cues\":2,\"events\":\"7f6cc36bf6e2b663a53ecdc52a30db1b4882c3d4415b4bee6034d6ab6bcf4127\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"none\",\"max\":null,\"mean\":null,\"min\":null,\"n\":0,\"p50\":null,\"p95\":null},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"ece138c262789855e0836b0000fa7ef9ed336dee529fdd438f6e0271098023d9dae2b0b17e7752b323e7e6c49f92eca5664be774c7a7f8362a434051f1a94c0d\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":null,\"stability\":{\"cues_corrected\":0,\"revisions\":1,\"words_changed\":0}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"6d4f8c60647ba7e6555060b365bf3d5e8da0bbece085d596f48daf904dc0d25b85a0a2fbf429fea7323637bc94f36cb64c36d585dcd46af465a615634d9b540a\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":10000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":null,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"bdb2f87aa1b43ff97c23edc8c7adb13d28b2f161d8863fe71eba71507c62e67d\",\"service\":\"audio-description\"},{\"lang\":\"ase\",\"offset_max\":null,\"record\":\"709b72ba2870096354b9a52500944052a13407a77ea3c9432fd46030eb718fd9\",\"review\":null,\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 1, + "reason": "sign_revision_not_final" + }, + { + "name": "latency_unmeasured", + "note": "the claim bounds the latency of captions no sources record places", + "stream": "reviewed", + "records": [ + "{\"events\":[{\"begin\":11000,\"duck\":{\"gain\":500,\"ramp\":150},\"end\":12200,\"id\":\"r1\",\"represents\":\"visual.nonText\",\"text\":\"Divers swim over a reef.\",\"voice\":null},{\"begin\":14000,\"duck\":{\"gain\":1000,\"ramp\":0},\"end\":15000,\"id\":\"r2\",\"represents\":\"visual.text.title\",\"text\":\"Title:\\nReef Tour & Co.\",\"voice\":null}],\"kind\":\"wai-description\",\"lang\":\"en\",\"script\":{\"model\":\"cd01c4b4a40ca82e51f554a0d17cba629c8e828c960c3f3f396b232419bcedb2\",\"origin\":\"machine\"},\"sig\":\"72a89943dfa20e184f574c63ab0c51257da815dced6fe7eb459e53c590863ba0693958d673542a28b1427afd5b65dfaafc77305c5ae08b69cf64f96a1b05bf04\",\"signer_pubkey\":\"b247ef25a66372d4485c83c4f66e508d15550dfcb04ea6d2e8e50a6dd10b8444\",\"voicing\":{\"form\":\"sink\",\"model\":\"78735f2962641be6afd75736236889f0fb4eab577c9b29d4c6e0c1de32ee7879\",\"origin\":\"machine-reviewed\",\"track\":null}}", + "{\"form\":\"video\",\"kind\":\"wai-signing\",\"lang\":\"ase\",\"model\":\"3978c5b3911274bc05898b55b7231ed8b2c333cf9cea930ad28414983baafacc\",\"origin\":\"machine\",\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"segments\":[{\"end\":5000000,\"object\":\"1150c555c08fef06ef997f730bea23e3789b05712cf1a143070e53dbfbf4f33e\",\"revisions\":[\"a490a6ff974eba5f5e101a8cc6ebe555611fb6c8efc33649b38f1eb3eb157212\"],\"start\":3000000},{\"end\":8200000,\"object\":\"eaee76d570d9135f2d935ea86c72508d5bf12a857fecadb61db66eecc5bba415\",\"revisions\":[\"692449658943f2343ceed5f7acecc70c454e00d688fe027f5d882ad9ea403eaf\"],\"start\":6500000}],\"sig\":\"0a3f86fae6da5138e81e8419cc290bef1ea8669ec2d1d0b8cc970f68ecea07ff94224e846ec1919b95eba9751dcf90ebb66df9bb71c39f4239da5eaaf30bc706\",\"signer_pubkey\":\"95c12b988c8cf5df861c02b7aba75dd996d90348aaeaeef09e8966fd7d1a972f\",\"source\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"track\":\"1a90b39e6fc282ee2e5e8a2136e1586219fca76c8e0c35ce294e452a1eca25fe\",\"video\":{\"height\":360,\"rate_den\":1,\"rate_num\":25,\"width\":640}}", + "{\"accuracy\":{\"class\":\"reviewed\",\"final\":null,\"first\":{\"deletions\":0,\"errors\":0,\"insertions\":0,\"substitutions\":0,\"words\":6}},\"cues\":2,\"events\":\"7f6cc36bf6e2b663a53ecdc52a30db1b4882c3d4415b4bee6034d6ab6bcf4127\",\"kind\":\"wai-caption-quality\",\"latency\":{\"class\":\"none\",\"max\":null,\"mean\":null,\"min\":null,\"n\":0,\"p50\":null,\"p95\":null},\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"reference\":null,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"ece138c262789855e0836b0000fa7ef9ed336dee529fdd438f6e0271098023d9dae2b0b17e7752b323e7e6c49f92eca5664be774c7a7f8362a434051f1a94c0d\",\"signer_pubkey\":\"52c5abb2a1bb06da81afd4243f30a990c5c32071c1d3b405439945356b2ec130\",\"sources\":null,\"stability\":{\"cues_corrected\":0,\"revisions\":1,\"words_changed\":0}}", + "{\"from\":0,\"kind\":\"wai-access-completeness\",\"pt0\":10000,\"room\":\"10cad9729a9f0c2b69c529091ff2989cfe519ebf468e9b3017b55116a7e74187\",\"sig\":\"731fd8e154657e55a158253c20b042af4702eb2ca4e9e801c7d195306474391207c87a3dc0207ccdb6da55de873fb5f7cb25be8ec343c55b73badc4a1ccf150d\",\"signer_pubkey\":\"fc940ff52466a0f214c46f7f204e8700eed7266c7ac1d1b113ae06393b16db23\",\"to\":10000000,\"tracks\":[{\"lang\":\"en\",\"latency_max\":null,\"latency_mean_max\":4500000,\"principal\":\"56fd6f25954aef31b842f11382e706ba52e92606b196afd58855db637edb7001\",\"service\":\"captions\"},{\"lang\":\"en\",\"record\":\"bdb2f87aa1b43ff97c23edc8c7adb13d28b2f161d8863fe71eba71507c62e67d\",\"service\":\"audio-description\"},{\"lang\":\"ase\",\"offset_max\":null,\"record\":\"0f40a4a72dd8d04b012920ba1d01d670f27c11e5d7f2e3404c87094830236ec4\",\"review\":null,\"service\":\"sign-language\"}]}" + ], + "outcome": "refuse", + "at": "record", + "index": 3, + "reason": "sync_unmeasured" + } + ], + "documents": [ + { + "vector": "lesson", + "record": 3, + "uri": "https://media.example/lesson/description.mp4", + "type": "audio/mp4", + "file": "lesson.dapt.ttml" + }, + { + "vector": "reviewed", + "record": 0, + "uri": null, + "type": null, + "file": "reviewed.dapt.ttml" + }, + { + "vector": "lesson", + "record": 3, + "uri": "https://media.example/a\"b", + "type": "audio/mp4", + "reason": "parameter_malformed" + }, + { + "vector": "lesson", + "record": 3, + "uri": "https://media.example/lesson/description.mp4", + "type": "", + "reason": "parameter_malformed" + } + ] +} diff --git a/wai/wai-rs/Cargo.toml b/wai/wai-rs/Cargo.toml index 4eacec8be..2a3494534 100644 --- a/wai/wai-rs/Cargo.toml +++ b/wai/wai-rs/Cargo.toml @@ -281,6 +281,14 @@ live_provenance = ["live_watermark", "timed_text"] # machine-generation disclosure carried through each. No new dependency: the XML is # written by hand. timed_text = ["live_events"] +# Access services (extensions/access-services): `wai.access.services` — a caption track's +# latency, stability and accuracy computed from its signed revisions (sources placed on the +# room clock through a take's opening commitment, a reference transcript, word alignment in +# integer arithmetic) and the check of a stated figure; audio description (script, ducking, +# voicing, synchronisation to DAPT §5.5's bounds) and its DAPT document, written by hand; +# sign language as a pose or video track bound to final caption revisions, with a review; and +# the completeness claim of a room session. SHA-256, Ed25519 and JCS only; no new dependency. +access_services = ["timed_text", "capture_take"] # Object-based spatial audio (extensions/spatial-audio): the deterministic # Fx mixdown engine. Reuses the world `Fx` floor + blake3; no codec/ML deps # (sources arrive as decoded mono PCM — decoding the wai.audio.* assets is @@ -748,6 +756,11 @@ name = "wai_timed_text_vectors" path = "src/bin/wai_timed_text_vectors.rs" required-features = ["timed_text"] +[[bin]] +name = "wai_access_services_vectors" +path = "src/bin/wai_access_services_vectors.rs" +required-features = ["access_services"] + [[bin]] name = "wai_world_meter" path = "src/bin/wai_world_meter.rs" @@ -1453,6 +1466,11 @@ name = "timed_text" path = "tests/timed_text.rs" required-features = ["timed_text"] +[[test]] +name = "access_services" +path = "tests/access_services.rs" +required-features = ["access_services"] + [[test]] name = "world_replay" path = "tests/world_replay.rs" diff --git a/wai/wai-rs/src/access_services.rs b/wai/wai-rs/src/access_services.rs new file mode 100644 index 000000000..9046eaa11 --- /dev/null +++ b/wai/wai-rs/src/access_services.rs @@ -0,0 +1,1483 @@ +//! Access services — `wai.access.services` ([extensions/access-services.md]). +//! +//! Captions are timed-text's, unchanged; this module adds figures about them that any +//! verifier recomputes from the signed revisions, and the two other access services, audio +//! description and sign language, with a claim that a room session carried each complete +//! and in sync. +//! +//! What this module implements, by section of the extension: +//! +//! - §2: the records, read as JSON with a claim's limits, their shape, their strict +//! Ed25519 signature over the JCS form, and their record ids; +//! - §3: words, and the alignment of two lists of words with its fixed walk back; +//! - §4: a caption track's sources (placed on the room clock through a take's opening +//! commitment), its reference transcript, and its latency, stability and accuracy, and the +//! check of a stated figure; +//! - §5: the description record, its rules and synchronisation, its overlap with dialogue, +//! and its DAPT document; +//! - §6: the signing record, its binding to final caption revisions, its figures, and a +//! review; +//! - §7: the completeness claim; +//! - §8: verification of a room's events and records. +//! +//! The corpus `live-conformance/access/` is written by [`corpus::generate`] and checked by +//! [`corpus::verify`], and by `live-conformance/access_services_verify.py`, which shares no +//! code with this module. +//! +//! [extensions/access-services.md]: ../../extensions/access-services.md + +use std::collections::{BTreeMap, BTreeSet}; + +use ed25519_dalek::{Signer, SigningKey}; +use serde_json::{json, Map, Value}; +use sha2::{Digest, Sha256}; + +use crate::capture_take::{take_id, Commit}; +use crate::jcs::{jcs, MAX_INTEGER}; +use crate::live_events::{self as le, Command, Payload}; +use crate::timed_text::{self as tt, CaptionVerifier, Revision}; + +pub mod corpus; + +/// The prefix of every signature's message (§2). +pub const SIGN_DOMAIN: &[u8] = b"wai:access\x01"; +/// The namespace of the DAPT document's foreign attributes (§5.5). +pub const XML_NS: &str = "tag:transaction.science,2026:wai/access"; +/// DAPT's content profile designator (DAPT §5.6.1). +pub const DAPT_CONTENT: &str = "http://www.w3.org/ns/ttml/profile/dapt1.0/content"; +/// The latest a media time may be, in milliseconds (timed-text §3.1). +pub const MAX_MS: u64 = tt::MAX_MS; +/// DAPT §5.5: audio may change this many milliseconds before the time a document states. +pub const EARLY_MS: u64 = 35; +/// DAPT §5.5: and this many after it. +pub const LATE_MS: u64 = 45; + +/// The `kind` of each record (§4.2 to §7.1). +pub mod kinds { + pub const SOURCES: &str = "wai-caption-sources"; + pub const REFERENCE: &str = "wai-caption-reference"; + pub const QUALITY: &str = "wai-caption-quality"; + pub const DESCRIPTION: &str = "wai-description"; + pub const SIGNING: &str = "wai-signing"; + pub const REVIEW: &str = "wai-signing-review"; + pub const CLAIM: &str = "wai-access-completeness"; +} + +/// A refusal of §10. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Reason { + RecordMalformed, + BadKey, + BadSignature, + WrongRoom, + RecordConflict, + SourceUnknown, + SourceTakeUnknown, + TextNotInSubset, + ReferenceUnknown, + ReferenceIncomplete, + StreamIncomplete, + FigureInputsMismatch, + FigureMismatch, + DescriptionMalformed, + DescriptionOutOfSync, + ParameterMalformed, + SigningMalformed, + SignRevisionUnknown, + SignRevisionNotFinal, + ReviewSubjectUnknown, + ClaimMalformed, + TrackMissing, + TrackIncomplete, + TrackMismatch, + SyncUnmeasured, + OutOfSync, + ReviewMissing, + ReviewMismatch, + ReviewRejected, +} + +impl Reason { + /// Every reason, in the order §10 lists them. + pub const ALL: [Reason; 29] = [ + Reason::RecordMalformed, + Reason::BadKey, + Reason::BadSignature, + Reason::WrongRoom, + Reason::RecordConflict, + Reason::SourceUnknown, + Reason::SourceTakeUnknown, + Reason::TextNotInSubset, + Reason::ReferenceUnknown, + Reason::ReferenceIncomplete, + Reason::StreamIncomplete, + Reason::FigureInputsMismatch, + Reason::FigureMismatch, + Reason::DescriptionMalformed, + Reason::DescriptionOutOfSync, + Reason::ParameterMalformed, + Reason::SigningMalformed, + Reason::SignRevisionUnknown, + Reason::SignRevisionNotFinal, + Reason::ReviewSubjectUnknown, + Reason::ClaimMalformed, + Reason::TrackMissing, + Reason::TrackIncomplete, + Reason::TrackMismatch, + Reason::SyncUnmeasured, + Reason::OutOfSync, + Reason::ReviewMissing, + Reason::ReviewMismatch, + Reason::ReviewRejected, + ]; + + /// Its code, as §10 writes it. + pub fn code(self) -> &'static str { + match self { + Reason::RecordMalformed => "record_malformed", + Reason::BadKey => "bad_key", + Reason::BadSignature => "bad_signature", + Reason::WrongRoom => "wrong_room", + Reason::RecordConflict => "record_conflict", + Reason::SourceUnknown => "source_unknown", + Reason::SourceTakeUnknown => "source_take_unknown", + Reason::TextNotInSubset => "text_not_in_subset", + Reason::ReferenceUnknown => "reference_unknown", + Reason::ReferenceIncomplete => "reference_incomplete", + Reason::StreamIncomplete => "stream_incomplete", + Reason::FigureInputsMismatch => "figure_inputs_mismatch", + Reason::FigureMismatch => "figure_mismatch", + Reason::DescriptionMalformed => "description_malformed", + Reason::DescriptionOutOfSync => "description_out_of_sync", + Reason::ParameterMalformed => "parameter_malformed", + Reason::SigningMalformed => "signing_malformed", + Reason::SignRevisionUnknown => "sign_revision_unknown", + Reason::SignRevisionNotFinal => "sign_revision_not_final", + Reason::ReviewSubjectUnknown => "review_subject_unknown", + Reason::ClaimMalformed => "claim_malformed", + Reason::TrackMissing => "track_missing", + Reason::TrackIncomplete => "track_incomplete", + Reason::TrackMismatch => "track_mismatch", + Reason::SyncUnmeasured => "sync_unmeasured", + Reason::OutOfSync => "out_of_sync", + Reason::ReviewMissing => "review_missing", + Reason::ReviewMismatch => "review_mismatch", + Reason::ReviewRejected => "review_rejected", + } + } + + pub fn from_code(code: &str) -> Option { + Reason::ALL.iter().copied().find(|r| r.code() == code) + } +} + +impl std::fmt::Display for Reason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.code()) + } +} + +impl std::error::Error for Reason {} + +fn sha(parts: &[&[u8]]) -> [u8; 32] { + let mut h = Sha256::new(); + for p in parts { + h.update(p); + } + h.finalize().into() +} + +pub(crate) fn hex(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() +} + +fn unhex(s: &str) -> Option<[u8; N]> { + if s.len() != 2 * N || !s.bytes().all(|c| c.is_ascii_digit() || (b'a'..=b'f').contains(&c)) { + return None; + } + let mut out = [0u8; N]; + for (i, o) in out.iter_mut().enumerate() { + *o = u8::from_str_radix(&s[2 * i..2 * i + 2], 16).ok()?; + } + Some(out) +} + +// --------------------------------------------------------------------------------------- +// §2 Records +// --------------------------------------------------------------------------------------- + +/// A member's type in a record's table (§2). +#[derive(Debug)] +enum Ty { + Hex32, + Hex64, + Int, + Sint, + Str, + OneOf(&'static [&'static str]), + Obj(&'static [(&'static str, Ty)]), + Arr(&'static Ty), + OrNull(&'static Ty), +} + +const ORIGINS: &[&str] = &["human", "machine", "machine-reviewed"]; +const REPRESENTS: &[&str] = + &["visual", "visual.nonText", "visual.text", "visual.text.title", "visual.text.credit", "visual.text.location", "visual.dialogue"]; + +const SOURCE_ENTRY: &[(&str, Ty)] = + &[("cue", Ty::Hex32), ("basis", Ty::OneOf(&["take", "room"])), ("take", Ty::OrNull(&Ty::Hex32)), ("start", Ty::Int), ("end", Ty::Int)]; +const SOURCES: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::SOURCES])), + ("room", Ty::Hex32), + ("principal", Ty::Hex32), + ("sources", Ty::Arr(&Ty::Obj(SOURCE_ENTRY))), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const REFERENCE_ENTRY: &[(&str, Ty)] = &[("cue", Ty::Hex32), ("text", Ty::Str)]; +const REFERENCE: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::REFERENCE])), + ("room", Ty::Hex32), + ("principal", Ty::Hex32), + ("entries", Ty::Arr(&Ty::Obj(REFERENCE_ENTRY))), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const LATENCY: &[(&str, Ty)] = &[ + ("class", Ty::OneOf(&["none", "capture", "stated"])), + ("n", Ty::Int), + ("min", Ty::OrNull(&Ty::Sint)), + ("max", Ty::OrNull(&Ty::Sint)), + ("mean", Ty::OrNull(&Ty::Sint)), + ("p50", Ty::OrNull(&Ty::Sint)), + ("p95", Ty::OrNull(&Ty::Sint)), +]; +const STABILITY: &[(&str, Ty)] = &[("revisions", Ty::Int), ("words_changed", Ty::Int), ("cues_corrected", Ty::Int)]; +const COUNTS: &[(&str, Ty)] = + &[("words", Ty::Int), ("errors", Ty::Int), ("substitutions", Ty::Int), ("deletions", Ty::Int), ("insertions", Ty::Int)]; +const ACCURACY: &[(&str, Ty)] = &[ + ("class", Ty::OneOf(&["transcript", "reviewed", "self"])), + ("first", Ty::Obj(COUNTS)), + ("final", Ty::OrNull(&Ty::Obj(COUNTS))), +]; +const QUALITY: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::QUALITY])), + ("room", Ty::Hex32), + ("principal", Ty::Hex32), + ("events", Ty::Hex32), + ("sources", Ty::OrNull(&Ty::Hex32)), + ("reference", Ty::OrNull(&Ty::Hex32)), + ("cues", Ty::Int), + ("latency", Ty::Obj(LATENCY)), + ("stability", Ty::Obj(STABILITY)), + ("accuracy", Ty::Obj(ACCURACY)), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const LABEL: &[(&str, Ty)] = &[("origin", Ty::OneOf(ORIGINS)), ("model", Ty::OrNull(&Ty::Hex32))]; +const VOICING: &[(&str, Ty)] = &[ + ("form", Ty::OneOf(&["track", "sink"])), + ("origin", Ty::OneOf(ORIGINS)), + ("model", Ty::OrNull(&Ty::Hex32)), + ("track", Ty::OrNull(&Ty::Hex32)), +]; +const DUCK: &[(&str, Ty)] = &[("gain", Ty::Int), ("ramp", Ty::Int)]; +const SPAN: &[(&str, Ty)] = &[("begin", Ty::Int), ("end", Ty::Int)]; +const DESCRIPTION_EVENT: &[(&str, Ty)] = &[ + ("id", Ty::Str), + ("begin", Ty::Int), + ("end", Ty::Int), + ("represents", Ty::OneOf(REPRESENTS)), + ("text", Ty::Str), + ("duck", Ty::Obj(DUCK)), + ("voice", Ty::OrNull(&Ty::Obj(SPAN))), +]; +const DESCRIPTION: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::DESCRIPTION])), + ("lang", Ty::Str), + ("script", Ty::Obj(LABEL)), + ("voicing", Ty::Obj(VOICING)), + ("events", Ty::Arr(&Ty::Obj(DESCRIPTION_EVENT))), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const VIDEO: &[(&str, Ty)] = &[("width", Ty::Int), ("height", Ty::Int), ("rate_num", Ty::Int), ("rate_den", Ty::Int)]; +const SEGMENT: &[(&str, Ty)] = + &[("object", Ty::Hex32), ("start", Ty::Int), ("end", Ty::Int), ("revisions", Ty::Arr(&Ty::Hex32))]; +const SIGNING: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::SIGNING])), + ("room", Ty::Hex32), + ("lang", Ty::Str), + ("source", Ty::Hex32), + ("form", Ty::OneOf(&["pose", "video"])), + ("track", Ty::Hex32), + ("origin", Ty::OneOf(ORIGINS)), + ("model", Ty::OrNull(&Ty::Hex32)), + ("video", Ty::OrNull(&Ty::Obj(VIDEO))), + ("segments", Ty::Arr(&Ty::Obj(SEGMENT))), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const REVIEW: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::REVIEW])), + ("signing", Ty::Hex32), + ("scope", Ty::OneOf(&["translation"])), + ("verdict", Ty::OneOf(&["approved", "approved-with-notes", "rejected"])), + ("notes", Ty::OrNull(&Ty::Hex32)), + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; +const TRACK_CAPTIONS: &[(&str, Ty)] = &[ + ("service", Ty::OneOf(&["captions"])), + ("principal", Ty::Hex32), + ("lang", Ty::Str), + ("latency_mean_max", Ty::OrNull(&Ty::Int)), + ("latency_max", Ty::OrNull(&Ty::Int)), +]; +const TRACK_DESCRIPTION: &[(&str, Ty)] = + &[("service", Ty::OneOf(&["audio-description"])), ("record", Ty::Hex32), ("lang", Ty::Str)]; +const TRACK_SIGN: &[(&str, Ty)] = &[ + ("service", Ty::OneOf(&["sign-language"])), + ("record", Ty::Hex32), + ("lang", Ty::Str), + ("review", Ty::OrNull(&Ty::Hex32)), + ("offset_max", Ty::OrNull(&Ty::Int)), +]; +const CLAIM: &[(&str, Ty)] = &[ + ("kind", Ty::OneOf(&[kinds::CLAIM])), + ("room", Ty::Hex32), + ("from", Ty::Int), + ("to", Ty::Int), + ("pt0", Ty::Int), + ("tracks", Ty::Arr(&Ty::Obj(&[]))), // each track is checked by its service's table + ("signer_pubkey", Ty::Hex32), + ("sig", Ty::Hex64), +]; + +fn is_sint(s: &str) -> bool { + let digits = s.strip_prefix('-').unwrap_or(s); + if digits.is_empty() || !digits.bytes().all(|c| c.is_ascii_digit()) { + return false; + } + if s == "0" { + return true; + } + if digits.starts_with('0') { + return false; + } + s.parse::().is_ok() +} + +/// Whether `v` is of type `t` (§2). +fn shape(v: &Value, t: &Ty) -> bool { + match t { + Ty::Hex32 => v.as_str().is_some_and(|s| unhex::<32>(s).is_some()), + Ty::Hex64 => v.as_str().is_some_and(|s| unhex::<64>(s).is_some()), + Ty::Int => v.as_u64().is_some_and(|n| n <= MAX_INTEGER), + Ty::Sint => v.as_str().is_some_and(is_sint), + Ty::Str => v.is_string(), + Ty::OneOf(set) => v.as_str().is_some_and(|s| set.contains(&s)), + Ty::Obj(table) => obj_shape(v, table), + Ty::Arr(item) => v.as_array().is_some_and(|a| a.iter().all(|x| shape(x, item))), + Ty::OrNull(inner) => v.is_null() || shape(v, inner), + } +} + +fn obj_shape(v: &Value, table: &[(&str, Ty)]) -> bool { + let Some(m) = v.as_object() else { return false }; + m.len() == table.len() && table.iter().all(|(k, t)| m.get(*k).is_some_and(|x| shape(x, t))) +} + +/// The table of a claim's track, by its service (§7.1). +fn track_table(service: &str) -> Option<&'static [(&'static str, Ty)]> { + match service { + "captions" => Some(TRACK_CAPTIONS), + "audio-description" => Some(TRACK_DESCRIPTION), + "sign-language" => Some(TRACK_SIGN), + _ => None, + } +} + +/// Every kind, in the order §8.2 step 3 checks them. +pub const KINDS: [&str; 7] = + [kinds::SOURCES, kinds::REFERENCE, kinds::DESCRIPTION, kinds::SIGNING, kinds::REVIEW, kinds::QUALITY, kinds::CLAIM]; + +fn table_of(kind: &str) -> Option<&'static [(&'static str, Ty)]> { + match kind { + kinds::SOURCES => Some(SOURCES), + kinds::REFERENCE => Some(REFERENCE), + kinds::QUALITY => Some(QUALITY), + kinds::DESCRIPTION => Some(DESCRIPTION), + kinds::SIGNING => Some(SIGNING), + kinds::REVIEW => Some(REVIEW), + kinds::CLAIM => Some(CLAIM), + _ => None, + } +} + +/// One record read (§2): its value, its kind and its record id. +#[derive(Clone, Debug)] +pub struct Record { + pub value: Value, + pub kind: &'static str, + pub id: [u8; 32], +} + +/// The bytes a record's signature covers (§2). +pub fn signing_bytes(v: &Value) -> Vec { + let mut m = v.as_object().cloned().unwrap_or_default(); + m.remove("sig"); + let mut out = SIGN_DOMAIN.to_vec(); + out.extend_from_slice(jcs(&Value::Object(m)).expect("a record is in the JCS subset").as_bytes()); + out +} + +/// A record's id: SHA-256 over its JCS form (§2). +pub fn record_id(v: &Value) -> [u8; 32] { + sha(&[jcs(v).expect("a record is in the JCS subset").as_bytes()]) +} + +/// Sign `body` (a record without `signer_pubkey` and `sig`) with `key`: the record. +pub fn sign(key: &SigningKey, mut body: Map) -> Value { + body.insert("signer_pubkey".into(), Value::String(hex(&key.verifying_key().to_bytes()))); + body.remove("sig"); + let unsigned = Value::Object(body.clone()); + let sig = key.sign(&signing_bytes(&unsigned)).to_bytes(); + body.insert("sig".into(), Value::String(hex(&sig))); + Value::Object(body) +} + +/// The text of a record as the corpus writes it: its JCS form. +pub fn text(v: &Value) -> String { + jcs(v).expect("a record is in the JCS subset") +} + +/// Read one record's text (§2): JSON with a claim's limits, its shape, its signature. +pub fn read(text: &str) -> Result { + let v = crate::claim_text::read(text).map_err(|_| Reason::RecordMalformed)?; + let named = v.get("kind").and_then(Value::as_str); + let kind = KINDS.into_iter().find(|k| Some(*k) == named).ok_or(Reason::RecordMalformed)?; + let table = table_of(kind).expect("every kind has a table"); + if !obj_shape_claim(&v, table, kind) { + return Err(Reason::RecordMalformed); + } + let pk = unhex::<32>(v["signer_pubkey"].as_str().expect("shape")).expect("shape"); + let sig = unhex::<64>(v["sig"].as_str().expect("shape")).expect("shape"); + crate::sig::verify_strict(&pk, &signing_bytes(&v), &sig).map_err(|e| match e { + crate::sig::SigError::BadKey => Reason::BadKey, + crate::sig::SigError::BadSignature => Reason::BadSignature, + })?; + let id = record_id(&v); + Ok(Record { value: v, kind, id }) +} + +/// The shape of a record, with a claim's tracks read by their service's table. +fn obj_shape_claim(v: &Value, table: &[(&str, Ty)], kind: &str) -> bool { + if kind != kinds::CLAIM { + return obj_shape(v, table); + } + let Some(m) = v.as_object() else { return false }; + if m.len() != table.len() { + return false; + } + for (k, t) in table { + let Some(x) = m.get(*k) else { return false }; + if *k == "tracks" { + let Some(a) = x.as_array() else { return false }; + for tr in a { + let Some(service) = tr.get("service").and_then(Value::as_str) else { return false }; + let Some(tt) = track_table(service) else { return false }; + if !obj_shape(tr, tt) { + return false; + } + } + } else if !shape(x, t) { + return false; + } + } + true +} + +fn h32(v: &Value) -> [u8; 32] { + unhex::<32>(v.as_str().expect("a hex32 the shape admitted")).expect("a hex32 the shape admitted") +} + +fn opt_h32(v: &Value) -> Option<[u8; 32]> { + v.as_str().map(|s| unhex::<32>(s).expect("a hex32 the shape admitted")) +} + +fn int(v: &Value) -> u64 { + v.as_u64().expect("an int the shape admitted") +} + +fn st(v: &Value) -> &str { + v.as_str().expect("a string the shape admitted") +} + +// --------------------------------------------------------------------------------------- +// §3 Words and their alignment +// --------------------------------------------------------------------------------------- + +/// The set *P* of §3.1. +pub const EDGE_PUNCTUATION: [char; 24] = [ + '!', '"', '\'', '(', ')', ',', '-', '.', ':', ';', '?', '[', ']', '\u{a1}', '\u{ab}', '\u{bb}', '\u{bf}', '\u{2013}', '\u{2014}', + '\u{2018}', '\u{2019}', '\u{201c}', '\u{201d}', '\u{2026}', +]; + +/// The words of a text (§3.1). +pub fn words(text: &str) -> Vec { + text.split([' ', '\n']) + .filter(|p| !p.is_empty()) + .filter_map(|p| { + let low: String = p.chars().map(|c| c.to_ascii_lowercase()).collect(); + let w = low.trim_matches(|c| EDGE_PUNCTUATION.contains(&c)); + (!w.is_empty()).then(|| w.to_string()) + }) + .collect() +} + +/// The counts of an alignment (§3.2). +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct Counts { + pub words: u64, + pub errors: u64, + pub substitutions: u64, + pub deletions: u64, + pub insertions: u64, +} + +impl Counts { + fn add(&mut self, o: Counts) { + self.words += o.words; + self.errors += o.errors; + self.substitutions += o.substitutions; + self.deletions += o.deletions; + self.insertions += o.insertions; + } + + fn json(&self) -> Value { + json!({"words": self.words, "errors": self.errors, "substitutions": self.substitutions, + "deletions": self.deletions, "insertions": self.insertions}) + } +} + +/// The alignment of hypothesis `h` to reference `r` (§3.2), full or prefix. +pub fn align(h: &[String], r: &[String], prefix: bool) -> Counts { + let (m, n) = (h.len(), r.len()); + let mut d = vec![vec![0u64; n + 1]; m + 1]; + for (j, x) in d[0].iter_mut().enumerate() { + *x = j as u64; + } + for (i, row) in d.iter_mut().enumerate() { + row[0] = i as u64; + } + for i in 1..=m { + for j in 1..=n { + let c = (h[i - 1] != r[j - 1]) as u64; + d[i][j] = (d[i - 1][j - 1] + c).min(d[i - 1][j] + 1).min(d[i][j - 1] + 1); + } + } + let end = if prefix { + let least = *d[m].iter().min().expect("a row of at least one column"); + (0..=n).rev().find(|&j| d[m][j] == least).expect("the least is in the row") + } else { + n + }; + let mut c = Counts { words: end as u64, errors: d[m][end], ..Default::default() }; + let (mut i, mut j) = (m, end); + while i > 0 || j > 0 { + if i > 0 && j > 0 { + let cost = (h[i - 1] != r[j - 1]) as u64; + if d[i][j] == d[i - 1][j - 1] + cost { + c.substitutions += cost; + i -= 1; + j -= 1; + continue; + } + } + if i > 0 && d[i][j] == d[i - 1][j] + 1 { + c.insertions += 1; + i -= 1; + } else { + c.deletions += 1; + j -= 1; + } + } + debug_assert_eq!(c.substitutions + c.deletions + c.insertions, c.errors); + c +} + +// --------------------------------------------------------------------------------------- +// §4 Caption quality: the tracks a stream holds +// --------------------------------------------------------------------------------------- + +/// One cue (§4.1): the positions of its revisions among the verifier's, first to last. +#[derive(Clone, Debug)] +pub struct CueChain { + pub revs: Vec, +} + +/// What the events gave (§8.2 step 1). +pub struct Stream { + pub room: [u8; 32], + pub revisions: Vec, + pub accepted: Vec, + pub gaps: Vec, +} + +impl Stream { + /// The principals with a caption, in the order of their first `caption` event. + pub fn caption_principals(&self) -> Vec<[u8; 32]> { + let mut out = Vec::new(); + for r in &self.revisions { + if !out.contains(&r.event.principal) { + out.push(r.event.principal); + } + } + out + } + + /// The cues of `p`, in the stream order of their first revisions. + pub fn cues(&self, p: &[u8; 32]) -> Vec { + let mut out = Vec::new(); + for (i, r) in self.revisions.iter().enumerate() { + if r.event.principal != *p || r.supersedes.is_some() || r.supersedes_digest.is_some() { + continue; + } + let mut revs = vec![i]; + let mut k = i; + while let Some(n) = self.revisions[k].superseded_by { + revs.push(n); + k = n; + } + out.push(CueChain { revs }); + } + out + } + + fn head_digest(&self, c: &CueChain) -> [u8; 32] { + self.revisions[c.revs[0]].digest + } + + fn last(&self, c: &CueChain) -> &Revision { + &self.revisions[*c.revs.last().expect("a cue has a revision")] + } + + /// Whether `p`'s captions are whole (§4.1). + pub fn whole(&self, p: &[u8; 32]) -> bool { + let cues = self.cues(p); + !cues.is_empty() + && !self.gaps.iter().any(|g| g.principal == *p) + && cues.iter().all(|c| { + let r = self.last(c); + r.final_ && !r.unknown + }) + } + + /// Whether `p`'s captions are resolved (§4.1). + pub fn resolved(&self, p: &[u8; 32]) -> bool { + self.whole(p) && self.cues(p).iter().all(|c| self.last(c).caption.duration_ms > 0) + } + + /// `p`'s events digest (§4.1). + pub fn events_digest(&self, p: &[u8; 32]) -> [u8; 32] { + let mut mine: Vec<&Revision> = self.revisions.iter().filter(|r| r.event.principal == *p).collect(); + mine.sort_by_key(|r| r.event.seq); + let mut h = Sha256::new(); + for r in mine { + h.update(r.digest); + } + h.finalize().into() + } + + /// The opening commitment of `take` and the take derived (§4.2 rule 6): its offset. + fn take_offset(&self, take: &[u8; 32]) -> Option { + let opening = self.accepted.iter().find_map(|a| match &a.payload { + Payload::TakeCommit(b) => Commit::parse(b).ok().filter(|c| c.take == *take && c.n == 0 && c.phase == 1).map(|c| (a.event.principal, c.offset)), + _ => None, + })?; + let (author, offset) = opening; + let derived = self.accepted.iter().any(|a| { + matches!(&a.payload, Payload::Control { target, command: Command::RecordStart { .. } } if *target == author) + && take_id(&self.room, &author, &a.digest) == *take + }); + derived.then_some(offset) + } + + /// The media intervals of `p`'s resolved cues (timed-text §4.5), with `pt0`. + fn cue_intervals(&self, p: &[u8; 32], pt0: u64) -> Vec<(u64, u64)> { + self.cues(p) + .iter() + .map(|c| { + let head = &self.revisions[c.revs[0]]; + let last = self.last(c); + (pt0 + head.event.t / 1000, pt0 + last.event.t / 1000 + last.caption.duration_ms as u64) + }) + .collect() + } +} + +/// A sources record, checked (§4.2): each cue's source instant `start` on the room clock. +#[derive(Clone, Debug)] +struct Sources { + id: [u8; 32], + /// Cue (head digest) → (`start` on the room clock, on the basis `take`). + starts: BTreeMap<[u8; 32], (i128, bool)>, +} + +/// A reference record, checked (§4.3): its id, and each cue's (head digest) text. +type Reference = ([u8; 32], BTreeMap<[u8; 32], String>); + +/// The verifier's state over the records (§8.2 steps 2 and 3). +struct Run<'a> { + stream: &'a Stream, + records: Vec, + sources: BTreeMap<[u8; 32], Sources>, + references: BTreeMap<[u8; 32], Reference>, +} + +fn sint(v: i128) -> Value { + Value::String(v.to_string()) +} + +impl Run<'_> { + /// Latencies of the cues `cues` of `p` that `p`'s sources record places (§4.4). + fn latencies(&self, p: &[u8; 32], cues: &[CueChain]) -> Vec<(i128, bool)> { + let Some(s) = self.sources.get(p) else { return Vec::new() }; + cues.iter() + .filter_map(|c| { + let (start, take) = *s.starts.get(&self.stream.head_digest(c))?; + Some((self.stream.revisions[c.revs[0]].event.t as i128 - start, take)) + }) + .collect() + } + + /// The figure of `p`'s whole track (§4.7). + fn figure(&self, p: &[u8; 32]) -> Value { + let s = self.stream; + let cues = s.cues(p); + let lat = self.latencies(p, &cues); + let mut sorted: Vec = lat.iter().map(|x| x.0).collect(); + sorted.sort(); + let n = sorted.len(); + let latency = if n == 0 { + json!({"class": "none", "n": 0, "min": null, "max": null, "mean": null, "p50": null, "p95": null}) + } else { + let sum: i128 = sorted.iter().sum(); + let rank = |p: usize| sorted[(p * n).div_ceil(100) - 1]; + let class = if lat.iter().all(|x| x.1) { "capture" } else { "stated" }; + json!({"class": class, "n": n, "min": sint(sorted[0]), "max": sint(sorted[n - 1]), + "mean": sint(sum.div_euclid(n as i128)), "p50": sint(rank(50)), "p95": sint(rank(95))}) + }; + let (mut revisions, mut changed_total, mut corrected) = (0u64, 0u64, 0u64); + for c in &cues { + revisions += (c.revs.len() - 1) as u64; + let mut changed = 0u64; + for w in c.revs.windows(2) { + let a = align(&words(&s.revisions[w[0]].caption.text), &words(&s.revisions[w[1]].caption.text), false); + changed += a.substitutions + a.insertions; + } + changed_total += changed; + corrected += (changed > 0) as u64; + } + let reference = self.references.get(p); + let class = if reference.is_some() { + "transcript" + } else if cues.iter().all(|c| matches!(s.last(c).caption.origin, tt::origin::HUMAN | tt::origin::REVIEWED)) { + "reviewed" + } else { + "self" + }; + let (mut first, mut fin) = (Counts::default(), Counts::default()); + for c in &cues { + let ref_text = match reference { + Some((_, entries)) => entries[&s.head_digest(c)].clone(), + None => s.last(c).caption.text.clone(), + }; + let rw = words(&ref_text); + first.add(align(&words(&s.revisions[c.revs[0]].caption.text), &rw, true)); + if reference.is_some() { + fin.add(align(&words(&s.last(c).caption.text), &rw, false)); + } + } + json!({ + "room": hex(&s.room), + "principal": hex(p), + "events": hex(&s.events_digest(p)), + "sources": self.sources.get(p).map(|x| hex(&x.id)), + "reference": reference.map(|x| hex(&x.0)), + "cues": cues.len(), + "latency": latency, + "stability": {"revisions": revisions, "words_changed": changed_total, "cues_corrected": corrected}, + "accuracy": {"class": class, "first": first.json(), "final": if reference.is_some() { fin.json() } else { Value::Null }}, + }) + } + + fn room_ok(&self, v: &Value) -> Result<(), Reason> { + if h32(&v["room"]) == self.stream.room { + Ok(()) + } else { + Err(Reason::WrongRoom) + } + } + + /// The head digests of `p`'s cues. + fn heads(&self, p: &[u8; 32]) -> Vec<[u8; 32]> { + self.stream.cues(p).iter().map(|c| self.stream.head_digest(c)).collect() + } + + /// §4.2. + fn check_sources(&mut self, at: usize) -> Result<(), Reason> { + let v = self.records[at].value.clone(); + self.room_ok(&v)?; + let p = h32(&v["principal"]); + if self.records[..at].iter().any(|r| r.kind == kinds::SOURCES && h32(&r.value["principal"]) == p) { + return Err(Reason::RecordConflict); + } + let entries = v["sources"].as_array().expect("shape"); + let mut seen = BTreeSet::new(); + for e in entries { + let take = e["basis"] == "take"; + if take != e["take"].is_string() || int(&e["start"]) > int(&e["end"]) || !seen.insert(h32(&e["cue"])) { + return Err(Reason::RecordMalformed); + } + } + if !self.stream.whole(&p) { + return Err(Reason::StreamIncomplete); + } + let heads = self.heads(&p); + if entries.iter().any(|e| !heads.contains(&h32(&e["cue"]))) { + return Err(Reason::SourceUnknown); + } + let mut starts = BTreeMap::new(); + for e in entries { + let start = int(&e["start"]) as i128; + let placed = if e["basis"] == "take" { + let o = self.stream.take_offset(&h32(&e["take"])).ok_or(Reason::SourceTakeUnknown)?; + let s = start + o as i128; + if s < 0 { + return Err(Reason::SourceTakeUnknown); + } + (s, true) + } else { + (start, false) + }; + starts.insert(h32(&e["cue"]), placed); + } + let id = self.records[at].id; + self.sources.entry(p).or_insert(Sources { id, starts }); + Ok(()) + } + + /// §4.3. + fn check_reference(&mut self, at: usize) -> Result<(), Reason> { + let v = self.records[at].value.clone(); + self.room_ok(&v)?; + let p = h32(&v["principal"]); + if self.records[..at].iter().any(|r| r.kind == kinds::REFERENCE && h32(&r.value["principal"]) == p) { + return Err(Reason::RecordConflict); + } + let entries = v["entries"].as_array().expect("shape"); + let mut map = BTreeMap::new(); + for e in entries { + if map.insert(h32(&e["cue"]), st(&e["text"]).to_string()).is_some() { + return Err(Reason::RecordMalformed); + } + } + if map.values().any(|t| !tt::text_in_subset(t)) { + return Err(Reason::TextNotInSubset); + } + if !self.stream.whole(&p) { + return Err(Reason::StreamIncomplete); + } + let heads = self.heads(&p); + if map.keys().any(|k| !heads.contains(k)) { + return Err(Reason::ReferenceUnknown); + } + if heads.iter().any(|h| !map.contains_key(h)) { + return Err(Reason::ReferenceIncomplete); + } + let id = self.records[at].id; + self.references.entry(p).or_insert((id, map)); + Ok(()) + } + + /// §4.7. + fn check_quality(&self, at: usize) -> Result<(), Reason> { + let v = &self.records[at].value; + self.room_ok(v)?; + let p = h32(&v["principal"]); + if !self.stream.whole(&p) { + return Err(Reason::StreamIncomplete); + } + let f = self.figure(&p); + for k in ["events", "sources", "reference"] { + if v[k] != f[k] { + return Err(Reason::FigureInputsMismatch); + } + } + for (k, x) in f.as_object().expect("an object") { + if v[k] != *x { + return Err(Reason::FigureMismatch); + } + } + Ok(()) + } + + /// §6.2. + fn check_signing(&self, at: usize) -> Result<(), Reason> { + let v = &self.records[at].value; + self.room_ok(v)?; + let machine = st(&v["origin"]) != "human"; + let video = st(&v["form"]) == "video"; + let segs = v["segments"].as_array().expect("shape"); + let mut ok = le::lang_tag_ok(st(&v["lang"])) && machine == v["model"].is_string() && video == v["video"].is_object(); + if let Some(vd) = v["video"].as_object() { + ok &= ["width", "height", "rate_num", "rate_den"].iter().all(|k| int(&vd[*k]) > 0); + } + ok &= !segs.is_empty(); + let mut prev_end = 0u64; + let mut named = BTreeSet::new(); + for (i, s) in segs.iter().enumerate() { + let (a, b) = (int(&s["start"]), int(&s["end"])); + let revs = s["revisions"].as_array().expect("shape"); + ok &= a < b && !revs.is_empty() && (i == 0 || a >= prev_end); + prev_end = b; + for r in revs { + ok &= named.insert(h32(r)); + } + } + if !ok { + return Err(Reason::SigningMalformed); + } + let src = h32(&v["source"]); + if !self.stream.whole(&src) { + return Err(Reason::StreamIncomplete); + } + let revs: Vec<&Revision> = self.stream.revisions.iter().filter(|r| r.event.principal == src).collect(); + for d in &named { + if !revs.iter().any(|r| r.digest == *d) { + return Err(Reason::SignRevisionUnknown); + } + } + for d in &named { + let r = revs.iter().find(|r| r.digest == *d).expect("held"); + if r.superseded_by.is_some() || !r.final_ || r.unknown { + return Err(Reason::SignRevisionNotFinal); + } + } + Ok(()) + } + + /// The head digest of the cue whose last revision is `d`, of `src`. + fn cue_of_final(&self, src: &[u8; 32], d: &[u8; 32]) -> Option { + self.stream.cues(src).into_iter().find(|c| self.stream.last(c).digest == *d) + } + + /// A segment's offset (§6.3). + fn segment_offset(&self, src: &[u8; 32], seg: &Value) -> Option { + let cues: Vec = + seg["revisions"].as_array().expect("shape").iter().filter_map(|r| self.cue_of_final(src, &h32(r))).collect(); + let earliest = cues.iter().min_by_key(|c| (self.stream.revisions[c.revs[0]].event.t, c.revs[0]))?; + let s = self.sources.get(src)?; + let (start, _) = s.starts.get(&self.stream.head_digest(earliest))?; + Some(int(&seg["start"]) as i128 - start) + } + + /// §6.4. + fn check_review(&self, at: usize) -> Result<(), Reason> { + let v = &self.records[at].value; + if (st(&v["verdict"]) == "approved") != v["notes"].is_null() { + return Err(Reason::RecordMalformed); + } + let target = h32(&v["signing"]); + if !self.records.iter().any(|r| r.kind == kinds::SIGNING && r.id == target) { + return Err(Reason::ReviewSubjectUnknown); + } + Ok(()) + } + + /// §7.2. + fn check_claim(&self, at: usize) -> Result<(), Reason> { + let v = &self.records[at].value; + self.room_ok(v)?; + let (from, to, pt0) = (int(&v["from"]), int(&v["to"]), int(&v["pt0"])); + let tracks = v["tracks"].as_array().expect("shape"); + let mut ok = from < to && !tracks.is_empty(); + let (mut principals, mut recs) = (BTreeSet::new(), BTreeSet::new()); + for t in tracks { + ok &= le::lang_tag_ok(st(&t["lang"])); + if t["service"] == "captions" { + ok &= principals.insert(h32(&t["principal"])); + } else { + ok &= recs.insert(h32(&t["record"])); + } + } + if !ok { + return Err(Reason::ClaimMalformed); + } + let in_session = |p: &[u8; 32]| -> Vec { + self.stream.cues(p).into_iter().filter(|c| (from..to).contains(&self.stream.revisions[c.revs[0]].event.t)).collect() + }; + let (m_from, m_to) = (pt0 + from / 1000, pt0 + to / 1000); + for t in tracks { + match st(&t["service"]) { + "captions" => { + let p = h32(&t["principal"]); + let cues = in_session(&p); + if cues.is_empty() { + return Err(Reason::TrackMissing); + } + if !self.stream.resolved(&p) { + return Err(Reason::TrackIncomplete); + } + let lang = st(&t["lang"]); + if cues.iter().any(|c| c.revs.iter().any(|&r| self.stream.revisions[r].caption.lang != lang)) { + return Err(Reason::TrackMismatch); + } + let (mean_max, max) = (t["latency_mean_max"].as_u64(), t["latency_max"].as_u64()); + if mean_max.is_some() || max.is_some() { + let lat = self.latencies(&p, &cues); + if lat.len() != cues.len() { + return Err(Reason::SyncUnmeasured); + } + let sum: i128 = lat.iter().map(|x| x.0).sum(); + let mean = sum.div_euclid(lat.len() as i128); + if mean_max.is_some_and(|m| mean > m as i128) || max.is_some_and(|m| lat.iter().any(|x| x.0 > m as i128)) { + return Err(Reason::OutOfSync); + } + } + } + "audio-description" => { + let id = h32(&t["record"]); + let d = self.records.iter().find(|r| r.kind == kinds::DESCRIPTION && r.id == id).ok_or(Reason::TrackMissing)?; + let dv = &d.value; + let events = dv["events"].as_array().expect("shape"); + if st(&dv["lang"]) != st(&t["lang"]) || events.iter().any(|e| int(&e["begin"]) < m_from || int(&e["end"]) > m_to) { + return Err(Reason::TrackMismatch); + } + if dv["voicing"]["form"] == "track" && events.iter().any(|e| e["voice"].is_null()) { + return Err(Reason::TrackIncomplete); + } + } + _ => { + let id = h32(&t["record"]); + let g = self.records.iter().find(|r| r.kind == kinds::SIGNING && r.id == id).ok_or(Reason::TrackMissing)?; + let gv = &g.value; + let src = h32(&gv["source"]); + if st(&gv["lang"]) != st(&t["lang"]) || !principals.contains(&src) { + return Err(Reason::TrackMismatch); + } + let named: BTreeSet<[u8; 32]> = gv["segments"] + .as_array() + .expect("shape") + .iter() + .flat_map(|s| s["revisions"].as_array().expect("shape").iter().map(h32)) + .collect(); + if in_session(&src).iter().any(|c| !named.contains(&self.stream.last(c).digest)) { + return Err(Reason::TrackIncomplete); + } + if let Some(rid) = opt_h32(&t["review"]) { + let r = self.records.iter().find(|r| r.kind == kinds::REVIEW && r.id == rid).ok_or(Reason::ReviewMissing)?; + if h32(&r.value["signing"]) != id { + return Err(Reason::ReviewMismatch); + } + if r.value["verdict"] == "rejected" { + return Err(Reason::ReviewRejected); + } + } + if let Some(m) = t["offset_max"].as_u64() { + let mut offs = Vec::new(); + for s in gv["segments"].as_array().expect("shape") { + offs.push(self.segment_offset(&src, s).ok_or(Reason::SyncUnmeasured)?); + } + if offs.iter().any(|o| o.unsigned_abs() > m as u128) { + return Err(Reason::OutOfSync); + } + } + } + } + } + Ok(()) + } + + /// A claim's dialogue overlap (§7.2, §5.4). + fn claim_overlap(&self, r: &Record) -> Value { + let v = &r.value; + let pt0 = int(&v["pt0"]); + let tracks = v["tracks"].as_array().expect("shape"); + let mut dialogue: Vec<(u64, u64)> = Vec::new(); + for t in tracks.iter().filter(|t| t["service"] == "captions") { + dialogue.extend(self.stream.cue_intervals(&h32(&t["principal"]), pt0)); + } + let union = merge(dialogue); + let mut out = Vec::new(); + for (i, t) in tracks.iter().enumerate().filter(|(_, t)| t["service"] == "audio-description") { + let d = self.records.iter().find(|d| d.kind == kinds::DESCRIPTION && d.id == h32(&t["record"])).expect("checked"); + let (ms, n) = overlap(&d.value, &union); + out.push(json!({"track": i, "ms": ms, "events": n})); + } + json!({"record": hex(&r.id), "overlap": out}) + } +} + +/// The union of intervals, as disjoint intervals in order. +fn merge(mut xs: Vec<(u64, u64)>) -> Vec<(u64, u64)> { + xs.sort(); + let mut out: Vec<(u64, u64)> = Vec::new(); + for (a, b) in xs { + match out.last_mut() { + Some(last) if a <= last.1 => last.1 = last.1.max(b), + _ => out.push((a, b)), + } + } + out +} + +/// A description's spoken interval of each event (§5.3, §5.4). +fn spoken(e: &Value) -> (u64, u64) { + match e["voice"].as_object() { + Some(v) => (int(&v["begin"]), int(&v["end"])), + None => { + let r = int(&e["duck"]["ramp"]); + (int(&e["begin"]) + r, int(&e["end"]) - r) + } + } +} + +/// §5.4: the sum of the events' overlaps with `union`, and how many overlap. +fn overlap(d: &Value, union: &[(u64, u64)]) -> (u64, u64) { + let (mut ms, mut n) = (0u64, 0u64); + for e in d["events"].as_array().expect("shape") { + let (a, b) = spoken(e); + let o: u64 = union.iter().map(|&(x, y)| b.min(y).saturating_sub(a.max(x))).sum(); + ms += o; + n += (o > 0) as u64; + } + (ms, n) +} + +/// Whether an `id` of a description event has §5.2 rule 3's form. +fn id_ok(s: &str) -> bool { + let b = s.as_bytes(); + !b.is_empty() + && b.len() <= 64 + && (b[0].is_ascii_alphabetic() || b[0] == b'_') + && b[1..].iter().all(|&c| c.is_ascii_alphanumeric() || matches!(c, b'_' | b'.' | b'-')) +} + +/// §5.2: a description's rules. +pub fn check_description(v: &Value) -> Result<(), Reason> { + let m = Reason::DescriptionMalformed; + if !le::lang_tag_ok(st(&v["lang"])) { + return Err(m); + } + let (script, voicing) = (&v["script"], &v["voicing"]); + let machine = |o: &Value| st(o) != "human"; + let sink = voicing["form"] == "sink"; + if machine(&script["origin"]) != script["model"].is_string() + || machine(&voicing["origin"]) != voicing["model"].is_string() + || sink == voicing["track"].is_string() + || (sink && voicing["origin"] == "human") + { + return Err(m); + } + let events = v["events"].as_array().expect("shape"); + if events.is_empty() { + return Err(m); + } + let mut ids = BTreeSet::new(); + let mut prev_end = 0u64; + for (i, e) in events.iter().enumerate() { + let (b, en) = (int(&e["begin"]), int(&e["end"])); + if !id_ok(st(&e["id"])) || !ids.insert(st(&e["id"]).to_string()) || b >= en || en > MAX_MS || (i > 0 && b < prev_end) { + return Err(m); + } + prev_end = en; + } + if events.iter().any(|e| !tt::text_in_subset(st(&e["text"]))) { + return Err(Reason::TextNotInSubset); + } + for e in events { + let (b, en) = (int(&e["begin"]), int(&e["end"])); + let (g, r) = (int(&e["duck"]["gain"]), int(&e["duck"]["ramp"])); + let duck_ok = g <= 1000 && ((g == 1000) == (r == 0)) && 2 * r <= en - b; + let voice_ok = match e["voice"].as_object() { + None => true, + Some(vo) => !sink && b <= int(&vo["begin"]) && int(&vo["begin"]) < int(&vo["end"]) && int(&vo["end"]) <= en, + }; + if !duck_ok || !voice_ok { + return Err(m); + } + } + for e in events { + if let Some(vo) = e["voice"].as_object() { + let r = int(&e["duck"]["ramp"]); + let (a, z) = (int(&e["begin"]) + r, int(&e["end"]) - r); + let (vb, ve) = (int(&vo["begin"]), int(&vo["end"])); + if vb + EARLY_MS < a || vb > a + LATE_MS || ve > z + LATE_MS { + return Err(Reason::DescriptionOutOfSync); + } + } + } + Ok(()) +} + +/// A description's figures (§8.2 step 4). +fn description_figures(id: &[u8; 32], v: &Value) -> Value { + let events = v["events"].as_array().expect("shape"); + let offsets: Vec = events + .iter() + .map(|e| match e["voice"].as_object() { + Some(vo) => sint(int(&vo["begin"]) as i128 - (int(&e["begin"]) + int(&e["duck"]["ramp"])) as i128), + None => Value::Null, + }) + .collect(); + json!({"record": hex(id), "events": events.len(), "voiced": events.iter().filter(|e| !e["voice"].is_null()).count(), "offsets": offsets}) +} + +// --------------------------------------------------------------------------------------- +// §5.5 The DAPT document +// --------------------------------------------------------------------------------------- + +fn param_ok(s: &str) -> bool { + !s.is_empty() && s.len() <= 2048 && s.bytes().all(|c| (b'!'..=b'~').contains(&c) && !matches!(c, b'"' | b'&' | b'<' | b'>')) +} + +fn gain(g: u64) -> String { + if g == 0 { + return "0".into(); + } + if g == 1000 { + return "1".into(); + } + let digits = format!("{g:03}"); + format!("0.{}", digits.trim_end_matches('0')) +} + +fn esc(s: &str) -> String { + s.replace('&', "&").replace('<', "<").replace('>', ">").replace('\n', "
") +} + +/// The DAPT document of a description record that §5.2 accepts (§5.5): `uri` and `media_type` +/// name the voicing track for the form `track`. +pub fn dapt(v: &Value, uri: &str, media_type: &str) -> Result { + let track = v["voicing"]["form"] == "track"; + if track && (!param_ok(uri) || !param_ok(media_type)) { + return Err(Reason::ParameterMalformed); + } + let events = v["events"].as_array().expect("shape"); + let mut reps: Vec<&str> = Vec::new(); + for e in events { + let r = st(&e["represents"]); + if !reps.contains(&r) { + reps.push(r); + } + } + let label = |o: &Value, name: &str| { + let mut s = format!(" wai:{name}=\"{}\"", st(&o["origin"])); + if let Some(m) = o["model"].as_str() { + s.push_str(&format!(" wai:{name}-model=\"{m}\"")); + } + s + }; + let mut o = String::from("\n"); + o.push_str(&format!( + "\n", + st(&v["lang"]), + reps.join(" "), + if track { "asRecorded" } else { "preRecording" }, + label(&v["script"], "script"), + label(&v["voicing"], "voice"), + )); + o.push_str("\n"); + for e in events { + let (b, en) = (int(&e["begin"]), int(&e["end"])); + let (g, r) = (int(&e["duck"]["gain"]), int(&e["duck"]["ramp"])); + o.push_str(&format!( + "
\n", + st(&e["id"]), + tt::timestamp(b), + tt::timestamp(en), + st(&e["represents"]) + )); + if g < 1000 { + let gs = gain(g); + o.push_str(&format!( + "\n", + tt::timestamp(r) + )); + o.push_str(&format!( + "\n", + tt::timestamp(en - b - r), + tt::timestamp(en - b) + )); + } + let text = esc(st(&e["text"])); + let content = match (track, e["voice"].as_object()) { + (true, Some(vo)) => { + let (vb, ve) = (int(&vo["begin"]), int(&vo["end"])); + format!( + "", + tt::timestamp(vb - b), + tt::timestamp(ve - b), + tt::timestamp(vb), + tt::timestamp(ve) + ) + } + (true, None) => text, + (false, _) => format!("{text}"), + }; + o.push_str(&format!("

{content}

\n
\n")); + } + o.push_str("\n
\n"); + Ok(o) +} + +// --------------------------------------------------------------------------------------- +// §8 Verification +// --------------------------------------------------------------------------------------- + +/// Where a refusal is (§8.2). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Outcome { + /// Accept, with the figures of §8.2 step 4. + Accept(Value), + /// A refusal at `events` (an event record) or `record` (one of this extension's), its + /// index, and its reason's code. + Refuse { at: &'static str, index: usize, reason: &'static str }, +} + +/// Verify a room's events and records (§8). +pub fn verify(room: [u8; 32], events: &[Vec], records: &[String]) -> Outcome { + let mut cv = CaptionVerifier::new(room, le::Policy::default()); + match tt::verify_stream(&mut cv, events) { + tt::Outcome::Refuse { index, reason } => return Outcome::Refuse { at: "events", index, reason }, + tt::Outcome::Gap(_) | tt::Outcome::Accept => {} + } + let stream = Stream { + room, + revisions: cv.revisions().to_vec(), + accepted: cv.events.accepted().to_vec(), + gaps: cv.events.gaps().to_vec(), + }; + verify_records(&stream, records) +} + +/// §8.2 steps 2 to 4, over a stream already verified. +pub fn verify_records(stream: &Stream, records: &[String]) -> Outcome { + let mut read_all = Vec::new(); + for (i, t) in records.iter().enumerate() { + match read(t) { + Ok(r) => read_all.push(r), + Err(e) => return Outcome::Refuse { at: "record", index: i, reason: e.code() }, + } + } + let mut run = Run { stream, records: read_all, sources: BTreeMap::new(), references: BTreeMap::new() }; + for kind in KINDS { + for i in 0..run.records.len() { + if run.records[i].kind != kind { + continue; + } + let res = match kind { + kinds::SOURCES => run.check_sources(i), + kinds::REFERENCE => run.check_reference(i), + kinds::QUALITY => run.check_quality(i), + kinds::DESCRIPTION => check_description(&run.records[i].value), + kinds::SIGNING => run.check_signing(i), + kinds::REVIEW => run.check_review(i), + _ => run.check_claim(i), + }; + if let Err(e) = res { + return Outcome::Refuse { at: "record", index: i, reason: e.code() }; + } + } + } + let captions: Vec = stream.caption_principals().iter().filter(|p| stream.whole(p)).map(|p| run.figure(p)).collect(); + let descriptions: Vec = + run.records.iter().filter(|r| r.kind == kinds::DESCRIPTION).map(|r| description_figures(&r.id, &r.value)).collect(); + let signings: Vec = run + .records + .iter() + .filter(|r| r.kind == kinds::SIGNING) + .map(|r| { + let v = &r.value; + let src = h32(&v["source"]); + let segs = v["segments"].as_array().expect("shape"); + let offsets: Vec = segs.iter().map(|s| run.segment_offset(&src, s).map_or(Value::Null, sint)).collect(); + let floor = v["video"].as_object().map(|vd| { + let (w, h) = (int(&vd["width"]), int(&vd["height"])); + let meets = w.min(h) >= 240 && w.max(h) >= 320 && int(&vd["rate_num"]) >= 20 * int(&vd["rate_den"]); + if meets { "meets" } else { "below" } + }); + let named: usize = segs.iter().map(|s| s["revisions"].as_array().expect("shape").len()).sum(); + json!({"record": hex(&r.id), "segments": segs.len(), "revisions": named, "offsets": offsets, "video_floor": floor}) + }) + .collect(); + let claims: Vec = run.records.iter().filter(|r| r.kind == kinds::CLAIM).map(|r| run.claim_overlap(r)).collect(); + Outcome::Accept(json!({"captions": captions, "descriptions": descriptions, "signings": signings, "claims": claims})) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn w(s: &str) -> Vec { + words(s) + } + + #[test] + fn words_fold_ascii_case_and_strip_edge_punctuation() { + assert_eq!(w("The moon, \u{201c}pulls\u{201d}\nthe SEA."), ["the", "moon", "pulls", "the", "sea"]); + assert_eq!(w("- ... ¿Qué?"), ["qué"]); + assert_eq!(w("Ünïcode keeps CASE"), ["Ünïcode", "keeps", "case"]); + assert_eq!(w("it's twice-daily"), ["it's", "twice-daily"]); + } + + #[test] + fn a_full_alignment_counts_each_kind() { + let a = align(&w("the cap sat on mat"), &w("the cat sat on the mat"), false); + assert_eq!(a, Counts { words: 6, errors: 2, substitutions: 1, deletions: 1, insertions: 0 }); + let a = align(&w("a b c"), &w(""), false); + assert_eq!(a, Counts { words: 0, errors: 3, substitutions: 0, deletions: 0, insertions: 3 }); + let a = align(&w(""), &w("a b"), false); + assert_eq!(a, Counts { words: 2, errors: 2, substitutions: 0, deletions: 2, insertions: 0 }); + } + + #[test] + fn a_prefix_alignment_reads_only_as_far_as_the_hypothesis_reaches() { + // A partial that has not reached the end of the speech makes no error. + let a = align(&w("the moon pulls"), &w("the moon pulls the sea"), true); + assert_eq!(a, Counts { words: 3, errors: 0, ..Default::default() }); + // A wrong last word is a substitution against the word it stands for, not an + // insertion before it: the greatest column with the least errors. + let a = align(&w("high tied"), &w("high tide comes twice a day"), true); + assert_eq!(a, Counts { words: 2, errors: 1, substitutions: 1, ..Default::default() }); + let a = align(&w(""), &w("anything"), true); + assert_eq!(a, Counts::default()); + } + + #[test] + fn signed_integers_are_read_from_their_spelling() { + for ok in ["0", "-1", "45", "9223372036854775807", "-9223372036854775808"] { + assert!(is_sint(ok), "{ok}"); + } + for bad in ["", "-", "-0", "01", "+1", "1.0", "9223372036854775808", " 1"] { + assert!(!is_sint(bad), "{bad}"); + } + } + + #[test] + fn gains_are_written_without_trailing_zeros() { + assert_eq!([gain(0), gain(5), gain(390), gain(500), gain(999), gain(1000)], ["0", "0.005", "0.39", "0.5", "0.999", "1"]); + } + + #[test] + fn every_reason_has_one_code() { + let codes: BTreeSet<&str> = Reason::ALL.iter().map(|r| r.code()).collect(); + assert_eq!(codes.len(), Reason::ALL.len()); + for r in Reason::ALL { + assert_eq!(Reason::from_code(r.code()), Some(r)); + } + } +} diff --git a/wai/wai-rs/src/access_services/corpus.rs b/wai/wai-rs/src/access_services/corpus.rs new file mode 100644 index 000000000..749184fe8 --- /dev/null +++ b/wai/wai-rs/src/access_services/corpus.rs @@ -0,0 +1,718 @@ +//! The conformance corpus of extensions/access-services.md §11: `live-conformance/access/`. +//! +//! [`generate`] writes it from fixed seeds: every key, model, track and object digest is +//! SHA-256 of a fixed label and an index, the room id likewise, every time is a constant, and +//! Ed25519 signing is deterministic (RFC 8032), so every file is the same bytes on every +//! machine. Each vector is written with the outcome it is meant to have, and the generator +//! asserts, before it writes them, that this module gives it that outcome and that every +//! reason of §10 refuses a vector. +//! +//! [`verify`] checks a corpus directory's files against this module. +//! `live-conformance/access_services_verify.py` checks the same files from the extension's +//! text, sharing no code with this module. + +use super::*; +use crate::capture_take::{phase, Commit}; +use crate::live_events::{kind, Caption, Event}; +use crate::timed_text::{origin, Anchor, Annotation}; +use std::collections::BTreeMap; + +/// The media time of the room's `t0`, in milliseconds. +pub const PT0_MS: u64 = 10_000; +/// The offset of the lesson's take: a device-clock instant *d* is the room-clock *d* + this. +pub const TAKE_OFFSET: i64 = -499_000_000; + +const CAPTIONER: u8 = 1; +const ASR: u8 = 2; +const HOST: u8 = 3; +const DEVICE: u8 = 4; +const ALIGNER: u8 = 5; +const REVIEWER: u8 = 6; +const DESCRIBER: u8 = 7; +const INTERPRETER: u8 = 8; +const VENDOR: u8 = 9; +const AUTHORITY: u8 = 10; +const NAMES: [(&str, u8); 10] = [ + ("captioner", CAPTIONER), + ("asr", ASR), + ("host", HOST), + ("device", DEVICE), + ("aligner", ALIGNER), + ("reviewer", REVIEWER), + ("describer", DESCRIBER), + ("interpreter", INTERPRETER), + ("vendor", VENDOR), + ("authority", AUTHORITY), +]; + +const VOICING_URI: &str = "https://media.example/lesson/description.mp4"; +const VOICING_TYPE: &str = "audio/mp4"; + +fn label(l: &[u8], i: &[u8]) -> [u8; 32] { + sha(&[b"wai:access/corpus/", l, b"\x00", i]) +} + +fn key(i: u8) -> SigningKey { + SigningKey::from_bytes(&label(b"key", &[i])) +} + +fn pk(i: u8) -> [u8; 32] { + key(i).verifying_key().to_bytes() +} + +/// The room every vector's events belong to. +pub fn room() -> [u8; 32] { + label(b"room", &[1]) +} + +fn model(i: u8) -> [u8; 32] { + label(b"model", &[i]) +} + +fn track(i: u8) -> [u8; 32] { + label(b"track", &[i]) +} + +fn object(a: u8, b: u8) -> [u8; 32] { + label(b"object", &[a, b]) +} + +/// A digest that names nothing the corpus holds. +fn nothing(i: u8) -> [u8; 32] { + label(b"nothing", &[i]) +} + +fn h(b: &[u8; 32]) -> Value { + Value::String(hex(b)) +} + +/// A principal emitting its chain. +struct Author { + key: SigningKey, + seq: u64, + prev: [u8; 32], +} + +impl Author { + fn new(i: u8) -> Self { + Author { key: key(i), seq: 0, prev: [0; 32] } + } + + fn raw(&mut self, out: &mut Vec>, t: u64, k: u8, payload: Vec) -> [u8; 32] { + let ev = Event::sign(&self.key, room(), self.seq, self.prev, t, None, k, payload); + self.seq += 1; + self.prev = ev.digest(); + out.push(ev.to_bytes()); + self.prev + } + + #[allow(clippy::too_many_arguments)] + fn caption(&mut self, out: &mut Vec>, t: u64, d: u32, o: u8, m: Option<[u8; 32]>, text: &str) -> [u8; 32] { + let c = Caption { duration_ms: d, origin: o, model: m, lang: "en".into(), text: text.into() }; + self.raw(out, t, kind::CAPTION, Payload::Caption(c).encode()) + } + + fn annotate(&mut self, out: &mut Vec>, t: u64, supersedes: [u8; 32], final_: bool, stable: &str) -> [u8; 32] { + let a = Annotation { supersedes, final_, stable_cp: stable.chars().count() as u16, anchor: Anchor::BottomCenter, italic: vec![] }; + self.raw(out, t, kind::META, a.to_bytes()) + } +} + +/// The digests of a stream's events that records name. +type Digests = BTreeMap<&'static str, [u8; 32]>; + +/// A defect of the lesson's stream. +#[derive(Clone, Copy, PartialEq, Eq)] +enum StreamDefect { + None, + /// The captioner's second event names a `prev` that is not its first's. + ChainBroken, + /// An annotation of the machine captions supersedes a revision no one wrote. + SupersedeUnknown, + /// The machine captions' second cue's partial and its annotation are not delivered. + Gap, +} + +/// The lesson: a human captioner, machine captions revised to final, and a take whose +/// opening commitment places the machine captions' words. +fn lesson_stream(defect: StreamDefect) -> (Vec>, Digests) { + let s = 1_000_000u64; + let mut out = Vec::new(); + let mut d = Digests::new(); + let (mut cap, mut asr, mut host, mut dev) = (Author::new(CAPTIONER), Author::new(ASR), Author::new(HOST), Author::new(DEVICE)); + let m1 = Some(model(1)); + let start = host.raw(&mut out, s, kind::CONTROL, Payload::Control { target: pk(DEVICE), command: Command::RecordStart { count_in_ms: 0 } }.encode()); + let take = take_id(&room(), &pk(DEVICE), &start); + d.insert("take", take); + let commit = + Commit { take, n: 0, phase: phase::OPEN, prev: [0; 32], first: 0, size: 0, root: [0; 32], offset: TAKE_OFFSET, proof: vec![] }; + dev.raw(&mut out, s, kind::TAKE_COMMIT, Payload::TakeCommit(commit.encode()).encode()); + d.insert("cap1", cap.caption(&mut out, 2 * s, 2500, origin::HUMAN, None, "Good morning, everyone.")); + let a0 = asr.caption(&mut out, 3_200_000, 0, origin::MACHINE, m1, "the moon pulls"); + d.insert("asrA0", a0); + asr.annotate(&mut out, 3_200_000, [0; 32], false, "the moon "); + let a1 = asr.caption(&mut out, 3_900_000, 0, origin::MACHINE, m1, "the moon pulls the see"); + d.insert("asrA1", a1); + let sup = if defect == StreamDefect::SupersedeUnknown { nothing(6) } else { a0 }; + asr.annotate(&mut out, 3_900_000, sup, false, "the moon pulls "); + let a2 = asr.caption(&mut out, 4_600_000, 2000, origin::MACHINE, m1, "the moon pulls the sea."); + d.insert("asrA2", a2); + asr.annotate(&mut out, 4_600_000, a1, true, "the moon pulls the sea."); + if defect == StreamDefect::ChainBroken { + cap.prev = nothing(9); + } + d.insert("cap2", cap.caption(&mut out, 5 * s, 3000, origin::HUMAN, None, "Today we look at tides.")); + let before_gap = out.len(); + let b0 = asr.caption(&mut out, 6_500_000, 0, origin::MACHINE, m1, "high tied"); + d.insert("asrB0", b0); + asr.annotate(&mut out, 6_500_000, [0; 32], false, "high "); + let b1 = asr.caption(&mut out, 7_300_000, 2500, origin::MACHINE, m1, "high tide comes twice day."); + d.insert("asrB1", b1); + asr.annotate(&mut out, 7_300_000, b0, true, "high tide comes twice day."); + d.insert("cap3", cap.caption(&mut out, 9 * s, 2000, origin::HUMAN, None, "[Waves crash]")); + if defect == StreamDefect::Gap { + out.drain(before_gap..before_gap + 2); + } + (out, d) +} + +/// A session whose machine captions a person reviews before they are final. +fn reviewed_stream() -> (Vec>, Digests) { + let mut out = Vec::new(); + let mut d = Digests::new(); + let mut asr = Author::new(ASR); + let m1 = Some(model(1)); + let a0 = asr.caption(&mut out, 1_500_000, 0, origin::MACHINE, m1, "welcome to the"); + d.insert("A0", a0); + asr.annotate(&mut out, 1_500_000, [0; 32], false, "welcome "); + d.insert("A1", asr.caption(&mut out, 2_400_000, 3000, origin::REVIEWED, m1, "welcome to the reef tour.")); + asr.annotate(&mut out, 2_400_000, a0, true, "welcome to the reef tour."); + d.insert("B0", asr.caption(&mut out, 6_000_000, 2500, origin::REVIEWED, m1, "Corals are animals.")); + (out, d) +} + +fn body(v: Value) -> Map { + v.as_object().expect("a record body is an object").clone() +} + +fn signed(signer: u8, v: Value) -> Value { + sign(&key(signer), body(v)) +} + +/// A defect of a lesson's records, each the control of one rule. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Defect { + None, + LatencyMisstated, + DescriptionLate, + DescriptionEarly, + DescriptionRunsOn, + SignUnknownRevision, + ClaimMissingTrack, + DuplicateMember, + NegativeNumber, + FlippedSignature, + WeakKey, + WrongRoom, + SecondSources, + SourceNotAHead, + SourceUnknownTake, + ReferenceSpaces, + ReferenceUnknownCue, + ReferenceMissingCue, + QualityWithoutReference, + DescriptionOverlap, + SigningEmptySegment, + ReviewUnknownSigning, + ClaimEmptySession, + DescriptionUnvoiced, + ClaimWrongLanguage, + LatencyAboveBound, + ReviewNotGiven, + ReviewOfAnother, + ReviewRejected, + CaptionsOfNoOne, + SignOffsetAboveBound, + /// Only the captioner's quality record and a claim without latency bounds. + Unplaced, +} + +/// The lesson's records, with one defect: (records, the index of the description record). +fn lesson_records(events: &[Vec], d: &Digests, defect: Defect) -> (Vec, usize) { + let r = hex(&room()); + let mut records: Vec = Vec::new(); + let mut texts: Vec> = Vec::new(); + let push = |records: &mut Vec, texts: &mut Vec>, v: Value| { + records.push(v); + texts.push(None); + }; + if defect == Defect::Unplaced { + let q = quality(events, &[], CAPTIONER); + let claim = signed( + AUTHORITY, + json!({"kind": kinds::CLAIM, "room": r, "from": 0, "to": 12_000_000, "pt0": PT0_MS, "tracks": [ + {"service": "captions", "principal": h(&pk(CAPTIONER)), "lang": "en", "latency_mean_max": null, "latency_max": null}]}), + ); + return (vec![text(&q), text(&claim)], usize::MAX); + } + // 0: the captioner's sources, on the room clock. + let src_room = if defect == Defect::WrongRoom { hex(¬hing(1)) } else { r.clone() }; + let mut cap_sources = json!({"kind": kinds::SOURCES, "room": src_room, "principal": h(&pk(CAPTIONER)), "sources": [ + {"cue": h(&d["cap1"]), "basis": "room", "take": null, "start": 1_400_000, "end": 1_900_000}, + {"cue": h(&d["cap2"]), "basis": "room", "take": null, "start": 3_900_000, "end": 4_800_000}, + {"cue": h(&d["cap3"]), "basis": "room", "take": null, "start": 8_500_000, "end": 8_900_000}]}); + if defect == Defect::NegativeNumber { + cap_sources["sources"][0]["start"] = json!(0); + } + push(&mut records, &mut texts, signed(ALIGNER, cap_sources)); + if defect == Defect::NegativeNumber { + let t = text(&records[0]).replacen("\"start\":0", "\"start\":-1", 1); + texts[0] = Some(t); + } + // 1: the machine captions' sources, on the take. + let base = (-TAKE_OFFSET) as u64; + let a_cue = if defect == Defect::SourceNotAHead { d["asrA1"] } else { d["asrA0"] }; + let take = if defect == Defect::SourceUnknownTake { nothing(2) } else { d["take"] }; + let asr_sources = json!({"kind": kinds::SOURCES, "room": r, "principal": h(&pk(ASR)), "sources": [ + {"cue": h(&a_cue), "basis": "take", "take": h(&take), "start": base + 2_400_000, "end": base + 4_400_000}, + {"cue": h(&d["asrB0"]), "basis": "take", "take": h(&take), "start": base + 5_600_000, "end": base + 7_000_000}]}); + push(&mut records, &mut texts, signed(ALIGNER, asr_sources.clone())); + if defect == Defect::SecondSources { + push(&mut records, &mut texts, signed(REVIEWER, asr_sources)); + } + // 2: the reference transcript of the machine captions. + let mut entries = vec![ + json!({"cue": h(&d["asrA0"]), "text": if defect == Defect::ReferenceSpaces { "The moon pulls the sea." } else { "The moon pulls the sea." }}), + ]; + if defect != Defect::ReferenceMissingCue { + entries.push(json!({"cue": h(&d["asrB0"]), "text": "High tide comes twice a day."})); + } + if defect == Defect::ReferenceUnknownCue { + entries.push(json!({"cue": h(¬hing(3)), "text": "Spring tides."})); + } + push( + &mut records, + &mut texts, + signed(REVIEWER, json!({"kind": kinds::REFERENCE, "room": r, "principal": h(&pk(ASR)), "entries": entries})), + ); + // 3: the description, voiced on a track by a synthesized voice. + let mut d1 = json!({"id": "d1", "begin": 10_500, "end": 11_900, "represents": "visual.nonText", + "text": "A teacher stands beside a tide chart.", "duck": {"gain": 400, "ramp": 200}, "voice": {"begin": 10_720, "end": 11_690}}); + match defect { + Defect::DescriptionLate => d1["voice"]["begin"] = json!(10_746), + Defect::DescriptionEarly => d1["voice"]["begin"] = json!(10_664), + Defect::DescriptionRunsOn => d1["voice"]["end"] = json!(11_746), + _ => {} + } + let mut d2 = json!({"id": "d2", "begin": 15_200, "end": 16_000, "represents": "visual.text", + "text": "On the board: HIGH TIDE 06:10.", "duck": {"gain": 1000, "ramp": 0}, "voice": {"begin": 15_210, "end": 15_990}}); + if defect == Defect::DescriptionOverlap { + d2["begin"] = json!(11_800); + d2["voice"] = Value::Null; + } + if defect == Defect::DescriptionUnvoiced { + d2["voice"] = Value::Null; + } + let description = signed( + DESCRIBER, + json!({"kind": kinds::DESCRIPTION, "lang": "en", "script": {"origin": "human", "model": null}, + "voicing": {"form": "track", "origin": "machine", "model": h(&model(2)), "track": h(&track(1))}, "events": [d1, d2]}), + ); + let description_at = records.len(); + if defect != Defect::ClaimMissingTrack { + push(&mut records, &mut texts, description.clone()); + } + let description_id = record_id(&description); + // 4: the signing, motion-captured from a person, bound to the human captions. + let mut seg1 = json!({"object": h(&object(1, 1)), "start": 2_600_000, "end": 4_800_000, "revisions": [h(&d["cap1"])]}); + if defect == Defect::SignUnknownRevision { + seg1["revisions"] = json!([h(¬hing(4))]); + } + if defect == Defect::SigningEmptySegment { + seg1["end"] = json!(2_600_000); + } + let signing_body = json!({"kind": kinds::SIGNING, "room": r, "lang": "bfi", "source": h(&pk(CAPTIONER)), "form": "pose", + "track": h(&track(2)), "origin": "human", "model": null, "video": null, "segments": [seg1, + {"object": h(&object(1, 2)), "start": 5_700_000, "end": 8_800_000, "revisions": [h(&d["cap2"])]}, + {"object": h(&object(1, 3)), "start": 9_300_000, "end": 11_000_000, "revisions": [h(&d["cap3"])]}]}); + let signing = signed(INTERPRETER, signing_body.clone()); + push(&mut records, &mut texts, signing.clone()); + let signing_id = record_id(&signing); + // 5: the review of the signing. + let mut reviewed = signing_id; + if defect == Defect::ReviewOfAnother { + let mut other = signing_body; + other["track"] = h(&track(3)); + let other = signed(INTERPRETER, other); + reviewed = record_id(&other); + push(&mut records, &mut texts, other); + } + if defect == Defect::ReviewUnknownSigning { + reviewed = nothing(5); + } + let (verdict, notes) = if defect == Defect::ReviewRejected { ("rejected", h(¬hing(7))) } else { ("approved", Value::Null) }; + let review = signed(REVIEWER, json!({"kind": kinds::REVIEW, "signing": h(&reviewed), "scope": "translation", "verdict": verdict, "notes": notes})); + let review_at = records.len(); + if defect != Defect::ReviewNotGiven { + push(&mut records, &mut texts, review.clone()); + } + let review_id = record_id(&review); + match defect { + Defect::DuplicateMember => { + let t = text(&review); + texts[review_at] = Some(t.replacen("\"verdict\":\"approved\"", "\"verdict\":\"approved\",\"verdict\":\"rejected\"", 1)); + } + Defect::FlippedSignature => { + let mut v = review.clone(); + let mut s = v["sig"].as_str().expect("a signature").to_string(); + let last = if s.ends_with('0') { "1" } else { "0" }; + s.replace_range(s.len() - 1.., last); + v["sig"] = Value::String(s); + texts[review_at] = Some(text(&v)); + } + Defect::WeakKey => { + let mut v = review.clone(); + v["signer_pubkey"] = h(&crate::sig::IDENTITY); + texts[review_at] = Some(text(&v)); + } + _ => {} + } + // 6, 7: the quality records of both caption tracks, computed from what comes before. + // A defect the checks before the quality records refuse leaves them unread: they are the + // lesson's own then. + let so_far: Vec = records.iter().map(text).collect(); + let (cap_q, mut asr_q) = match super::verify(room(), events, &so_far) { + Outcome::Accept(_) => (quality(events, &so_far, CAPTIONER), quality(events, &so_far, ASR)), + Outcome::Refuse { .. } => { + let base = lesson_records(events, d, Defect::None).0; + (read(&base[6]).expect("a record").value, read(&base[7]).expect("a record").value) + } + }; + push(&mut records, &mut texts, cap_q); + if defect == Defect::LatencyMisstated { + asr_q["latency"]["mean"] = json!("850001"); + asr_q = signed(VENDOR, strip(asr_q)); + } + if defect == Defect::QualityWithoutReference { + asr_q["reference"] = Value::Null; + asr_q = signed(VENDOR, strip(asr_q)); + } + push(&mut records, &mut texts, asr_q); + // 8: the claim. + let (from, to) = if defect == Defect::ClaimEmptySession { (12_000_000, 12_000_000) } else { (0, 12_000_000) }; + let asr_max = if defect == Defect::LatencyAboveBound { json!(850_000) } else { json!(3_000_000) }; + let cap_principal = if defect == Defect::CaptionsOfNoOne { pk(HOST) } else { pk(CAPTIONER) }; + let ad_lang = if defect == Defect::ClaimWrongLanguage { "fr" } else { "en" }; + let offset_max = if defect == Defect::SignOffsetAboveBound { 1_500_000 } else { 4_000_000 }; + let claim = signed( + AUTHORITY, + json!({"kind": kinds::CLAIM, "room": r, "from": from, "to": to, "pt0": PT0_MS, "tracks": [ + {"service": "captions", "principal": h(&cap_principal), "lang": "en", "latency_mean_max": 4_500_000, "latency_max": null}, + {"service": "captions", "principal": h(&pk(ASR)), "lang": "en", "latency_mean_max": 4_500_000, "latency_max": asr_max}, + {"service": "audio-description", "record": h(&description_id), "lang": ad_lang}, + {"service": "sign-language", "record": h(&signing_id), "lang": "bfi", "review": h(&review_id), "offset_max": offset_max}]}), + ); + push(&mut records, &mut texts, claim); + let out = records.iter().zip(texts).map(|(v, t)| t.unwrap_or_else(|| text(v))).collect(); + (out, description_at) +} + +/// A record's body: without `signer_pubkey` and `sig`. +fn strip(v: Value) -> Value { + let mut m = body(v); + m.remove("signer_pubkey"); + m.remove("sig"); + Value::Object(m) +} + +/// The quality record of `p`'s track, stating the figure this module computes over `events` +/// and `records`. +fn quality(events: &[Vec], records: &[String], p: u8) -> Value { + let Outcome::Accept(f) = super::verify(room(), events, records) else { panic!("the records before a quality record verify") }; + let fig = f["captions"].as_array().expect("figures").iter().find(|x| x["principal"] == h(&pk(p))).expect("a figure").clone(); + let mut m = body(fig); + m.insert("kind".into(), Value::String(kinds::QUALITY.into())); + signed(VENDOR, Value::Object(m)) +} + +/// A defect of the reviewed session's records. +#[derive(Clone, Copy, PartialEq, Eq)] +enum ReviewedDefect { + None, + SignPartial, + LatencyBoundUnmeasured, +} + +/// The reviewed session's records: a description the sink voices, the video of a signer, a +/// quality record and a claim without latency bounds. +fn reviewed_records(events: &[Vec], d: &Digests, defect: ReviewedDefect) -> Vec { + let r = hex(&room()); + let description = signed( + DESCRIBER, + json!({"kind": kinds::DESCRIPTION, "lang": "en", "script": {"origin": "machine", "model": h(&model(3))}, + "voicing": {"form": "sink", "origin": "machine-reviewed", "model": h(&model(4)), "track": null}, "events": [ + {"id": "r1", "begin": 11_000, "end": 12_200, "represents": "visual.nonText", "text": "Divers swim over a reef.", + "duck": {"gain": 500, "ramp": 150}, "voice": null}, + {"id": "r2", "begin": 14_000, "end": 15_000, "represents": "visual.text.title", "text": "Title:\nReef Tour & Co.", + "duck": {"gain": 1000, "ramp": 0}, "voice": null}]}), + ); + let first = if defect == ReviewedDefect::SignPartial { d["A0"] } else { d["A1"] }; + let signing = signed( + INTERPRETER, + json!({"kind": kinds::SIGNING, "room": r, "lang": "ase", "source": h(&pk(ASR)), "form": "video", "track": h(&track(4)), + "origin": "machine", "model": h(&model(5)), "video": {"width": 640, "height": 360, "rate_num": 25, "rate_den": 1}, + "segments": [ + {"object": h(&object(2, 1)), "start": 3_000_000, "end": 5_000_000, "revisions": [h(&first)]}, + {"object": h(&object(2, 2)), "start": 6_500_000, "end": 8_200_000, "revisions": [h(&d["B0"])]}]}), + ); + let mut records = vec![text(&description), text(&signing)]; + let q = quality(events, &[], ASR); + records.push(text(&q)); + let bound = if defect == ReviewedDefect::LatencyBoundUnmeasured { json!(4_500_000) } else { Value::Null }; + let claim = signed( + AUTHORITY, + json!({"kind": kinds::CLAIM, "room": r, "from": 0, "to": 10_000_000, "pt0": PT0_MS, "tracks": [ + {"service": "captions", "principal": h(&pk(ASR)), "lang": "en", "latency_mean_max": bound, "latency_max": null}, + {"service": "audio-description", "record": h(&record_id(&description)), "lang": "en"}, + {"service": "sign-language", "record": h(&record_id(&signing)), "lang": "ase", "review": null, "offset_max": null}]}), + ); + records.push(text(&claim)); + records +} + +struct Vector { + name: &'static str, + note: &'static str, + stream: &'static str, + records: Vec, + /// The reason it is written to be refused with, or `None` for accept. + want: Option<&'static str>, +} + +fn vectors(streams: &BTreeMap<&'static str, (Vec>, Digests)>) -> (Vec, usize, usize) { + let lesson = &streams["lesson"]; + let reviewed = &streams["reviewed"]; + let mut out = Vec::new(); + let (lesson_records_base, lesson_desc) = lesson_records(&lesson.0, &lesson.1, Defect::None); + out.push(Vector { + name: "lesson", + note: "a human captioner, machine captions revised to final and placed by a take, a reference transcript, a quality record for each track, a description voiced on a track by a synthesized voice, a motion-captured signer bound to the human captions with an approved review, and a claim held to the 2024 statement's mean", + stream: "lesson", + records: lesson_records_base, + want: None, + }); + out.push(Vector { + name: "reviewed", + note: "machine captions a person reviews before they are final, a description the sink voices with a pinned model, the video of a generated signer, and a claim without latency bounds", + stream: "reviewed", + records: reviewed_records(&reviewed.0, &reviewed.1, ReviewedDefect::None), + want: None, + }); + out.push(Vector { + name: "unplaced", + note: "no sources: the latency's class is none, and a claim with no latency bound holds", + stream: "lesson", + records: lesson_records(&lesson.0, &lesson.1, Defect::Unplaced).0, + want: None, + }); + let negatives: [(&'static str, &'static str, Defect, &'static str); 30] = [ + ("latency_misstated", "the machine captions' quality record states a mean latency one microsecond above the recomputed one", Defect::LatencyMisstated, "figure_mismatch"), + ("description_late", "a description's voice starts 46 ms after the programme audio has fallen", Defect::DescriptionLate, "description_out_of_sync"), + ("description_early", "a description's voice starts 36 ms before the programme audio has fallen", Defect::DescriptionEarly, "description_out_of_sync"), + ("description_runs_on", "a description's voice ends 46 ms after the programme audio has risen", Defect::DescriptionRunsOn, "description_out_of_sync"), + ("sign_unknown_revision", "the signing names a caption revision the stream does not hold", Defect::SignUnknownRevision, "sign_revision_unknown"), + ("claim_missing_track", "the claim declares a description the verifier does not hold", Defect::ClaimMissingTrack, "track_missing"), + ("duplicate_member", "the review names its verdict twice", Defect::DuplicateMember, "record_malformed"), + ("negative_number", "a source's start is a negative number", Defect::NegativeNumber, "record_malformed"), + ("flipped_signature", "a bit of the review's signature is flipped", Defect::FlippedSignature, "bad_signature"), + ("weak_key", "the review's key is the identity point", Defect::WeakKey, "bad_key"), + ("wrong_room", "the captioner's sources name another room", Defect::WrongRoom, "wrong_room"), + ("second_sources", "a second sources record for the machine captions", Defect::SecondSources, "record_conflict"), + ("source_not_a_head", "a source names a later revision, not a cue's first", Defect::SourceNotAHead, "source_unknown"), + ("source_unknown_take", "a source names a take with no opening commitment", Defect::SourceUnknownTake, "source_take_unknown"), + ("reference_spaces", "a reference text holds two spaces in a row", Defect::ReferenceSpaces, "text_not_in_subset"), + ("reference_unknown_cue", "the reference names a cue the stream does not hold", Defect::ReferenceUnknownCue, "reference_unknown"), + ("reference_missing_cue", "the reference leaves a cue out", Defect::ReferenceMissingCue, "reference_incomplete"), + ("quality_without_reference", "the quality record names no reference while the track has one", Defect::QualityWithoutReference, "figure_inputs_mismatch"), + ("description_overlap", "a description begins before the one before it ends", Defect::DescriptionOverlap, "description_malformed"), + ("signing_empty_segment", "a signing segment ends where it starts", Defect::SigningEmptySegment, "signing_malformed"), + ("review_unknown_signing", "the review names a signing record the verifier does not hold", Defect::ReviewUnknownSigning, "review_subject_unknown"), + ("claim_empty_session", "the claim's session ends where it starts", Defect::ClaimEmptySession, "claim_malformed"), + ("description_unvoiced", "a description on a voicing track has an event the track does not voice", Defect::DescriptionUnvoiced, "track_incomplete"), + ("claim_wrong_language", "the claim declares the description in another language", Defect::ClaimWrongLanguage, "track_mismatch"), + ("latency_above_bound", "the claim holds the machine captions to a latency of at most 850 ms; one cue's is 900 ms", Defect::LatencyAboveBound, "out_of_sync"), + ("review_not_given", "the claim names a review the verifier does not hold", Defect::ReviewNotGiven, "review_missing"), + ("review_of_another", "the claim's review approves another signing record", Defect::ReviewOfAnother, "review_mismatch"), + ("review_rejected", "the claim's review rejects the signing", Defect::ReviewRejected, "review_rejected"), + ("captions_of_no_one", "the claim declares captions by a principal with none", Defect::CaptionsOfNoOne, "track_missing"), + ("sign_offset_above_bound", "the claim holds the signing to 1.5 s behind the speech; one segment is 1.8 s behind", Defect::SignOffsetAboveBound, "out_of_sync"), + ]; + for (name, note, defect, want) in negatives { + out.push(Vector { name, note, stream: "lesson", records: lesson_records(&lesson.0, &lesson.1, defect).0, want: Some(want) }); + } + let base = lesson_records(&lesson.0, &lesson.1, Defect::None).0; + out.push(Vector { name: "chain_broken", note: "the captioner's second caption names a prev that is not its first's", stream: "chain_broken", records: base.clone(), want: Some("chain_broken") }); + out.push(Vector { name: "supersede_unknown", note: "a machine revision supersedes a revision no one wrote", stream: "supersede_unknown", records: base.clone(), want: Some("supersede_unknown") }); + out.push(Vector { name: "undelivered_revisions", note: "the machine captions' second cue's partial and its annotation are not delivered, so the track is not whole", stream: "gap", records: base, want: Some("stream_incomplete") }); + out.push(Vector { name: "sign_partial", note: "the signing is bound to a partial a later revision superseded", stream: "reviewed", records: reviewed_records(&reviewed.0, &reviewed.1, ReviewedDefect::SignPartial), want: Some("sign_revision_not_final") }); + out.push(Vector { name: "latency_unmeasured", note: "the claim bounds the latency of captions no sources record places", stream: "reviewed", records: reviewed_records(&reviewed.0, &reviewed.1, ReviewedDefect::LatencyBoundUnmeasured), want: Some("sync_unmeasured") }); + (out, lesson_desc, 0) +} + +fn streams() -> BTreeMap<&'static str, (Vec>, Digests)> { + let mut m = BTreeMap::new(); + m.insert("lesson", lesson_stream(StreamDefect::None)); + m.insert("reviewed", reviewed_stream()); + m.insert("chain_broken", lesson_stream(StreamDefect::ChainBroken)); + m.insert("supersede_unknown", lesson_stream(StreamDefect::SupersedeUnknown)); + m.insert("gap", lesson_stream(StreamDefect::Gap)); + m +} + +fn outcome_json(o: &Outcome) -> Value { + match o { + Outcome::Accept(f) => json!({"outcome": "accept", "figures": f}), + Outcome::Refuse { at, index, reason } => json!({"outcome": "refuse", "at": at, "index": index, "reason": reason}), + } +} + +/// The corpus files, as (path relative to the corpus directory, contents), in order; +/// `vectors.json` first. +pub fn generate() -> Vec<(String, String)> { + let streams = streams(); + let (vectors, lesson_desc, reviewed_desc) = vectors(&streams); + let mut files: Vec<(String, String)> = Vec::new(); + let mut seen = BTreeSet::new(); + let mut vs = Vec::new(); + for v in &vectors { + let o = super::verify(room(), &streams[v.stream].0, &v.records); + match (&o, v.want) { + (Outcome::Accept(_), None) => {} + (Outcome::Refuse { reason, .. }, Some(w)) if *reason == w => { + seen.insert(w); + } + _ => panic!("{}: written to be {:?}, this module gives {o:?}", v.name, v.want), + } + let mut j = json!({"name": v.name, "note": v.note, "stream": v.stream, "records": v.records}); + for (k, x) in body(outcome_json(&o)) { + j[k] = x; + } + vs.push(j); + } + let mut documents = Vec::new(); + for (name, at, params) in [("lesson", lesson_desc, Some((VOICING_URI, VOICING_TYPE))), ("reviewed", reviewed_desc, None)] { + let v = vectors.iter().find(|v| v.name == name).expect("an accepted vector"); + let r = read(&v.records[at]).expect("a description record"); + let (uri, ty) = params.unwrap_or(("", "")); + let doc = dapt(&r.value, uri, ty).expect("a DAPT document"); + let file = format!("{name}.dapt.ttml"); + let (uri, ty) = match params { + Some((u, t)) => (json!(u), json!(t)), + None => (Value::Null, Value::Null), + }; + documents.push(json!({"vector": name, "record": at, "uri": uri, "type": ty, "file": file})); + files.push((file, doc)); + } + for (uri, ty) in [("https://media.example/a\"b", VOICING_TYPE), (VOICING_URI, "")] { + let v = &vectors[0]; + let r = read(&v.records[lesson_desc]).expect("a description record"); + let reason = dapt(&r.value, uri, ty).expect_err("a parameter refused").code(); + seen.insert(reason); + documents.push(json!({"vector": "lesson", "record": lesson_desc, "uri": uri, "type": ty, "reason": reason})); + } + for r in Reason::ALL { + assert!(seen.contains(r.code()), "no vector is refused {}", r.code()); + } + let doc = json!({ + "corpus": "wai.access.services", + "extension": "extensions/access-services.md", + "room": hex(&room()), + "pt0_ms": PT0_MS, + "principals": NAMES.iter().map(|(n, i)| (n.to_string(), json!(hex(&pk(*i))))).collect::>(), + "streams": streams.iter().map(|(n, (e, _))| (n.to_string(), json!(e.iter().map(|b| hex(b)).collect::>()))).collect::>(), + "vectors": vs, + "documents": documents, + }); + let mut out = vec![("vectors.json".to_string(), serde_json::to_string_pretty(&doc).expect("the corpus serialises") + "\n")]; + out.extend(files); + let fails = verify_files(&out.iter().cloned().collect()); + assert!(fails.is_empty(), "the generated corpus does not verify:\n{}", fails.join("\n")); + out +} + +fn unhex_bytes(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() +} + +/// Check a corpus directory's files (name → contents) against this module: every vector's +/// outcome, place, reason and figures, and every DAPT document. Returns the failures. +pub fn verify_files(files: &BTreeMap) -> Vec { + let mut fails = Vec::new(); + let Some(doc) = files.get("vectors.json") else { return vec!["no vectors.json".into()] }; + let root: Value = match serde_json::from_str(doc) { + Ok(v) => v, + Err(e) => return vec![format!("vectors.json does not parse: {e}")], + }; + let room_id = unhex::<32>(root["room"].as_str().unwrap_or("")).unwrap_or([0; 32]); + let mut streams: BTreeMap>> = BTreeMap::new(); + for (n, e) in root["streams"].as_object().into_iter().flatten() { + let evs: Option>> = e.as_array().into_iter().flatten().map(|x| x.as_str().and_then(unhex_bytes)).collect(); + match evs { + Some(evs) => { + streams.insert(n.clone(), evs); + } + None => fails.push(format!("stream {n} does not read")), + } + } + let mut records_of: BTreeMap> = BTreeMap::new(); + for v in root["vectors"].as_array().into_iter().flatten() { + let name = v["name"].as_str().unwrap_or("?").to_string(); + let Some(events) = v["stream"].as_str().and_then(|s| streams.get(s)) else { + fails.push(format!("{name}: names no stream the corpus holds")); + continue; + }; + let records: Vec = v["records"].as_array().into_iter().flatten().filter_map(|r| r.as_str().map(String::from)).collect(); + let got = outcome_json(&super::verify(room_id, events, &records)); + for k in ["outcome", "at", "index", "reason", "figures"] { + let (g, w) = (got.get(k).unwrap_or(&Value::Null), v.get(k).unwrap_or(&Value::Null)); + if g != w { + fails.push(format!("{name}: {k}: {w} is stated, this module gives {g}")); + } + } + records_of.insert(name, records); + } + for d in root["documents"].as_array().into_iter().flatten() { + let vname = d["vector"].as_str().unwrap_or("?"); + let at = d["record"].as_u64().unwrap_or(u64::MAX) as usize; + let Some(text) = records_of.get(vname).and_then(|r| r.get(at)) else { + fails.push(format!("document of {vname}: names no record")); + continue; + }; + let rec = match read(text) { + Ok(r) if r.kind == kinds::DESCRIPTION => r, + _ => { + fails.push(format!("document of {vname}: record {at} is not a description")); + continue; + } + }; + let got = dapt(&rec.value, d["uri"].as_str().unwrap_or(""), d["type"].as_str().unwrap_or("")); + match (got, d["file"].as_str(), d["reason"].as_str()) { + (Ok(doc), Some(f), None) => { + if files.get(f) != Some(&doc) { + fails.push(format!("document of {vname}: {f} differs from this module's")); + } + } + (Err(e), None, Some(r)) if e.code() == r => {} + (g, f, r) => fails.push(format!("document of {vname}: the corpus states {f:?} / {r:?}, this module gives {:?}", g.map(|_| "a document"))), + } + } + fails +} + +/// The corpus check of a directory's files: [`verify_files`]. +pub fn verify(files: &BTreeMap) -> Vec { + verify_files(files) +} diff --git a/wai/wai-rs/src/bin/wai_access_services_vectors.rs b/wai/wai-rs/src/bin/wai_access_services_vectors.rs new file mode 100644 index 000000000..d20545da9 --- /dev/null +++ b/wai/wai-rs/src/bin/wai_access_services_vectors.rs @@ -0,0 +1,75 @@ +//! Conformance corpus for access services (`live-conformance/access/`, extensions/access-services.md §11). +//! +//! wai_access_services_vectors gen write vectors.json and every expected output +//! (.dapt.ttml), from fixed seeds +//! wai_access_services_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/access_services_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::access_services::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_access_services_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/lib.rs b/wai/wai-rs/src/lib.rs index b1e066f70..a0dae3680 100644 --- a/wai/wai-rs/src/lib.rs +++ b/wai/wai-rs/src/lib.rs @@ -495,6 +495,14 @@ pub mod live_provenance; /// cbindgen:ignore #[cfg(feature = "timed_text")] pub mod timed_text; +// Access services (extensions/access-services.md): `wai.access.services` — caption quality +// (latency, stability, accuracy) recomputed from the signed revisions, audio description with +// its mixing, voicing and DAPT document, sign language bound to caption revisions by digest, +// and the completeness claim of a room session. Rust-only, like timed_text: its constants +// must not become macros in include/wai.h. +/// cbindgen:ignore +#[cfg(feature = "access_services")] +pub mod access_services; // Typed receipt classes (extensions/jwp-receipts.md §2.4.3–§2.4.12, §2.6, §3.1–§3.2): // energy, lawful-basis, log-inclusion, soft-binding, binding-recovery, measurement, diff --git a/wai/wai-rs/tests/access_services.rs b/wai/wai-rs/tests/access_services.rs new file mode 100644 index 000000000..a74d7c5af --- /dev/null +++ b/wai/wai-rs/tests/access_services.rs @@ -0,0 +1,69 @@ +//! `wai.access.services` (extensions/access-services.md): the committed corpus +//! `live-conformance/access/` regenerates byte for byte from its fixed seeds, holds no +//! other file, every vector and document in it gets the outcome it states, every reason of +//! §10 refuses a case, and the extension's §10 lists exactly the reasons the reference +//! reports. +#![cfg(feature = "access_services")] + +use std::collections::{BTreeMap, BTreeSet}; +use std::path::PathBuf; +use wai::access_services::{corpus, Reason}; + +fn wai_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..") +} + +fn committed() -> BTreeMap { + let dir = wai_dir().join("live-conformance/access"); + 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_access_services_vectors gen`"); +} + +#[test] +fn every_case_gets_its_stated_outcome() { + let fails = corpus::verify(&committed()); + assert!(fails.is_empty(), "{}", fails.join("\n")); +} + +/// Every reason of §10 refuses a vector or a document of the committed corpus. +#[test] +fn every_reason_refuses_a_case() { + let files = committed(); + let root: serde_json::Value = serde_json::from_str(&files["vectors.json"]).expect("vectors.json"); + let mut seen = BTreeSet::new(); + for v in root["vectors"].as_array().into_iter().flatten().chain(root["documents"].as_array().into_iter().flatten()) { + if let Some(r) = v["reason"].as_str() { + seen.insert(r.to_string()); + } + } + for r in Reason::ALL { + assert!(seen.contains(r.code()), "no case of the corpus is refused {}", r.code()); + } +} + +/// §10 of the extension lists exactly the codes `Reason` has, each once, in order. +#[test] +fn the_extension_lists_the_reasons() { + let text = std::fs::read_to_string(wai_dir().join("extensions/access-services.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"); +} -- 2.54.0 (Apple Git-157) From 6e747e412ace686e4650bb90a831ebbbab1683e4 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Wed, 21 Oct 2026 12:22:21 -0400 Subject: [PATCH 2/4] access_services_verify.py: the access-services corpus's second implementation Written from the extension's text: records read strictly and their JCS signatures, words and their alignment, the caption figures, description rules and DAPT documents (parsed with xml.etree), signing, reviews and claims; every mutated copy of the corpus must fail. The extension now links synthesis, merged on main, for the origin of a synthesized voice or signer and for its review vocabulary. Co-Authored-By: Claude Opus 5.5 --- wai/extensions/access-services.md | 18 +- .../access_services_verify.py | 990 ++++++++++++++++++ 2 files changed, 1006 insertions(+), 2 deletions(-) create mode 100644 wai/live-conformance/access_services_verify.py diff --git a/wai/extensions/access-services.md b/wai/extensions/access-services.md index ebd137c48..874eecc5c 100644 --- a/wai/extensions/access-services.md +++ b/wai/extensions/access-services.md @@ -70,6 +70,17 @@ track in pose form is a `wai.avatar.pose` world, whose op batches are its object §5); a source on a take is placed on the room clock by the take's clock mapping (capture-binding §9.3). +Relationship to [synthesis](synthesis.md): the origins this extension's records state are a +caption's, which synthesis §1 maps onto its classes. A description voiced or written by a +model, and a signing a model generates, is synthesized media in its sense: class +`synthesized`, step `generate`, with the operation `speech-synthesis` for a voice, and +oversight `fully_autonomous` for origin `machine` or `human_validated` for origin +`machine-reviewed` (synthesis §3.1, §3.2). The publisher of such a track signs its origin +claim there; this extension's label is the same statement, carried where a description or a +signing is read. A review of §6.4 reviews a translation against caption revisions; a review +of one exact reconstruction of a generated track, which every exact sink then shows, is +synthesis §9.1's. + Duties this extension supports: the access services of Directive (EU) 2019/882, Annex I, Section IV(b)(ii) ("subtitles for the deaf and hard of hearing, audio description, spoken subtitles and sign language interpretation … fully transmitted with adequate quality for @@ -520,7 +531,8 @@ meeting them is not a statement about any law. SHOULD let the listener learn whether the script was machine-written. The script's origin and the voicing's are the description's labels, as a caption's origin is its label (timed-text §10.1); a synthesized voice's origin, with the model's digest, is the statement - a synthesized object's origin claim makes of it. + its origin claim makes of it (synthesis §3.1), and a player shows its label as synthesis + §10 has it show a synthesized object's. 6. **Signing under the viewer's control.** A player that shows a signing track MUST let the viewer choose to show it, and SHOULD let the viewer choose its size and position (Directive (EU) 2019/882 Annex I Section IV(b)(ii), "user control of their display"); a pose stream @@ -606,7 +618,9 @@ A person who reviews the translation signs a **review**: Rules: `notes` is `null` exactly when the verdict is `approved` (`record_malformed`), and `signing` is the record id of a signing record the verifier holds (`review_subject_unknown`). The review binds the objects by their digests, so, for a pose stream, every viewer whose sink -is pose-equivalent sees the motion the reviewer approved. +is pose-equivalent sees the motion the reviewer approved. Its vocabulary is synthesis §9.1's +review with the scope `translation`; that review binds one reconstruction of a synthesized +object, and this one binds a signing record to the caption revisions it translates. ## 7. The completeness claim diff --git a/wai/live-conformance/access_services_verify.py b/wai/live-conformance/access_services_verify.py new file mode 100644 index 000000000..af207c084 --- /dev/null +++ b/wai/live-conformance/access_services_verify.py @@ -0,0 +1,990 @@ +#!/usr/bin/env python3 +"""Independent verifier of the access-services corpus (extensions/access-services.md). + +Written from the extension's text. It shares no code with wai-rs, which generates the +corpus, and never runs it. It verifies every event and the captions in it with +timed_text_verify.py (this directory), the timed-text corpus's second implementation, which +verifies events with live_events_verify.py; checks every record's signature with +../claim-conformance/_ed25519.py, WAI's strict Ed25519 rule written from RFC 8032; and writes +everything else from the extension's sections: + +- the records (§2): a strict JSON reading, each record's shape from the tables, its JCS + form, its signature and its record id; +- words and their alignment (§3), with the walk back of §3.2; +- caption quality (§4): the tracks and cues, sources placed through a take's opening + commitment, reference transcripts, latency, stability and accuracy, and the check of a + stated figure; +- audio description (§5): the rules, the synchronisation bounds, the overlap with dialogue, + and the DAPT document, written byte for byte and parsed with xml.etree; +- sign language (§6): the rules, the binding to final revisions, offsets and the video + floor, and reviews; +- the completeness claim (§7) and verification (§8). + +For every vector it requires the outcome, place, reason and figures the corpus states; for +every document, its bytes or its refusal; that every reason of §10 (read from the extension) +refuses a case; and that every mutated copy of the corpus fails. + + python3 -I access_services_verify.py + +Exit status 0 only if every case verifies. Python 3.8 or later; standard library only. +""" +import copy +import hashlib +import json +import os +import re +import sys +import xml.etree.ElementTree as ET + +HERE = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, HERE) +sys.path.insert(0, os.path.join(HERE, "..", "claim-conformance")) +import timed_text_verify as TT # noqa: E402 +import live_events_verify as LEV # noqa: E402 +import _ed25519 as ED # noqa: E402 + +EXTENSION = os.path.join(HERE, "..", "extensions", "access-services.md") +SIGN_DOMAIN = b"wai:access\x01" +MAX_SAFE = (1 << 53) - 1 +MAX_MS = 359999999 +NS_WAI = "tag:transaction.science,2026:wai/access" +NS_TT = "http://www.w3.org/ns/ttml" +NS_TTA = "http://www.w3.org/ns/ttml#audio" +NS_TTP = "http://www.w3.org/ns/ttml#parameter" +NS_DAPTM = "http://www.w3.org/ns/ttml/profile/dapt#metadata" +NS_XML = "http://www.w3.org/XML/1998/namespace" +DAPT_CONTENT = "http://www.w3.org/ns/ttml/profile/dapt1.0/content" +CAPTION, CONTROL, TAKE_COMMIT = 0x0A, 0x09, 0x0C + + +class Refused(Exception): + def __init__(self, reason): + super().__init__(reason) + self.reason = reason + + +def reasons_of_extension(): + """The codes of §10's table, in order.""" + text = open(EXTENSION, encoding="utf-8").read() + at = text.index("\n## 10. Reasons") + end = text.find("\n## ", at + 1) + body = text[at:end if end >= 0 else len(text)] + return [l.split("`")[1] for l in body.split("\n") if l.startswith("| `")] + + +# ---------------------------------------------------------------- §2 records + +class _Bad: + """A JSON number this extension's records may not hold.""" + + +BAD = _Bad() + + +def _no_dupes(pairs): + out = {} + for k, v in pairs: + if k in out: + raise Refused("record_malformed") + out[k] = v + return out + + +def _clean(v, depth): + if depth > 32: + raise Refused("record_malformed") + if isinstance(v, str): + if any(0xD800 <= ord(c) <= 0xDFFF for c in v): + raise Refused("record_malformed") + elif isinstance(v, list): + for x in v: + _clean(x, depth + 1) + elif isinstance(v, dict): + for k, x in v.items(): + _clean(k, depth) + _clean(x, depth + 1) + + +def read_json(text): + """jwp-receipts §3.1 step 1's reading: no BOM, no repeated member, no lone surrogate, at + most 32 levels. A number with a sign, a fraction or an exponent is kept as BAD.""" + if text.startswith(""): + raise Refused("record_malformed") + try: + v = json.loads(text, object_pairs_hook=_no_dupes, + parse_int=lambda s: BAD if s.startswith("-") else int(s), + parse_float=lambda s: BAD, + parse_constant=lambda s: BAD) + except Refused: + raise + except ValueError: + raise Refused("record_malformed") + _clean(v, 1) + return v + + +HEX = re.compile(r"[0-9a-f]*") +SINT = re.compile(r"0|-?[1-9][0-9]*") + + +def is_hex(v, n): + return isinstance(v, str) and len(v) == 2 * n and HEX.fullmatch(v) is not None + + +def is_int(v): + return type(v) is int and 0 <= v <= MAX_SAFE + + +def is_sint(v): + return isinstance(v, str) and SINT.fullmatch(v) is not None and -(1 << 63) <= int(v) < (1 << 63) + + +# A type: "hex32", "hex64", "int", "sint", "str", ("one", [...]), ("obj", table), +# ("arr", type), ("null", type). +ORIGINS = ["human", "machine", "machine-reviewed"] +REPRESENTS = ["visual", "visual.nonText", "visual.text", "visual.text.title", "visual.text.credit", + "visual.text.location", "visual.dialogue"] +SIG = [("signer_pubkey", "hex32"), ("sig", "hex64")] +SOURCES = [("kind", ("one", ["wai-caption-sources"])), ("room", "hex32"), ("principal", "hex32"), + ("sources", ("arr", ("obj", [("cue", "hex32"), ("basis", ("one", ["take", "room"])), ("take", ("null", "hex32")), + ("start", "int"), ("end", "int")])))] + SIG +REFERENCE = [("kind", ("one", ["wai-caption-reference"])), ("room", "hex32"), ("principal", "hex32"), + ("entries", ("arr", ("obj", [("cue", "hex32"), ("text", "str")])))] + SIG +COUNTS = ("obj", [("words", "int"), ("errors", "int"), ("substitutions", "int"), ("deletions", "int"), ("insertions", "int")]) +QUALITY = [("kind", ("one", ["wai-caption-quality"])), ("room", "hex32"), ("principal", "hex32"), ("events", "hex32"), + ("sources", ("null", "hex32")), ("reference", ("null", "hex32")), ("cues", "int"), + ("latency", ("obj", [("class", ("one", ["none", "capture", "stated"])), ("n", "int")] + + [(k, ("null", "sint")) for k in ("min", "max", "mean", "p50", "p95")])), + ("stability", ("obj", [("revisions", "int"), ("words_changed", "int"), ("cues_corrected", "int")])), + ("accuracy", ("obj", [("class", ("one", ["transcript", "reviewed", "self"])), ("first", COUNTS), ("final", ("null", COUNTS))]))] + SIG +DESCRIPTION = [("kind", ("one", ["wai-description"])), ("lang", "str"), + ("script", ("obj", [("origin", ("one", ORIGINS)), ("model", ("null", "hex32"))])), + ("voicing", ("obj", [("form", ("one", ["track", "sink"])), ("origin", ("one", ORIGINS)), + ("model", ("null", "hex32")), ("track", ("null", "hex32"))])), + ("events", ("arr", ("obj", [("id", "str"), ("begin", "int"), ("end", "int"), ("represents", ("one", REPRESENTS)), + ("text", "str"), ("duck", ("obj", [("gain", "int"), ("ramp", "int")])), + ("voice", ("null", ("obj", [("begin", "int"), ("end", "int")])))])))] + SIG +SIGNING = [("kind", ("one", ["wai-signing"])), ("room", "hex32"), ("lang", "str"), ("source", "hex32"), + ("form", ("one", ["pose", "video"])), ("track", "hex32"), ("origin", ("one", ORIGINS)), ("model", ("null", "hex32")), + ("video", ("null", ("obj", [("width", "int"), ("height", "int"), ("rate_num", "int"), ("rate_den", "int")]))), + ("segments", ("arr", ("obj", [("object", "hex32"), ("start", "int"), ("end", "int"), ("revisions", ("arr", "hex32"))])))] + SIG +REVIEW = [("kind", ("one", ["wai-signing-review"])), ("signing", "hex32"), ("scope", ("one", ["translation"])), + ("verdict", ("one", ["approved", "approved-with-notes", "rejected"])), ("notes", ("null", "hex32"))] + SIG +TRACKS = { + "captions": [("service", ("one", ["captions"])), ("principal", "hex32"), ("lang", "str"), + ("latency_mean_max", ("null", "int")), ("latency_max", ("null", "int"))], + "audio-description": [("service", ("one", ["audio-description"])), ("record", "hex32"), ("lang", "str")], + "sign-language": [("service", ("one", ["sign-language"])), ("record", "hex32"), ("lang", "str"), + ("review", ("null", "hex32")), ("offset_max", ("null", "int"))], +} +CLAIM = [("kind", ("one", ["wai-access-completeness"])), ("room", "hex32"), ("from", "int"), ("to", "int"), ("pt0", "int"), + ("tracks", "tracks")] + SIG +TABLES = {"wai-caption-sources": SOURCES, "wai-caption-reference": REFERENCE, "wai-caption-quality": QUALITY, + "wai-description": DESCRIPTION, "wai-signing": SIGNING, "wai-signing-review": REVIEW, "wai-access-completeness": CLAIM} + + +def has_type(v, t): + if v is BAD: + return False + if t == "hex32": + return is_hex(v, 32) + if t == "hex64": + return is_hex(v, 64) + if t == "int": + return is_int(v) + if t == "sint": + return is_sint(v) + if t == "str": + return isinstance(v, str) + if t == "tracks": + return isinstance(v, list) and all(isinstance(x, dict) and x.get("service") in TRACKS and fits(x, TRACKS[x["service"]]) for x in v) + tag, arg = t + if tag == "one": + return isinstance(v, str) and v in arg + if tag == "obj": + return fits(v, arg) + if tag == "arr": + return isinstance(v, list) and all(has_type(x, arg) for x in v) + if tag == "null": + return v is None or has_type(v, arg) + raise AssertionError(t) + + +def fits(v, table): + return isinstance(v, dict) and len(v) == len(table) and all(k in v and has_type(v[k], t) for k, t in table) + + +def jcs(v): + """RFC 8785 over strings, unsigned integers, null, arrays and objects with ASCII member + names, which is what these records hold.""" + return json.dumps(v, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8") + + +def read_record(text): + """§2: (kind, value, record id).""" + v = read_json(text) + if not isinstance(v, dict) or v.get("kind") not in TABLES or not fits(v, TABLES[v["kind"]]): + raise Refused("record_malformed") + body = {k: x for k, x in v.items() if k != "sig"} + bad = ED.verify(bytes.fromhex(v["signer_pubkey"]), SIGN_DOMAIN + jcs(body), bytes.fromhex(v["sig"])) + if bad is not None: + raise Refused(bad) + return v["kind"], v, hashlib.sha256(jcs(v)).digest() + + +# ---------------------------------------------------------------- §3 words and alignment + +EDGE = "!\"'(),-.:;?[]¡«»¿–—‘’“”…" +UPPER = {c: c + 0x20 for c in range(0x41, 0x5B)} + + +def words(text): + out = [] + for piece in re.split("[ \n]", text): + if piece == "": + continue + w = piece.translate(UPPER).strip(EDGE) + if w: + out.append(w) + return out + + +def align(h, r, prefix): + """§3.2: (words, errors, substitutions, deletions, insertions).""" + m, n = len(h), len(r) + d = [[0] * (n + 1) for _ in range(m + 1)] + for j in range(n + 1): + d[0][j] = j + for i in range(m + 1): + d[i][0] = i + for i in range(1, m + 1): + for j in range(1, n + 1): + c = 0 if h[i - 1] == r[j - 1] else 1 + d[i][j] = min(d[i - 1][j - 1] + c, d[i - 1][j] + 1, d[i][j - 1] + 1) + if prefix: + least = min(d[m]) + end = max(j for j in range(n + 1) if d[m][j] == least) + else: + end = n + s = de = ins = 0 + i, j = m, end + while i > 0 or j > 0: + if i > 0 and j > 0: + c = 0 if h[i - 1] == r[j - 1] else 1 + if d[i][j] == d[i - 1][j - 1] + c: + s += c + i, j = i - 1, j - 1 + continue + if i > 0 and d[i][j] == d[i - 1][j] + 1: + ins += 1 + i -= 1 + else: + de += 1 + j -= 1 + assert s + de + ins == d[m][end] + return [end, d[m][end], s, de, ins] + + +def counts_json(c): + return {"words": c[0], "errors": c[1], "substitutions": c[2], "deletions": c[3], "insertions": c[4]} + + +def add(a, b): + return [x + y for x, y in zip(a, b)] + + +# ---------------------------------------------------------------- §4 the caption tracks + +class Stream: + def __init__(self, room, cap): + self.room, self.revs, self.accepted, self.gaps = room, cap.revs, cap.ev.accepted, cap.ev.gaps + + def principals(self): + out = [] + for r in self.revs: + if r["event"]["principal"] not in out: + out.append(r["event"]["principal"]) + return out + + def cues(self, p): + """§4.1: each cue as the positions of its revisions, first to last.""" + out = [] + for i, r in enumerate(self.revs): + if r["event"]["principal"] != p or r["sup"] is not None or r["sup_digest"] is not None: + continue + chain = [i] + while self.revs[chain[-1]]["by"] is not None: + chain.append(self.revs[chain[-1]]["by"]) + out.append(chain) + return out + + def head(self, c): + return self.revs[c[0]]["event"]["digest"] + + def last(self, c): + return self.revs[c[-1]] + + def whole(self, p): + cues = self.cues(p) + return (len(cues) > 0 and not any(g[0] == p for g in self.gaps) + and all(self.last(c)["final"] and not self.last(c)["unknown"] for c in cues)) + + def resolved(self, p): + return self.whole(p) and all(self.last(c)["duration"] > 0 for c in self.cues(p)) + + def events_digest(self, p): + mine = sorted((r for r in self.revs if r["event"]["principal"] == p), key=lambda r: r["event"]["seq"]) + return hashlib.sha256(b"".join(r["event"]["digest"] for r in mine)).digest() + + def take_offset(self, take): + """§4.2 rule 6: the offset of the take's opening commitment, when the take is derived.""" + opening = None + for _, ev, p in self.accepted: + if ev["kind"] != TAKE_COMMIT: + continue + c = read_commit(p["bytes"]) + if c is not None and c["take"] == take and c["n"] == 0 and c["phase"] == 1: + opening = (ev["principal"], c["offset"]) + break + if opening is None: + return None + author, offset = opening + for _, ev, p in self.accepted: + if ev["kind"] == CONTROL and p["command"] == 1 and p["target"] == author: + if hashlib.sha256(b"wai:capture-take\x01" + self.room + author + ev["digest"]).digest() == take: + return offset + return None + + def intervals(self, p, pt0): + out = [] + for c in self.cues(p): + h, l = self.revs[c[0]], self.last(c) + out.append((pt0 + h["event"]["t"] // 1000, pt0 + l["event"]["t"] // 1000 + l["duration"])) + return out + + +def read_commit(b): + """capture-binding §5.1 and §5.2: a take_commit payload, or None when it does not read.""" + if len(b) < 126: + return None + take, n, phase = b[0:32], int.from_bytes(b[32:36], "little"), b[36] + first, size = int.from_bytes(b[69:77], "little"), int.from_bytes(b[77:85], "little") + root, offset, k = b[85:117], int.from_bytes(b[117:125], "little", signed=True), b[125] + if phase not in (1, 2, 3) or size < first or k > 64 or len(b) != 126 + 32 * k or (size == 0 and root != bytes(32)): + return None + return {"take": take, "n": n, "phase": phase, "offset": offset} + + +def floor_div(a, n): + return a // n + + +class Run: + def __init__(self, stream, records): + self.s, self.records = stream, records # records: [(kind, value, id)] + self.sources = {} # principal -> (id, {cue: (start, on_take)}) + self.references = {} # principal -> (id, {cue: text}) + + def room_ok(self, v): + if bytes.fromhex(v["room"]) != self.s.room: + raise Refused("wrong_room") + + def latencies(self, p, cues): + src = self.sources.get(p) + if src is None: + return [] + out = [] + for c in cues: + placed = src[1].get(self.s.head(c)) + if placed is not None: + out.append((self.s.revs[c[0]]["event"]["t"] - placed[0], placed[1])) + return out + + def figure(self, p): + s = self.s + cues = s.cues(p) + lat = sorted(x[0] for x in self.latencies(p, cues)) + n = len(lat) + if n == 0: + latency = {"class": "none", "n": 0, "min": None, "max": None, "mean": None, "p50": None, "p95": None} + else: + def rank(q): + return lat[-(-q * n // 100) - 1] + on_take = all(x[1] for x in self.latencies(p, cues)) + latency = {"class": "capture" if on_take else "stated", "n": n, "min": str(lat[0]), "max": str(lat[-1]), + "mean": str(floor_div(sum(lat), n)), "p50": str(rank(50)), "p95": str(rank(95))} + revisions = changed_total = corrected = 0 + for c in cues: + revisions += len(c) - 1 + changed = 0 + for a, b in zip(c, c[1:]): + al = align(words(s.revs[a]["text"]), words(s.revs[b]["text"]), False) + changed += al[2] + al[4] + changed_total += changed + corrected += 1 if changed > 0 else 0 + ref = self.references.get(p) + if ref is not None: + cls = "transcript" + elif all(s.last(c)["origin"] in ("human", "machine-reviewed") for c in cues): + cls = "reviewed" + else: + cls = "self" + first, final = [0] * 5, [0] * 5 + for c in cues: + rt = ref[1][s.head(c)] if ref is not None else s.last(c)["text"] + rw = words(rt) + first = add(first, align(words(s.revs[c[0]]["text"]), rw, True)) + if ref is not None: + final = add(final, align(words(s.last(c)["text"]), rw, False)) + src = self.sources.get(p) + return {"room": s.room.hex(), "principal": p.hex(), "events": s.events_digest(p).hex(), + "sources": None if src is None else src[0].hex(), "reference": None if ref is None else ref[0].hex(), + "cues": len(cues), "latency": latency, + "stability": {"revisions": revisions, "words_changed": changed_total, "cues_corrected": corrected}, + "accuracy": {"class": cls, "first": counts_json(first), "final": counts_json(final) if ref is not None else None}} + + def heads(self, p): + return [self.s.head(c) for c in self.s.cues(p)] + + def earlier(self, at, kind, p): + return any(k == kind and bytes.fromhex(v["principal"]) == p for k, v, _ in self.records[:at]) + + # §4.2 + def sources_rec(self, at): + _, v, rid = self.records[at] + self.room_ok(v) + p = bytes.fromhex(v["principal"]) + if self.earlier(at, "wai-caption-sources", p): + raise Refused("record_conflict") + seen = set() + for e in v["sources"]: + if (e["basis"] == "take") != (e["take"] is not None) or e["start"] > e["end"] or e["cue"] in seen: + raise Refused("record_malformed") + seen.add(e["cue"]) + if not self.s.whole(p): + raise Refused("stream_incomplete") + heads = self.heads(p) + if any(bytes.fromhex(e["cue"]) not in heads for e in v["sources"]): + raise Refused("source_unknown") + starts = {} + for e in v["sources"]: + if e["basis"] == "take": + o = self.s.take_offset(bytes.fromhex(e["take"])) + if o is None or e["start"] + o < 0: + raise Refused("source_take_unknown") + starts[bytes.fromhex(e["cue"])] = (e["start"] + o, True) + else: + starts[bytes.fromhex(e["cue"])] = (e["start"], False) + self.sources.setdefault(p, (rid, starts)) + + # §4.3 + def reference_rec(self, at): + _, v, rid = self.records[at] + self.room_ok(v) + p = bytes.fromhex(v["principal"]) + if self.earlier(at, "wai-caption-reference", p): + raise Refused("record_conflict") + texts = {} + for e in v["entries"]: + if e["cue"] in texts: + raise Refused("record_malformed") + texts[e["cue"]] = e["text"] + if not all(TT.text_ok(t) for t in texts.values()): + raise Refused("text_not_in_subset") + if not self.s.whole(p): + raise Refused("stream_incomplete") + heads = self.heads(p) + if any(bytes.fromhex(k) not in heads for k in texts): + raise Refused("reference_unknown") + if any(h.hex() not in texts for h in heads): + raise Refused("reference_incomplete") + self.references.setdefault(p, (rid, {bytes.fromhex(k): t for k, t in texts.items()})) + + # §4.7 + def quality_rec(self, at): + _, v, _ = self.records[at] + self.room_ok(v) + p = bytes.fromhex(v["principal"]) + if not self.s.whole(p): + raise Refused("stream_incomplete") + f = self.figure(p) + if any(v[k] != f[k] for k in ("events", "sources", "reference")): + raise Refused("figure_inputs_mismatch") + if any(v[k] != x for k, x in f.items()): + raise Refused("figure_mismatch") + + # §6.2 + def signing_rec(self, at): + _, v, _ = self.records[at] + self.room_ok(v) + machine = v["origin"] != "human" + ok = TT.lang_ok(v["lang"]) and machine == (v["model"] is not None) and (v["form"] == "video") == (v["video"] is not None) + if v["video"] is not None: + ok = ok and all(v["video"][k] > 0 for k in ("width", "height", "rate_num", "rate_den")) + segs = v["segments"] + ok = ok and len(segs) > 0 + named = [] + for i, sg in enumerate(segs): + ok = ok and sg["start"] < sg["end"] and len(sg["revisions"]) > 0 and (i == 0 or sg["start"] >= segs[i - 1]["end"]) + named += sg["revisions"] + ok = ok and len(set(named)) == len(named) + if not ok: + raise Refused("signing_malformed") + src = bytes.fromhex(v["source"]) + if not self.s.whole(src): + raise Refused("stream_incomplete") + mine = {r["event"]["digest"]: r for r in self.s.revs if r["event"]["principal"] == src} + if any(bytes.fromhex(d) not in mine for d in named): + raise Refused("sign_revision_unknown") + for d in named: + r = mine[bytes.fromhex(d)] + if r["by"] is not None or not r["final"] or r["unknown"]: + raise Refused("sign_revision_not_final") + + def segment_offset(self, src, sg): + cues = [c for c in self.s.cues(src) if self.s.last(c)["event"]["digest"].hex() in sg["revisions"]] + if not cues: + return None + earliest = min(cues, key=lambda c: (self.s.revs[c[0]]["event"]["t"], c[0])) + placed = self.sources.get(src, (None, {}))[1].get(self.s.head(earliest)) + return None if placed is None else sg["start"] - placed[0] + + # §6.4 + def review_rec(self, at): + _, v, _ = self.records[at] + if (v["verdict"] == "approved") != (v["notes"] is None): + raise Refused("record_malformed") + if not any(k == "wai-signing" and rid.hex() == v["signing"] for k, _, rid in self.records): + raise Refused("review_subject_unknown") + + def find(self, kind, rid): + return next((v for k, v, i in self.records if k == kind and i.hex() == rid), None) + + # §7.2 + def claim_rec(self, at): + _, v, _ = self.records[at] + self.room_ok(v) + frm, to, pt0, tracks = v["from"], v["to"], v["pt0"], v["tracks"] + ok = frm < to and len(tracks) > 0 + principals, recs = [], [] + for t in tracks: + ok = ok and TT.lang_ok(t["lang"]) + if t["service"] == "captions": + ok = ok and t["principal"] not in principals + principals.append(t["principal"]) + else: + ok = ok and t["record"] not in recs + recs.append(t["record"]) + if not ok: + raise Refused("claim_malformed") + + def session(p): + return [c for c in self.s.cues(p) if frm <= self.s.revs[c[0]]["event"]["t"] < to] + + m_from, m_to = pt0 + frm // 1000, pt0 + to // 1000 + for t in tracks: + if t["service"] == "captions": + p = bytes.fromhex(t["principal"]) + cues = session(p) + if not cues: + raise Refused("track_missing") + if not self.s.resolved(p): + raise Refused("track_incomplete") + if any(self.s.revs[r]["lang"] != t["lang"] for c in cues for r in c): + raise Refused("track_mismatch") + if t["latency_mean_max"] is not None or t["latency_max"] is not None: + lat = [x[0] for x in self.latencies(p, cues)] + if len(lat) != len(cues): + raise Refused("sync_unmeasured") + if (t["latency_mean_max"] is not None and floor_div(sum(lat), len(lat)) > t["latency_mean_max"]) or \ + (t["latency_max"] is not None and any(x > t["latency_max"] for x in lat)): + raise Refused("out_of_sync") + elif t["service"] == "audio-description": + d = self.find("wai-description", t["record"]) + if d is None: + raise Refused("track_missing") + if d["lang"] != t["lang"] or any(e["begin"] < m_from or e["end"] > m_to for e in d["events"]): + raise Refused("track_mismatch") + if d["voicing"]["form"] == "track" and any(e["voice"] is None for e in d["events"]): + raise Refused("track_incomplete") + else: + g = self.find("wai-signing", t["record"]) + if g is None: + raise Refused("track_missing") + if g["lang"] != t["lang"] or g["source"] not in principals: + raise Refused("track_mismatch") + src = bytes.fromhex(g["source"]) + named = {d for sg in g["segments"] for d in sg["revisions"]} + if any(self.s.last(c)["event"]["digest"].hex() not in named for c in session(src)): + raise Refused("track_incomplete") + if t["review"] is not None: + r = self.find("wai-signing-review", t["review"]) + if r is None: + raise Refused("review_missing") + if r["signing"] != t["record"]: + raise Refused("review_mismatch") + if r["verdict"] == "rejected": + raise Refused("review_rejected") + if t["offset_max"] is not None: + offs = [self.segment_offset(src, sg) for sg in g["segments"]] + if any(o is None for o in offs): + raise Refused("sync_unmeasured") + if any(abs(o) > t["offset_max"] for o in offs): + raise Refused("out_of_sync") + + def overlap(self, v, rid): + dialogue = [] + for t in v["tracks"]: + if t["service"] == "captions": + dialogue += self.s.intervals(bytes.fromhex(t["principal"]), v["pt0"]) + union = [] + for a, b in sorted(dialogue): + if union and a <= union[-1][1]: + union[-1][1] = max(union[-1][1], b) + else: + union.append([a, b]) + out = [] + for i, t in enumerate(v["tracks"]): + if t["service"] != "audio-description": + continue + d = self.find("wai-description", t["record"]) + ms = n = 0 + for e in d["events"]: + if e["voice"] is not None: + a, b = e["voice"]["begin"], e["voice"]["end"] + else: + a, b = e["begin"] + e["duck"]["ramp"], e["end"] - e["duck"]["ramp"] + o = sum(max(0, min(b, y) - max(a, x)) for x, y in union) + ms += o + n += 1 if o > 0 else 0 + out.append({"track": i, "ms": ms, "events": n}) + return {"record": rid.hex(), "overlap": out} + + +# ---------------------------------------------------------------- §5 audio description + +ID = re.compile(r"[A-Za-z_][A-Za-z0-9_.\-]{0,63}") + + +def description_rules(v): + """§5.2, in order.""" + m = "description_malformed" + if not TT.lang_ok(v["lang"]): + raise Refused(m) + sc, vo = v["script"], v["voicing"] + sink = vo["form"] == "sink" + if (sc["origin"] != "human") != (sc["model"] is not None) or (vo["origin"] != "human") != (vo["model"] is not None) \ + or sink == (vo["track"] is not None) or (sink and vo["origin"] == "human"): + raise Refused(m) + evs = v["events"] + if not evs: + raise Refused(m) + ids = set() + for i, e in enumerate(evs): + if ID.fullmatch(e["id"]) is None or e["id"] in ids or not e["begin"] < e["end"] <= MAX_MS or \ + (i > 0 and e["begin"] < evs[i - 1]["end"]): + raise Refused(m) + ids.add(e["id"]) + if not all(TT.text_ok(e["text"]) for e in evs): + raise Refused("text_not_in_subset") + for e in evs: + g, r = e["duck"]["gain"], e["duck"]["ramp"] + if not (g <= 1000 and (g == 1000) == (r == 0) and 2 * r <= e["end"] - e["begin"]): + raise Refused(m) + vc = e["voice"] + if vc is not None and (sink or not e["begin"] <= vc["begin"] < vc["end"] <= e["end"]): + raise Refused(m) + for e in evs: + vc = e["voice"] + if vc is None: + continue + a, z = e["begin"] + e["duck"]["ramp"], e["end"] - e["duck"]["ramp"] + if not (a - 35 <= vc["begin"] <= a + 45 and vc["end"] <= z + 45): + raise Refused("description_out_of_sync") + + +def description_figures(v, rid): + offs = [None if e["voice"] is None else str(e["voice"]["begin"] - (e["begin"] + e["duck"]["ramp"])) for e in v["events"]] + return {"record": rid.hex(), "events": len(v["events"]), "voiced": sum(1 for e in v["events"] if e["voice"] is not None), + "offsets": offs} + + +PARAM = re.compile(r"[!#-%'-;=?-~]{1,2048}") + + +def hhmmss(ms): + return "%02d:%02d:%02d.%03d" % (ms // 3600000, ms // 60000 % 60, ms // 1000 % 60, ms % 1000) + + +def gain(g): + if g == 0: + return "0" + if g == 1000: + return "1" + return "0." + ("%03d" % g).rstrip("0") + + +def esc(s): + return s.replace("&", "&").replace("<", "<").replace(">", ">").replace("\n", "
") + + +def dapt(v, uri, typ): + """§5.5's document.""" + track = v["voicing"]["form"] == "track" + if track and not (PARAM.fullmatch(uri or "") and PARAM.fullmatch(typ or "")): + raise Refused("parameter_malformed") + reps = [] + for e in v["events"]: + if e["represents"] not in reps: + reps.append(e["represents"]) + + def label(o, name): + s = ' wai:%s="%s"' % (name, o["origin"]) + if o["model"] is not None: + s += ' wai:%s-model="%s"' % (name, o["model"]) + return s + + out = ['', + '' + % (NS_TT, NS_TTP, NS_TTA, NS_DAPTM, NS_WAI, v["lang"], DAPT_CONTENT, " ".join(reps), + "asRecorded" if track else "preRecording", label(v["script"], "script"), label(v["voicing"], "voice")), + ""] + for e in v["events"]: + b, en, g, r = e["begin"], e["end"], e["duck"]["gain"], e["duck"]["ramp"] + out.append('
' % (e["id"], hhmmss(b), hhmmss(en), e["represents"])) + if g < 1000: + out.append('' % (hhmmss(r), gain(g))) + out.append('' % (hhmmss(en - b - r), hhmmss(en - b), gain(g))) + text = esc(e["text"]) + if track and e["voice"] is not None: + vb, ve = e["voice"]["begin"], e["voice"]["end"] + content = '' % ( + hhmmss(vb - b), hhmmss(ve - b), uri, typ, hhmmss(vb), hhmmss(ve), text) + elif track: + content = text + else: + content = '%s' % text + out.append("

%s

" % content) + out.append("
") + out += ["", "
"] + return "\n".join(out) + "\n" + + +def dapt_structure(doc, v): + """Parse the document and check what DAPT §4 and §5 ask of it.""" + root = ET.fromstring(doc.encode("utf-8")) + q = lambda ns, n: "{%s}%s" % (ns, n) # noqa: E731 + fails = [] + if root.tag != q(NS_TT, "tt"): + fails.append("the root is not tt") + if root.get(q(NS_TTP, "contentProfiles")) != DAPT_CONTENT or root.get(q(NS_TTP, "profile")) is not None: + fails.append("the profile is not signalled as DAPT §5.6 asks") + if root.get(q(NS_DAPTM, "scriptType")) not in ("preRecording", "asRecorded") or not root.get(q(NS_DAPTM, "scriptRepresents")): + fails.append("no script type or script represents") + if root.get(q(NS_XML, "lang")) != v["lang"]: + fails.append("xml:lang is not the record's") + reps = root.get(q(NS_DAPTM, "scriptRepresents"), "").split(" ") + divs = root.findall(q(NS_TT, "body") + "/" + q(NS_TT, "div")) + if len(divs) != len(v["events"]): + fails.append("not one Script Event per description") + for div, e in zip(divs, v["events"]): + if div.get(q(NS_XML, "id")) != e["id"] or div.get(q(NS_DAPTM, "represents")) not in reps: + fails.append("Script Event %s: its id or represents" % e["id"]) + anim = div.findall(q(NS_TT, "animate")) + if len(anim) != (2 if e["duck"]["gain"] < 1000 else 0): + fails.append("Script Event %s: its mixing instructions" % e["id"]) + ps = div.findall(q(NS_TT, "p")) + if len(ps) != 1: + fails.append("Script Event %s: not one Text" % e["id"]) + continue + if "".join(ps[0].itertext()) != e["text"].replace("\n", ""): + fails.append("Script Event %s: its text" % e["id"]) + audio = ps[0].findall(".//" + q(NS_TT, "audio")) + spoken = [s for s in ps[0].iter(q(NS_TT, "span")) if s.get(q(NS_TTA, "speak")) is not None] + want_audio = v["voicing"]["form"] == "track" and e["voice"] is not None + if (len(audio) == 1) != want_audio or (len(spoken) == 1) != (v["voicing"]["form"] == "sink"): + fails.append("Script Event %s: its audio" % e["id"]) + return fails + + +# ---------------------------------------------------------------- §8 verification + +KIND_ORDER = ["wai-caption-sources", "wai-caption-reference", "wai-description", "wai-signing", "wai-signing-review", + "wai-caption-quality", "wai-access-completeness"] + + +def verify(room, events, texts): + out, cap = TT.verify_events(room, events) + if out["outcome"] == "refuse": + return {"outcome": "refuse", "at": "events", "index": out["index"], "reason": out["reason"]} + stream = Stream(room, cap) + records = [] + for i, t in enumerate(texts): + try: + records.append(read_record(t)) + except Refused as e: + return {"outcome": "refuse", "at": "record", "index": i, "reason": e.reason} + run = Run(stream, records) + checks = {"wai-caption-sources": run.sources_rec, "wai-caption-reference": run.reference_rec, + "wai-description": lambda i: description_rules(records[i][1]), "wai-signing": run.signing_rec, + "wai-signing-review": run.review_rec, "wai-caption-quality": run.quality_rec, + "wai-access-completeness": run.claim_rec} + for kind in KIND_ORDER: + for i, (k, _, _) in enumerate(records): + if k != kind: + continue + try: + checks[kind](i) + except Refused as e: + return {"outcome": "refuse", "at": "record", "index": i, "reason": e.reason} + signings = [] + for k, v, rid in records: + if k != "wai-signing": + continue + src = bytes.fromhex(v["source"]) + offs = [run.segment_offset(src, sg) for sg in v["segments"]] + floor = None + if v["video"] is not None: + w, h = v["video"]["width"], v["video"]["height"] + floor = "meets" if min(w, h) >= 240 and max(w, h) >= 320 and v["video"]["rate_num"] >= 20 * v["video"]["rate_den"] else "below" + signings.append({"record": rid.hex(), "segments": len(v["segments"]), "revisions": sum(len(s["revisions"]) for s in v["segments"]), + "offsets": [None if o is None else str(o) for o in offs], "video_floor": floor}) + figures = { + "captions": [run.figure(p) for p in stream.principals() if stream.whole(p)], + "descriptions": [description_figures(v, rid) for k, v, rid in records if k == "wai-description"], + "signings": signings, + "claims": [run.overlap(v, rid) for k, v, rid in records if k == "wai-access-completeness"], + } + return {"outcome": "accept", "figures": figures} + + +# ---------------------------------------------------------------- the corpus + +def check(doc, files, quiet=False, only=None): + """Every vector and document, or only those `only` names (a mutation's), with the corpus's + coverage of §10 checked when all are.""" + fails, seen = [], set() + room = bytes.fromhex(doc["room"]) + streams = {n: [bytes.fromhex(h) for h in evs] for n, evs in doc["streams"].items()} + texts_of = {} + for v in doc["vectors"]: + name = v["name"] + texts_of[name] = v["records"] + if only is not None and name not in only: + continue + before = len(fails) + try: + got = verify(room, streams[v["stream"]], v["records"]) + except Exception as e: # a verifier that cannot read a case fails it + fails.append("%s: does not verify: %s: %s" % (name, type(e).__name__, e)) + continue + for k in ("outcome", "at", "index", "reason", "figures"): + if got.get(k) != v.get(k): + fails.append("%s: %s is %s, the corpus states %s" % (name, k, json.dumps(got.get(k))[:300], json.dumps(v.get(k))[:300])) + if got.get("reason"): + seen.add(got["reason"]) + if not quiet: + print("%s %s: %s" % ("PASS" if len(fails) == before else "FAIL", name, got["outcome"] + (" " + got["reason"] if got.get("reason") else ""))) + for d in doc["documents"]: + if only is not None and d.get("file", d["vector"]) not in only: + continue + before = len(fails) + try: + _, v, _ = read_record(texts_of[d["vector"]][d["record"]]) + doc_text, why = dapt(v, d["uri"], d["type"]), None + except Refused as e: + doc_text, why = None, e.reason + if why is not None: + seen.add(why) + if d.get("reason") != why: + fails.append("document of %s: refused %s, the corpus states %s" % (d["vector"], why, d.get("reason"))) + elif doc_text is not None: + if files.get(d["file"]) != doc_text: + fails.append("document of %s: %s differs from the text's" % (d["vector"], d["file"])) + else: + fails += ["document %s: %s" % (d["file"], f) for f in dapt_structure(doc_text, v)] + if not quiet: + print("%s document of %s: %s" % ("PASS" if len(fails) == before else "FAIL", d["vector"], d.get("file") or why)) + missing = [r for r in reasons_of_extension() if r not in seen] + if missing and only is None: + fails.append("nothing is refused %s" % ", ".join(missing)) + return fails + + +def mutations(doc, files): + """Copies of the corpus, each with one defect a conforming verifier must catch.""" + out = [] + + def mutate(label, f, only): + d, fs = copy.deepcopy(doc), dict(files) + f(d, fs) + out.append((label, d, fs, only)) + + def flip_sig(text): + v = json.loads(text) + v["sig"] = v["sig"][:-1] + ("1" if v["sig"][-1] == "0" else "0") + return json.dumps(v, sort_keys=True, separators=(",", ":"), ensure_ascii=False) + + for i, v in enumerate(doc["vectors"]): + if v["outcome"] == "accept": + def stated(d, fs, i=i): + d["vectors"][i]["figures"]["captions"][0]["latency"]["n"] += 1 + mutate("%s: a stated figure changed" % v["name"], stated, {v["name"]}) + for k in range(len(v["records"])): + def sig(d, fs, i=i, k=k): + d["vectors"][i]["records"][k] = flip_sig(d["vectors"][i]["records"][k]) + mutate("%s: record %d's signature flipped" % (v["name"], k), sig, {v["name"]}) + for k in range(len(doc["streams"][v["stream"]])): + def ev(d, fs, i=i, k=k): + name = "mutated" + evs = list(d["streams"][d["vectors"][i]["stream"]]) + b = bytearray(bytes.fromhex(evs[k])) + b[-1] ^= 0x01 + evs[k] = b.hex() + d["streams"][name] = evs + d["vectors"][i]["stream"] = name + mutate("%s: event %d altered" % (v["name"], k), ev, {v["name"]}) + else: + def place(d, fs, i=i): + d["vectors"][i]["index"] += 1 + mutate("%s: the place of its refusal moved" % v["name"], place, {v["name"]}) + + def reason(d, fs, i=i): + d["vectors"][i]["reason"] = "record_malformed" if d["vectors"][i]["reason"] != "record_malformed" else "bad_key" + mutate("%s: its reason changed" % v["name"], reason, {v["name"]}) + for d0 in doc["documents"]: + if "file" in d0: + def doc_byte(d, fs, f=d0["file"]): + fs[f] = fs[f].replace("

", "

", 1) + mutate("%s: a byte added" % d0["file"], doc_byte, {d0["file"]}) + return out + + +def main(corpus_dir): + files = {} + for n in sorted(os.listdir(corpus_dir)): + if n != "README.md": + with open(os.path.join(corpus_dir, n), encoding="utf-8") as f: + files[n] = f.read() + doc = json.loads(files["vectors.json"]) + fails = check(doc, files) + for f in fails: + print("FAIL " + f) + caught = 0 + muts = mutations(doc, files) + for label, d, fs, only in muts: + if check(d, fs, quiet=True, only=only): + caught += 1 + else: + fails.append("a mutated copy verifies: " + label) + print("FAIL a mutated copy verifies: " + label) + print("%s every mutated copy of the corpus fails (%d of %d)" % ("PASS" if caught == len(muts) else "FAIL", caught, len(muts))) + print("%s %s" % ("PASS" if not fails else "FAIL", "the corpus verifies" if not fails else "%d failures" % len(fails))) + return 0 if not fails else 1 + + +if __name__ == "__main__": + if len(sys.argv) != 2: + sys.exit("usage: access_services_verify.py ") + sys.exit(main(sys.argv[1])) -- 2.54.0 (Apple Git-157) From 4dacdb2038eb2053b752bf1691805d57764c0e76 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Wed, 21 Oct 2026 12:27:36 -0400 Subject: [PATCH 3/4] =?UTF-8?q?wai.access.services:=20registry=20entry=20a?= =?UTF-8?q?nd=20export,=20SPEC=20=C2=A75,=20CHANGELOG,=20CI=20step,=20corp?= =?UTF-8?q?us=20README;=20timed-text's=20scope=20points=20to=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .github/workflows/wai-conformance.yml | 24 +++++++++ wai/CHANGELOG.md | 50 +++++++++++++++++++ wai/REGISTRY.md | 13 ++++- wai/SPEC.md | 21 +++++++- wai/extensions/access-services.md | 18 ++++--- wai/extensions/timed-text.md | 6 ++- wai/live-conformance/README.md | 8 ++- wai/live-conformance/access/README.md | 46 ++++++++++++++++++ wai/registry/capabilities.json | 70 +++++++++++++++++++++++++++ wai/vocab/v2.ttl | 7 +++ wai/wai-rs/src/codecs/registry.rs | 16 +++++- 11 files changed, 261 insertions(+), 18 deletions(-) create mode 100644 wai/live-conformance/access/README.md diff --git a/.github/workflows/wai-conformance.yml b/.github/workflows/wai-conformance.yml index ce39465a6..92a1dab4e 100644 --- a/.github/workflows/wai-conformance.yml +++ b/.github/workflows/wai-conformance.yml @@ -83,6 +83,10 @@ on: # tests/timed_text.rs requires this extension's §12 to list the codes the reference # reports, and the registry's wire identifiers test reads its sections. - 'wai/extensions/timed-text.md' + # tests/access_services.rs requires this extension's §10 to list the codes the reference + # reports, access_services_verify.py reads that table, and the registry's wire + # identifiers test reads its sections. + - 'wai/extensions/access-services.md' # tests/live_metering.rs requires this extension's §9 to list the codes the reference # reports, live_metering_verify.py reads that table, and the registry's wire identifiers # test reads its sections. @@ -789,6 +793,7 @@ 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), + # access_services_verify.py (the access-services 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), and # e2ee_verify.py (the end-to-end encrypted rooms corpus), live_watermark_verify.py (the @@ -1023,6 +1028,25 @@ jobs: (cd wai-rs && cargo test --no-default-features --features timed_text --lib timed_text::) (cd wai-rs && cargo test --no-default-features --features timed_text --test timed_text) python3 -I live-conformance/timed_text_verify.py live-conformance/captions + # wai.access.services (extensions/access-services.md): the reference module's unit tests + # (words, full and prefix alignment with their walk back, signed integers, gains) and + # tests/access_services.rs (vectors.json and each DAPT document regenerate byte for byte + # from their fixed seeds and no other file is there, wai-rs gives every vector and + # document its stated outcome and figures, every reason of §10 refuses a case, and §10 + # lists exactly the reference's codes); then the corpus's second implementation, + # access_services_verify.py, written from the extension's text and sharing no code with + # wai-rs, which verifies events and captions with timed_text_verify.py and every record + # with WAI's strict Ed25519 rule, computes every figure and writes every DAPT document + # itself, parses each with xml.etree, reads the extension's reason table, and requires + # every mutated copy of the corpus to fail; standard library only, run isolated (-I). + - name: access services · wai-rs and access_services_verify.py + working-directory: wai + shell: bash + run: | + set -euo pipefail + (cd wai-rs && cargo test --no-default-features --features access_services --lib access_services::) + (cd wai-rs && cargo test --no-default-features --features access_services --test access_services) + python3 -I live-conformance/access_services_verify.py live-conformance/access # wai.live.metering (extensions/live-metering.md): the reference module's unit tests # (records and ledgers round-trip, the energy rules, the size bound at its limit, a # total of two classes told from a wrong one, funds rounding, the CMCD event-timeline diff --git a/wai/CHANGELOG.md b/wai/CHANGELOG.md index a961d721c..e7bcb4566 100644 --- a/wai/CHANGELOG.md +++ b/wai/CHANGELOG.md @@ -6,6 +6,56 @@ wire format may change and such changes are recorded here. ## v0.4.0 — current +### `wai.access.services`: caption quality anyone can recompute, audio description and sign language + +- **The extension** ([access-services](extensions/access-services.md)) registers the record + `wai.access.services`. Captions are timed-text's, unchanged; its records are JSON texts in + the JCS form, each signed with Ed25519 under `wai:access` and named by its SHA-256. +- **Caption quality from the signed revisions.** A caption track's **latency** is each cue's + first display on the room clock less the capture of its first word: a sources record places + the words on a take, mapped to the room clock by the take's opening commitment (the take is + checked to derive from a `record_start` to the commitment's author), or on the room clock as + its signer states, and the class (`capture`, `stated`, `none`) says which. Its **stability** + is the revisions after first display and the words they changed; its **accuracy**, the word + errors of the first revision shown against a reference transcript or the reviewed final + revision, by a prefix alignment that does not count the words a partial has not reached. + Words fold ASCII case and edge punctuation, and the alignment walks back by one fixed rule, + so substitutions, deletions and insertions are the same everywhere. A quality record states + the figure and names its inputs by digest; a verifier recomputes it (`figure_mismatch`, + `figure_inputs_mismatch`). §9 maps each figure onto 47 CFR 79.1(j) and (k)(2), the two UK + regulator statements on live subtitling (2013, 2024) and EBU Tech 3370's authoring delay, + and says what is not computed (severity grading, speed, placement). +- **Audio description.** A description record holds the script (each event's interval, what + of the image it describes, its text), the ducking of the programme audio under each event, + and the voicing, on a separate track or by the sink with a pinned model, the script and the + voice each labelled human, machine or machine-reviewed. A voice must start within 35 ms + early and 45 ms late of the end of the duck and end no later than 45 ms after the duck + starts to rise, DAPT §5.5's bounds (`description_out_of_sync`). The record maps onto a DAPT + document (W3C Candidate Recommendation Draft of 2026-06-26), written by hand, with the + ducking as Mixing Instructions on each Script Event and the voice as an Audio Recording or + Synthesized Audio. A claim reports how much of each description is spoken over captioned + dialogue, a figure, not a refusal. +- **Sign language.** A signing record binds each object of an avatar pose stream, or of the + video of a signer, to the final caption revisions it translates, by digest + (`sign_revision_unknown`, `sign_revision_not_final`); a review signs off the translation. + Its figures are each segment's delay behind the speech and, for video, whether it meets the + resolution and frame rate EN 301 549 V4.1.1 clauses 6.5.2 and 6.5.3 state. +- **Completeness.** A claim declares a session's access tracks; a verifier checks each is + present, finished (every cue resolved, every description voiced, every cue signed), in its + language and within the tolerances the claim states, its reviews held and not rejected. +- **Reference and corpus.** The `access_services` module of `wai-rs` (feature + `access_services`) and `live-conformance/access/`, written from fixed seeds by + `wai_access_services_vectors`: a lesson with human and machine captions, a take, a + reference, quality records, a voiced description, a motion-captured signer and a claim; a + reviewed session with a sink-voiced description and a signer's video; a session with no + sources; and a negative control for every reason of §10, among them a misstated latency, a + broken revision chain, a signing bound to a superseded revision, descriptions spoken early + and late, and a claim over a track the verifier does not hold. Its second implementation, + `live-conformance/access_services_verify.py`, gives every case the same outcome and figures + and every DAPT document the same bytes, and every mutated copy of the corpus fails. +- **timed-text** §1 now points audio description, which it leaves out of scope, to this + extension. + ### `wai.ai.usage`: AI usage preferences bound to the bytes, and the agent's consumption claim - **The extension** ([ai-usage](extensions/ai-usage.md)) registers the record `wai.ai.usage`. diff --git a/wai/REGISTRY.md b/wai/REGISTRY.md index 4bf39d63a..e0cb5a8a8 100644 --- a/wai/REGISTRY.md +++ b/wai/REGISTRY.md @@ -44,8 +44,8 @@ Every registered string has one kind. `wai.live.metering`, `wai.live.steering`, `wai.live.moderation`, `wai.live.e2ee`, `wai.live.watermark`, `wai.live.ads` and `wai.live.provenance`; timed text, `wai.text.timed`; the deriving edge's record, `wai.edge.derivation`; the origin claims of - media, `wai.media.synthesis`; AI usage preferences and consumption claims, `wai.ai.usage`). - It names no payload format. + media, `wai.media.synthesis`; AI usage preferences and consumption claims, `wai.ai.usage`; + access services, `wai.access.services`). It names no payload format. A derivation or record string is not a payload capability, so it is not dispatchable (SPEC §4): dispatch never takes an envelope's capability that names @@ -159,6 +159,7 @@ and a role are fixed once registered. | string | kind | status | media | role | licence | replicate | sets | registered in | |---|---|---|---|---|---|---|---|---| +| `wai.access.services` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.ai.usage` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.asset.provenance` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content | | `wai.audio.aac` | payload | registered | audio | standalone | patent-pool | standard-unclassified | — | §5 Broadcast and streaming codecs | @@ -355,6 +356,7 @@ and a role are fixed once registered. | `science.transaction.wai.multivariant` | data-id | defined | http-delivery §11.1 | | `science.transaction.wai.stages` | data-id | defined | packaging §8 | | `science.transaction.wai.timed-text` | data-id | defined | timed-text §10.5 | +| `tag:transaction.science,2026:wai/access` | scheme | defined | access-services §5.5 | | `tag:transaction.science,2026:wai/class` | scheme | defined | packaging §8 | | `tag:transaction.science,2026:wai/floor` | scheme | defined | http-delivery §11.1 | | `tag:transaction.science,2026:wai/http-delivery` | scheme | defined | http-delivery §11.1 | @@ -364,8 +366,13 @@ and a role are fixed once registered. | `urn:wai:event:1` | scheme | defined | live-events §8.4 | | `urn:wai:event:1` | catalog | defined | live-events §8.1 | | `wai` | catalog | defined | moq-streaming-format §3 | +| `wai-access-completeness` | document-kind | defined | access-services §7.1 | | `wai-c2pa` | catalog | defined | live-provenance §10.2 | +| `wai-caption-quality` | document-kind | defined | access-services §4.7 | +| `wai-caption-reference` | document-kind | defined | access-services §4.3 | +| `wai-caption-sources` | document-kind | defined | access-services §4.2 | | `wai-derivation` | document-kind | defined | deriving-edge §5.1 | +| `wai-description` | document-kind | defined | access-services §5.1 | | `wai-detection` | document-kind | defined | synthesis §7.3 | | `wai-key-status` | document-kind | defined | jwp-receipts §7.9 | | `wai-label-policy` | document-kind | defined | synthesis §10.1 | @@ -377,6 +384,8 @@ and a role are fixed once registered. | `wai-receipt-index` | document-kind | defined | http-delivery §8.2 | | `wai-receipts` | catalog | defined | moq-streaming-format §4.1 | | `wai-review` | document-kind | defined | synthesis §9.1 | +| `wai-signing` | document-kind | defined | access-services §6.1 | +| `wai-signing-review` | document-kind | defined | access-services §6.4 | | `wai1` | codecs-prefix | defined | http-delivery §4.1 | | `wai1` | fourcc | provisional | http-delivery Appendix B | | `wai2` | codecs-prefix | defined | http-delivery §4.1 | diff --git a/wai/SPEC.md b/wai/SPEC.md index d3617b4c2..593e89b08 100644 --- a/wai/SPEC.md +++ b/wai/SPEC.md @@ -596,8 +596,8 @@ kind: `wai.live.metering`, `wai.live.steering`, `wai.live.moderation`, `wai.live.e2ee`, `wai.live.watermark`, `wai.live.ads` and `wai.live.provenance`, and timed text, `wai.text.timed`; an edge's derivation record, `wai.edge.derivation`; the origin claims of - media, `wai.media.synthesis`; and AI usage preferences and consumption claims, `wai.ai.usage`), - which names no payload format. + media, `wai.media.synthesis`; AI usage preferences and consumption claims, `wai.ai.usage`; and + access services, `wai.access.services`), 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 @@ -975,6 +975,23 @@ The event's origin and model digest are the disclosure label, carried through ev IMSC1 attributes) or, where a target cannot hold it, in a sidecar: [`extensions/timed-text.md`](extensions/timed-text.md). +And for the **access services** of a room session — `wai.access.services`: figures about a +caption track that any verifier recomputes from its signed revisions. Its latency is each cue's +first display on the room clock less the capture instant of the speech it carries, placed +through a take's opening commitment or as an aligner states it; its stability, the revisions +after first display and the words they changed; its accuracy, the word errors of the first +revision shown against a reviewed final revision or a signed reference transcript; all in +integer arithmetic over one fixed word alignment, so a quality figure a vendor states is checked +by recomputing it. An audio description track is a signed script of timed descriptions, the +ducking of the programme audio under each, and its voicing on a separate track or by the sink, +each labelled human or machine; its voice is held to the synchronisation bounds of the Dubbing +and Audio description Profiles of TTML2, and it maps onto a document of that profile. A sign +language track, an avatar pose stream or the video of a person signing, is bound by digest to +the final caption revisions it translates, with a reviewer's optional sign-off. A completeness +claim states that each access track a session declares was delivered complete and in sync, +against tolerances it names, and a verifier checks it against the records: +[`extensions/access-services.md`](extensions/access-services.md). + And for what a room session **cost** — `wai.live.metering`: every hop that carried the session (a relay, a compositor, an ingest gateway) signs one per-hop session record, `WMH1`: per track and direction the objects and bytes it carried and the objects it dropped by reason, with those diff --git a/wai/extensions/access-services.md b/wai/extensions/access-services.md index 874eecc5c..448deabe1 100644 --- a/wai/extensions/access-services.md +++ b/wai/extensions/access-services.md @@ -411,9 +411,9 @@ In order; the first that fails names the refusal: ### 5.3 Synchronisation -The programme audio falls to the event's gain over [`begin`, `begin` + `ramp`) and rises back -over [`end` − `ramp`, `end`). The description is **spoken** over the interval between, from -*a* = `begin` + `ramp` to *z* = `end` − `ramp`. Of a voiced event (its `voice` not `null`): +The programme audio falls to the event's gain from `begin` to `begin` + `ramp`, and rises +back from `end` − `ramp` to `end`. The description is **spoken** over the interval between, +from *a* = `begin` + `ramp` to *z* = `end` − `ramp`. Of a voiced event (its `voice` not `null`): - `voice.begin` ≥ *a* − 35 and `voice.begin` ≤ *a* + 45; - `voice.end` ≤ *z* + 45. @@ -433,9 +433,10 @@ A description is spoken in the pauses of the dialogue (47 CFR 79.3(a)(3): "into pauses between the program's dialogue"), though the regulator's 2024 statement accepts describing over dialogue where what is seen matters more (§6.14 there). So this is a figure, not a refusal. Against the dialogue of one or more caption tracks, whose resolved cues -(timed-text §4.5) cover the union *U* of their intervals [`start`, `end`), an event's -**overlap** is the milliseconds of its spoken interval, [`voice.begin`, `voice.end`) when it is -voiced and [*a*, *z*) otherwise, that lie in *U*. The figure is the sum of the overlaps and the +(timed-text §4.5) cover the union *U* of their intervals, each from its `start` up to, not +including, its `end`, an event's **overlap** is the milliseconds of its spoken interval that lie +in *U*: from `voice.begin` up to `voice.end` when it is voiced, and from *a* up to *z* +otherwise. The figure is the sum of the overlaps and the number of events whose overlap is above 0. ### 5.5 The DAPT document @@ -633,7 +634,7 @@ each was delivered complete and in sync. |---|---|---| | `kind` | `"wai-access-completeness"` | | | `room` | `hex32` | the room | -| `from`, `to` | `int` | the session, room-clock microseconds [`from`, `to`) | +| `from`, `to` | `int` | the session, from `from` up to, not including, `to`, in room-clock microseconds | | `pt0` | `int` | the media time of the room's `t0`, in milliseconds (timed-text §2) | | `tracks` | array | the access tracks it declares, each an object below | | `signer_pubkey`, `sig` | | §2 | @@ -647,7 +648,8 @@ each was delivered complete and in sync. The tracks a claim declares are the availability of access services an electronic programme guide states (EN 301 549 V4.1.1 clauses 12.4 and 12.5), made checkable. -A cue of *P* is **in the session** when its first revision's `t` is in [`from`, `to`). The +A cue of *P* is **in the session** when its first revision's `t` is at or after `from` and +before `to`. The session's media interval is from `pt0` + ⌊`from` / 1000⌋ to `pt0` + ⌊`to` / 1000⌋. ### 7.2 Checking the claim diff --git a/wai/extensions/timed-text.md b/wai/extensions/timed-text.md index d5d3829ac..b99e25865 100644 --- a/wai/extensions/timed-text.md +++ b/wai/extensions/timed-text.md @@ -48,8 +48,10 @@ disclosure label in every target (§10); and what a WAI player owes its viewers Out of scope: a transport; speech recognition and translation, which produce the text; the fragmented MP4 packaging of an IMSC1 rendition (HLS `draft-pantos-hls-rfc8216bis-22` §3.1.5 and ISO/IEC 14496-30 carry the document §6 writes); the paint-on style of 608, colours, -underline and flash; audio description; and a sink's own rendering of text, beyond §4.4 -and §11. +underline and flash; audio description, which [access-services](access-services.md) §5 +defines, with sign language and figures of a caption track's latency, stability and accuracy +computed from its revisions (§4 there); and a sink's own rendering of text, beyond §4.4 and +§11. Relationship to the core spec: `wai.text.timed` is a **record** ([SPEC](../SPEC.md) §5). Its unit is the signed caption revision, and the documents this extension writes are diff --git a/wai/live-conformance/README.md b/wai/live-conformance/README.md index 34bbb7687..de48fd624 100644 --- a/wai/live-conformance/README.md +++ b/wai/live-conformance/README.md @@ -11,6 +11,7 @@ and the independent verifier of each, beside it. | [`compose/`](compose/) | [live-compose](../extensions/live-compose.md) (`wai.live.compose`) | `live_compose_verify.py` | | [`recordings/`](recordings/) | [live-recording](../extensions/live-recording.md) (`wai.live.recording`) | `live_record_verify.py` | | [`captions/`](captions/) | [timed-text](../extensions/timed-text.md) (`wai.text.timed`) | `timed_text_verify.py` | +| [`access/`](access/) | [access-services](../extensions/access-services.md) (`wai.access.services`) | `access_services_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` | @@ -24,14 +25,16 @@ and the independent verifier of each, beside it. **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 +writes `recordings/`, `wai_timed_text_vectors gen` writes `captions/`, +`wai_access_services_vectors gen` writes `access/` and `wai_live_metering_vectors gen` writes `metering/`, `wai_energy_steering_vectors gen` writes `steering/`, `wai_live_moderation_vectors gen` writes `moderation/`, `wai_live_watermark_vectors gen` writes `watermark/`, `wai_live_ads_vectors gen` writes `ads/`, `wai_live_provenance_vectors gen` writes `c2pa-live/`, `wai_synthesis_vectors gen` writes `synthesis/` and `wai_ai_usage_vectors gen` writes `usage/`, 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`, +`compose/README.md`, `recordings/README.md`, `captions/README.md`, `access/README.md`, +`metering/README.md`, `steering/README.md`, `moderation/README.md`, `watermark/README.md`, `ads/README.md`, `c2pa-live/README.md`, `synthesis/README.md`, `usage/README.md`); `c2pa-live/` cuts its media from the packaging corpus's AV1 floor. `joule_moq_e2ee_vectors gen` (in @@ -51,6 +54,7 @@ python3 capture_take_verify.py takes python3 live_compose_verify.py compose python3 live_record_verify.py recordings python3 timed_text_verify.py captions +python3 access_services_verify.py access python3 live_metering_verify.py metering python3 energy_steering_verify.py steering python3 live_moderation_verify.py moderation diff --git a/wai/live-conformance/access/README.md b/wai/live-conformance/access/README.md new file mode 100644 index 000000000..7063fb3ff --- /dev/null +++ b/wai/live-conformance/access/README.md @@ -0,0 +1,46 @@ +# live-conformance/access — access services + +The corpus of [`extensions/access-services.md`](../../extensions/access-services.md) §11: room +sessions whose captions are `WEV1` events with their `WTX1` annotations, and the records of the +extension beside them: sources, reference transcripts, quality figures, audio descriptions, +signings, reviews and completeness claims, each a JSON text signed under `wai:access`. + +**Access-services equivalence.** For each vector, a conforming verifier of the corpus's room, +offered the events of the vector's `stream` in the order given and then its `records` (§8.1), +reaches the outcome the vector states (§8.2): `refuse`, with `at` (`events` or `record`), the +`index` of the record and the `reason`; or `accept`, with the `figures`: each whole caption +track's figure (§4.7), each description's events, voiced events and offsets (§5.3), each +signing's segments, revisions named, offsets and video floor (§6.3), and each claim's dialogue +overlap (§7.2). Signed integers are written as strings. For each entry of `documents`, the +description record it names maps, with the voicing track's `uri` and `type`, onto the DAPT +document in `file` byte for byte (§5.5), or is refused with `reason`. A verifier that reaches +another outcome, place, reason, figure or byte does not conform. + +**Provenance.** Generated here: `wai_access_services_vectors gen` writes `vectors.json` and +each DAPT document from events and records authored in code, from fixed seeds. Each key, +model, track and object digest is SHA-256 of a fixed label and an index, the room id +likewise, every time is a constant, and Ed25519 signing is deterministic (RFC 8032), so every +file is the same bytes on every machine. The captions, descriptions and transcripts are +written for the corpus, in English. The objects a signing names are digests only: no pose +stream, video or audio is in the corpus. The generator asserts, before it writes, that each +vector reaches the outcome it was written to have and that every reason of §10 refuses a +case. No recorded data. + +## Layout + +- `vectors.json`: `room`, `pt0_ms`, `principals` (the event authors `captioner`, `asr`, + `host` and `device`, and the record signers), `streams` (each a list of `WEV1` records in + lowercase hexadecimal: `lesson`, `reviewed`, and three defective copies of the lesson), + `vectors` (each with `name`, `note`, `stream`, `records` and its outcome) and `documents`. +- `NAME.dapt.ttml`: the DAPT document of vector `NAME`'s description. + +## Checking + +``` +cargo run --no-default-features --features access_services --bin wai_access_services_vectors -- verify ../live-conformance/access +python3 -I access_services_verify.py access +``` + +The first runs from `wai-rs/`, the second from `live-conformance/`. The second is the +corpus's second implementation, written from the extension's text; it shares no code with +`wai-rs`. diff --git a/wai/registry/capabilities.json b/wai/registry/capabilities.json index 2d0cb3198..556219350 100644 --- a/wai/registry/capabilities.json +++ b/wai/registry/capabilities.json @@ -1,6 +1,20 @@ { "schema": "https://git.transaction.science/Transaction-Science/open-standards/src/branch/main/wai/registry/capabilities.schema.json", "capabilities": [ + { + "capability": "wai.access.services", + "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-21" + }, { "capability": "wai.ai.usage", "kind": "record", @@ -2284,6 +2298,13 @@ "section": "§10.5", "status": "defined" }, + { + "name": "tag:transaction.science,2026:wai/access", + "kind": "scheme", + "document": "extensions/access-services.md", + "section": "§5.5", + "status": "defined" + }, { "name": "tag:transaction.science,2026:wai/class", "kind": "scheme", @@ -2347,6 +2368,13 @@ "section": "§3", "status": "defined" }, + { + "name": "wai-access-completeness", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§7.1", + "status": "defined" + }, { "name": "wai-c2pa", "kind": "catalog", @@ -2354,6 +2382,27 @@ "section": "§10.2", "status": "defined" }, + { + "name": "wai-caption-quality", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.7", + "status": "defined" + }, + { + "name": "wai-caption-reference", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.3", + "status": "defined" + }, + { + "name": "wai-caption-sources", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.2", + "status": "defined" + }, { "name": "wai-derivation", "kind": "document-kind", @@ -2361,6 +2410,13 @@ "section": "§5.1", "status": "defined" }, + { + "name": "wai-description", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§5.1", + "status": "defined" + }, { "name": "wai-detection", "kind": "document-kind", @@ -2438,6 +2494,20 @@ "section": "§9.1", "status": "defined" }, + { + "name": "wai-signing", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§6.1", + "status": "defined" + }, + { + "name": "wai-signing-review", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§6.4", + "status": "defined" + }, { "name": "wai1", "kind": "codecs-prefix", diff --git a/wai/vocab/v2.ttl b/wai/vocab/v2.ttl index 0078b7198..a68d86cb7 100644 --- a/wai/vocab/v2.ttl +++ b/wai/vocab/v2.ttl @@ -103,6 +103,13 @@ wai:pinTier a owl:DatatypeProperty ; rdfs:domain wai:ParameterSetPin ; rdfs:rang # ─── Registered strings ────────────────────────────────────────────── +wai:wai.access.services a wai:Capability ; + rdfs:label "wai.access.services" ; + wai:kind wai:kind-record ; + wai:status wai:status-registered ; + wai:specSection "§5 Interactive, temporal & computed content" ; + wai:registeredOn "2026-10-21"^^xsd:date . + wai:wai.ai.usage a wai:Capability ; rdfs:label "wai.ai.usage" ; wai:kind wai:kind-record ; diff --git a/wai/wai-rs/src/codecs/registry.rs b/wai/wai-rs/src/codecs/registry.rs index 928acca59..477a00cdb 100644 --- a/wai/wai-rs/src/codecs/registry.rs +++ b/wai/wai-rs/src/codecs/registry.rs @@ -225,6 +225,7 @@ pub const CAP_LIVE_PROVENANCE: &str = "wai.live.provenance"; pub const CAP_EDGE_DERIVATION: &str = "wai.edge.derivation"; pub const CAP_MEDIA_SYNTHESIS: &str = "wai.media.synthesis"; pub const CAP_AI_USAGE: &str = "wai.ai.usage"; +pub const CAP_ACCESS_SERVICES: &str = "wai.access.services"; /// One row per string SPEC §5 registers that is a payload, companion or record: /// `(string, SPEC section, edition, registered)`. @@ -318,6 +319,7 @@ const ROWS: &[(&str, &str, Option<&str>, &str)] = &[ (CAP_LIVE_PROVENANCE, S_INTERACTIVE, None, "2026-10-21"), (CAP_MEDIA_SYNTHESIS, S_INTERACTIVE, None, "2026-10-21"), (CAP_AI_USAGE, S_INTERACTIVE, None, "2026-10-21"), + (CAP_ACCESS_SERVICES, S_INTERACTIVE, None, "2026-10-21"), (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"), @@ -374,6 +376,7 @@ const RECORDS: &[&str] = &[ CAP_EDGE_DERIVATION, CAP_MEDIA_SYNTHESIS, CAP_AI_USAGE, + CAP_ACCESS_SERVICES, ]; /// A named identifier SPEC uses that has the shape of a capability string but is @@ -534,6 +537,7 @@ const LIVE_ADS: &str = "extensions/live-ads.md"; const LIVE_PROVENANCE: &str = "extensions/live-provenance.md"; const DERIVING_EDGE: &str = "extensions/deriving-edge.md"; const SYNTHESIS: &str = "extensions/synthesis.md"; +const ACCESS_SERVICES: &str = "extensions/access-services.md"; const fn wire(name: &'static str, kind: WireKind, document: &'static str, section: &'static str, status: WireStatus) -> WireIdentifier { @@ -545,8 +549,8 @@ const fn wire(name: &'static str, kind: WireKind, document: &'static str, sectio /// (jwp-receipts §7), of packaging, of live events, of live rooms, of capture binding, of /// live composition, of live recording, of timed text, of live metering, of energy steering, /// of live moderation, of confidentiality, of forensic watermark sessions, of live ads, of live -/// provenance, of the deriving edge, of synthesis and of AI usage, in document order. The export -/// lists them sorted by name and kind. +/// provenance, of the deriving edge, of synthesis, of AI usage and of access services, 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), @@ -644,6 +648,14 @@ pub const WIRE_IDENTIFIERS: &[WireIdentifier] = &[ wire("WAU1", WireKind::Magic, AI_USAGE, "§4.2", WireStatus::Defined), wire("wai_ai_usage", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined), wire("WAI-Usage-Claim", WireKind::HttpHeader, AI_USAGE, "§7.3", WireStatus::Proposed), + wire("wai-caption-sources", WireKind::DocumentKind, ACCESS_SERVICES, "§4.2", WireStatus::Defined), + wire("wai-caption-reference", WireKind::DocumentKind, ACCESS_SERVICES, "§4.3", WireStatus::Defined), + wire("wai-caption-quality", WireKind::DocumentKind, ACCESS_SERVICES, "§4.7", WireStatus::Defined), + wire("wai-description", WireKind::DocumentKind, ACCESS_SERVICES, "§5.1", WireStatus::Defined), + wire("tag:transaction.science,2026:wai/access", WireKind::Scheme, ACCESS_SERVICES, "§5.5", WireStatus::Defined), + wire("wai-signing", WireKind::DocumentKind, ACCESS_SERVICES, "§6.1", WireStatus::Defined), + wire("wai-signing-review", WireKind::DocumentKind, ACCESS_SERVICES, "§6.4", WireStatus::Defined), + wire("wai-access-completeness", WireKind::DocumentKind, ACCESS_SERVICES, "§7.1", WireStatus::Defined), ]; /// A string with the shape of a capability that the reference implementation uses -- 2.54.0 (Apple Git-157) From e3d105b66bc4009eedeceeb72b7aa457ee39295d Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Wed, 21 Oct 2026 19:23:32 -0400 Subject: [PATCH 4/4] registry export: regenerated after merging main Co-Authored-By: Claude Opus 5.5 --- wai/registry/capabilities.json | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/wai/registry/capabilities.json b/wai/registry/capabilities.json index 3cb107ada..152f9f284 100644 --- a/wai/registry/capabilities.json +++ b/wai/registry/capabilities.json @@ -1,6 +1,20 @@ { "schema": "https://git.transaction.science/Transaction-Science/open-standards/src/branch/main/wai/registry/capabilities.schema.json", "capabilities": [ + { + "capability": "wai.access.services", + "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-21" + }, { "capability": "wai.ai.usage", "kind": "record", @@ -2333,6 +2347,13 @@ "section": "§10.5", "status": "defined" }, + { + "name": "tag:transaction.science,2026:wai/access", + "kind": "scheme", + "document": "extensions/access-services.md", + "section": "§5.5", + "status": "defined" + }, { "name": "tag:transaction.science,2026:wai/class", "kind": "scheme", @@ -2396,6 +2417,13 @@ "section": "§3", "status": "defined" }, + { + "name": "wai-access-completeness", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§7.1", + "status": "defined" + }, { "name": "wai-authorship-map", "kind": "document-kind", @@ -2410,6 +2438,27 @@ "section": "§10.2", "status": "defined" }, + { + "name": "wai-caption-quality", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.7", + "status": "defined" + }, + { + "name": "wai-caption-reference", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.3", + "status": "defined" + }, + { + "name": "wai-caption-sources", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§4.2", + "status": "defined" + }, { "name": "wai-contribution", "kind": "document-kind", @@ -2424,6 +2473,13 @@ "section": "§5.1", "status": "defined" }, + { + "name": "wai-description", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§5.1", + "status": "defined" + }, { "name": "wai-detection", "kind": "document-kind", @@ -2515,6 +2571,20 @@ "section": "§3.1", "status": "defined" }, + { + "name": "wai-signing", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§6.1", + "status": "defined" + }, + { + "name": "wai-signing-review", + "kind": "document-kind", + "document": "extensions/access-services.md", + "section": "§6.4", + "status": "defined" + }, { "name": "wai-step", "kind": "document-kind", -- 2.54.0 (Apple Git-157)