A channel's operator needs to know, per input, whether the picture went black or froze, the sound went silent, captions or cues stopped, or the transport stream broke; and an input switch needs that answer from a monitor it can hold to account. extensions/signal-health.md registers `wai.live.signal_health`: a monitor's signed record (WSH1) of one input over a window with up to six checks: black and freeze over the decoded luma, silence in 10 ms blocks, caption and cue gaps, and the first-priority indicators of ETSI TR 101 290 V1.4.1 (sync lost with its five-and-two hysteresis, bad sync bytes, PAT_error_2, continuity, PMT_error_2, PID_error). Each check states its thresholds, its integer values, the digest of the media it read and its verdict. A verifier holds each verdict to its values and thresholds and each threshold to the profile it expects with no media, and recomputes every value with it; an input switch carries the first input whose latest record by a trusted monitor is fresh and states no fault. The reference is the `signal_health` module of wai-rs; the corpus is live-conformance/signal-health/ (41 records, 26 checks against a profile and their media, 10 switches), its media written from fixed seeds with each case's values declared and held by the generator, and signal_health_verify.py is its second implementation: 77 cases agree, 14 of 14 mutated copies fail and 30 of 30 weakened verifiers are caught. Twelve faults planted in the reference (the verdict rule, the freeze's held frame, the duplicate allowance, the discontinuity indicator, the profile, trust, silence over one channel, the PAT gap, the end of the window, the sync hysteresis, the media digest, freshness) each fail its tests. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2.7 KiB
live-conformance/signal-health — what a monitor measured on an input
The corpus of extensions/signal-health.md §9, in one
file, vectors.json.
Provenance. Generated here by wai_signal_health_vectors gen (wai-rs, feature
signal_health), from Ed25519 keys on fixed 32-byte seeds, constant instants, and media the
generator writes from a linear congruential generator with fixed seeds: luma planes of 16 × 8
and 8 × 8 samples, two channels of 16-bit samples at 800 Hz, caption and cue instants, and
transport streams of 40 packets at 30 080 bit/s (a packet every 50 ms) holding a program
association and a program map section with their CRCs and packets of two elementary streams;
no recording and no input from outside this repository.
keys names every key by its role, as 64 lowercase hexadecimal digits: two monitors a switch
trusts (monitor_a, monitor_b) and one it does not (rogue). profile gives the operator's
thresholds, per check by name; switch the switch's inputs in its order, the keys it trusts and
max_age_ms.
records(§4, §6.1, §6.2) are each a record'sbytesin hexadecimal, and itsoutcome:read, with itsdigest,inputand the names of its faulted checks (faults); orrefuseand itsreason.checks(§6.3, §6.4) are each arecord, theprofilea verifier expects (ornull) and themediait holds:frames(eachat_ms,width,heightandlumain hexadecimal),audio(at_ms,rate,channelsandsamples, the little-endian bytes in hexadecimal),captionsandcues(instants), andtransport(first_us,rate_bpsandbytesin hexadecimal), each present only where held.outcome.recordisstandsorreject reason=…, andoutcome.checksgives each check of a record that stands, in its order:recomputed,not_heldorreject reason=….switches(§7) are each therecordsa switch holds, the instantat_msand the input it carries (current);outcomegives each record's state, each input's state in the switch's order and the input itselected.
Everything is synthetic: keys attest nothing, and the media is the generator's. Each media case's values are declared in the generator, which requires the reference to measure them, and each case states the outcome it was written to have, never copied from a verifier.
wai_signal_health_vectors verify and tests/signal_health.rs check that the file regenerates
byte for byte and that wai-rs reaches every stated outcome. ../signal_health_verify.py is the
second implementation, written from the extension's text, which also mutates copies of the
corpus and drops each of its own checks in turn and requires each to be caught.