open-standards/wai/extensions/access-services.md
Transaction Science 4dacdb2038
Some checks failed
WAI conformance / does this change touch it (pull_request) Successful in 5s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 5s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 6s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 8s
WAI energy receipts / does this change touch it (pull_request) Successful in 5s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 5s
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Successful in 6s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 5s
wai-web wasm32 / does this change touch it (pull_request) Successful in 5s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 6s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 27s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 1m0s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 12s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 25s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m10s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 28s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 2m17s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 1m34s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 5m38s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 9m11s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 3m15s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 18m23s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 18m40s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m48s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 1m46s
wai-pack / wai-pack · linux (pull_request) Successful in 1m41s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 4m14s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 3m18s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m39s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 14m26s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 2m43s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 8m48s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 3m57s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 42m36s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 17m14s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 26s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m6s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 8m1s
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
wai.access.services: registry entry and export, SPEC §5, CHANGELOG, CI step, corpus README; timed-text's scope points to it
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 12:27:36 -04:00

51 KiB
Raw Permalink Blame History

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'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/, 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 §5): a signed record a WAI tool emits and verifies. It names no payload format and is not dispatchable.

Relationship to timed-text: 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 and capture-binding: 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).

Relationship to synthesis: 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 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 §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 §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 §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 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.

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, 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

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:

<?xml version="1.0" encoding="UTF-8"?>
<tt xmlns="http://www.w3.org/ns/ttml" xmlns:ttp="http://www.w3.org/ns/ttml#parameter" xmlns:tta="http://www.w3.org/ns/ttml#audio" xmlns:daptm="http://www.w3.org/ns/ttml/profile/dapt#metadata" xmlns:wai="tag:transaction.science,2026:wai/access" xml:lang="LANG" ttp:contentProfiles="http://www.w3.org/ns/ttml/profile/dapt1.0/content" daptm:langSrc="zxx" daptm:scriptRepresents="REPS" daptm:scriptType="TYPE" wai:script="SO" wai:voice="VO">
<body>
EVENTS
</body>
</tt>
  • 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:

    <div xml:id="ID" begin="B" end="E" daptm:represents="R">
    <animate begin="00:00:00.000" end="RAMP" tta:gain="1;G" fill="freeze"/>
    <animate begin="FALL" end="DUR" tta:gain="G;1"/>
    <p>CONTENT</p>
    </div>
    

    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 <br/> and &, < and > written &amp;, &lt; and &gt;:

    • for the form track and a voiced event, <span begin="VB" end="VE"><audio src="U" type="T" clipBegin="CB" clipEnd="CE"/>TEXT</span>, 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, <span tta:speak="normal">TEXT</span>.

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 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 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. 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

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, 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
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 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

  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 §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 or timed-text refuses keeps that extension's reason.

11. Conformance

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.