open-standards/wai/live-conformance/ads
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-20 08:47:53 -04:00
..
chapters.m3u8 live-conformance/ads: the corpus from fixed seeds (rooms, policies, receipts, HLS tags) 2026-10-20 08:37:43 -04:00
live_break.m3u8 live-conformance/ads: the corpus from fixed seeds (rooms, policies, receipts, HLS tags) 2026-10-20 08:37:43 -04:00
mid_roll.m3u8 live-conformance/ads: the corpus from fixed seeds (rooms, policies, receipts, HLS tags) 2026-10-20 08:37:43 -04:00
post_roll.m3u8 live-conformance/ads: the corpus from fixed seeds (rooms, policies, receipts, HLS tags) 2026-10-20 08:37:43 -04:00
README.md live-conformance/ads: a control for each other rule of the break receipt (format, work, figure without class, resolution floor, its own ceiling) 2026-10-20 08:47:53 -04:00
vectors.json live-conformance/ads: a control for each other rule of the break receipt (format, work, figure without class, resolution floor, its own ceiling) 2026-10-20 08:47:53 -04:00

live-conformance/ads — live ads

The corpus of extensions/live-ads.md §11: rooms whose cue events open ad breaks, each a room (its WRD1 descriptor, WRG1 grants, key-log head or none, and each principal's WEV1 chain, the break annotations WAB1 among them), its WAP1 ad policy, the presentation time of t0 on the DASH Period (pt0_ms), and the break-form wai.video.ssai receipts of its viewers, each with the pod its decision ran over; what a verifier states of them; and each accepted room's HLS tags, byte for byte.

Ads equivalence. For each vector, a conforming ads verifier given its descriptor, grants, key_log, chains, policy, pt0_ms, receipts and pods (§9.1) reaches the outcome the vector states (§9.4):

  • refuse: the reason and where, at: ["room", …] with the room verifier's own place (live-rooms §9.1), ["policy"], ["record", c, i] for record i of chain c, or ["receipt", k];
  • gap: the room's gaps, each principal, first and last;
  • accept: the room id; the breaks (§4.3), each its digest, id and event_id (§4.4), author, cue_id, t, type (out or break), placement (mid or post), planned_ms, avail_ms, duration_ms, closed_by and end (null while it is open), and its hls_list_uri and dash_list_uri (§7.2, §7.3); the chapters, each digest, t and duration_ms; hls, the file holding the room's HLS tags; dash, the Period's event streams (§6.3); dash_open, each out's event as written before its in, by the out's index among the breaks; receipt_facts, each receipt's identity (§8.4), the asset_list it binds as the verifier writes it, and its spend_micros; and spend_micros, the spend of every receipt together.

Each tag file, NAME.m3u8, is the HLS tags of vector NAME (§5.1 to §5.3), one tag a line in the order §5.4 gives, each line ended by a line feed. It is the date ranges of the room's Media Playlists, not a whole playlist: the segments are the room's tracks.

A verifier that reaches another outcome, reason, place, break, tag byte, event byte, asset-list byte, identity or spend does not conform.

Provenance. Generated here: wai_live_ads_vectors gen writes every file from rooms authored in code, from fixed seeds. Each principal's key is SHA-256 of a fixed label and the principal's index; each creative's hash and each session id likewise; every time is a constant (the rooms' t0 is 2026-10-16T00:00:00Z); every origin and base URI is an .example name (RFC 2606); and Ed25519 signing is deterministic (RFC 8032), so every file is the same bytes on every machine. The generator asserts that each vector reaches the outcome it was written to have, and that the corpus gives every reason of §10, before it writes. No recorded data.

Layout

  • vectors.json: principals (the keys, by name, informative) and vectors.
  • NAME.m3u8: the HLS tags of each accepted room.

Every room has a producer, whose grant permits cue, meta and chat; a viewer, whose grant permits chat; and the decider, whose grant permits no event and carries the room's ad budget, 2 minor units of EUR (2 000 000 millionths), and which never joins. The clock admits the producer and the viewer at the room's start.

The rooms:

  • live_break: an out at 60 s with no planned duration and its in at 90 s, under a policy whose open avail is 30 s and whose preload is 4 s. One viewer, present at the break's start, is filled with two 15 s ads from an HLS asset list (its decision energy model-based); a second joins 12 s into the break and is filled with what remains, one ad, from a DASH list MPD (its decision energy an on-chip counter's reading). No pre-roll.
  • mid_roll: a 30 s break, annotated mid-roll, under a policy that restricts skipping and jumping, snaps both ways and offers a skip control after 5 s, with pt0_ms 5000. One viewer's pod has two ads at one price, ordered by ad_id, and three fill the avail; another viewer's only ad costs more than its funds, so its fill is empty and its DASH list MPD is no bytes.
  • post_roll: two chapters, a 15 s mid-roll at 30 s, and a 20 s break annotated post-roll at 120 s; one viewer filled in both breaks, another in the post-roll only.
  • chapters: a chapter of a stated length and one of none, then an out with a planned duration of 15 s and its in, which states no duration.
  • gap: live_break's room as a subscriber holds it when the out was not delivered.
  • refused, one defect each: cue_kind_not_permitted (refused by the room, kind_not_permitted), policy_slots_zero, policy_wrong_room, policy_bad_signature, decider_grant_unknown, decider_grant_revoked (a room whose key log revokes the decider grant, grant_revoked), annotation_placement, annotation_on_out, cue_after_post_roll, overlapping_breaks, open_break_no_avail, break_of_no_duration, in_without_out, in_duration_mismatch, receipt_extra_member, receipt_wrong_room, receipt_bad_signature, receipt_quartile_six and, for the other rules of §8.5 each broken alone, receipt_format_three, receipt_work_below_fill, receipt_figure_without_class, receipt_below_resolution and receipt_over_its_ceiling (all receipt_invalid), receipt_not_decider, receipt_grant_mismatch, receipt_names_the_in, decider_grant_expired (outside_grant_window), pod_mismatch, decision_mismatch, asset_list_mismatch, receipt_duplicate and funds_exceeded (a budget of 1 minor unit, and two viewers each billed 600 000 millionths).

Running

cd ../../wai-rs
cargo run --no-default-features --features live_ads --bin wai_live_ads_vectors -- verify ../live-conformance/ads
cargo run --no-default-features --features live_ads --bin wai_live_ads_vectors -- gen    ../live-conformance/ads   # regenerate
cargo test --no-default-features --features live_ads --test live_ads
cd ../live-conformance
python3 -I live_ads_verify.py ads

wai_live_ads_vectors verify and tests/live_ads.rs require every file to regenerate byte for byte, no other file but this one to be there, and wai-rs to give every case its outcome; the test also requires §10 to list exactly the reasons the reference reports, and the generator that the corpus gives each of them. live_ads_verify.py is the second implementation, written from the extension's text and sharing no code with wai-rs: it verifies each room with live_rooms_verify.py, writes every tag, event and asset list itself, verifies every receipt's signature with WAI's strict Ed25519 rule and computes its BLAKE3 hashes from the specification, reads §10 from the extension, gives every case the same outcome, requires every reason of §10 to appear, and then mutates copies of the corpus, one defect each, each of which must fail. Pass = an exit status of 0 from each.