| Filename | Latest commit message | Latest commit date |
|---|---|---|
The change of wai/ad-consent-supply-chain (44d5f2264..110c53553, 2 commits), on the fix branch: its changelog entries as files of wai/changes/, its wai-conformance.yml edits as step files, corpus files and test tags, and every other file as the branch has it. - f8fe39cba WAI: an ad decision's consent signal and supply chain, bound into what the decider signs - 110c53553 WAI: a GPP string links what carries it; a chain per impression; sellers files read exactly Co-Authored-By: Claude Opus 5.5 <[email protected]> |
||
| .. | ||
| consent.viewer51.m3u8 | ||
| consent.viewer51.vast.xml | ||
| consent.viewer52.m3u8 | ||
| consent.viewer52.vast.xml | ||
| double_box.m3u8 | ||
| double_box.vmap.xml | ||
| form1_prefetch.m3u8 | ||
| form1_prefetch.receipt.json | ||
| hls_interstitial.assets.json | ||
| hls_interstitial.bid.json | ||
| hls_interstitial.m3u8 | ||
| hls_interstitial.vast.xml | ||
| hls_stitched.viewer1.m3u8 | ||
| hls_stitched.viewer1.vast.xml | ||
| hls_stitched.viewer2.m3u8 | ||
| hls_stitched.viewer2.vast.xml | ||
| README.md | ||
| squeezeback.mpd | ||
| squeezeback.vast.xml | ||
| vectors.json | ||
live-conformance/stitched — stitched presentation
The corpus of extensions/stitched-presentation.md
§10: streams with ads another party stitched into their segments or served as interstitials;
the manifests the players read (HLS Media Playlists, an asset list, an MPD); the ad servers'
responses (VAST documents and a form-1 wai.video.ssai receipt); the WSI1 pod-input record
each break's signer signed; the WSC1 claims the players signed, good ones and a control of
each check; what a verifier states of them.
Presentation equivalence. For each vector, a conforming verifier given its records and
claims, the files its manifests, responses and receipts name, and the corpus's
creatives, issuers and signers (§7.1), states exactly:
record_facts, each record in the order given: itsdigest(nullwhen it does not read) and itsverdict,acceptedor a reason; for an accepted record,response_checked, itsads(eachslot, itsown_claimsby index,presentations,verdict,quartiles,presented_spend_microsandstated_quartile), itspresented_spend_micros, itsstated_spend_micros, its frame'sshare_bpand adregion(rectangles[x, y, w, h],nullfor the full picture), and, for a record of version 2, itsconsent(gpp,gpp_sid,child_directed);claim_facts, each claim in the order given: itsdigest, itsverdict,presentedor a reason, therecordandslotit names (from §7.3 step 4 on), and, for an own claim, thequartileit reaches, itsrun_msand itsviewable_ms;spend, the presented spend by currency.
record_about and claim_about say what each record and claim is, and are not checked. The
files a vector's bound names are documents a record binds by digest and no verifier reads
(a winning bid, a VMAP response); they are here so that anyone recomputes the digests. A
verifier that states another verdict or fact does not conform.
Provenance. Generated here: wai_stitched_presentation vectors gen writes every file from
streams authored in code, from fixed seeds. Each session key is SHA-256 of
wai:stitched-presentation/corpus/player, a zero byte and its number (players lists their
public keys); each signer's key the same with signer (signers 1 and 2 are the trusted ones,
signers; signer 9 is not); each media object's content hash SHA-256 of a fixed label and two
numbers; each token's nonce SHA-256, and its salt SHA-384, of a fixed label and its number. The
attestation issuer's key is the test key RFC 9578 Appendix A.2 publishes, as in
../presentation/. Every playlist, asset list, MPD, VAST document, bid
document and receipt is a fixture written for its case under example domains; none was fetched
from a service. Ed25519, BLAKE3 and RSASSA-PSS over a given salt are deterministic, so every
file is the same bytes on every machine. The generator asserts that each record and claim gets
the verdict it was written to have and that the corpus gives every reason of §9, before it
writes. No recorded data.
Layout
vectors.json:creatives, each itsobjects(content_hash,duration_ms);issuers;signers(Ed25519 public keys, hexadecimal);players(informative); andvectors.NAME.*: each vector's documents:.m3u8Media Playlists,.assets.jsonan asset list,.mpdan MPD,.vast.xmlVAST 4.3 responses,.vmap.xmla VMAP response,.bid.jsona winning bid's document,.receipt.jsona form-1 receipt in its JSON carriage (§4.5).
The vectors:
hls_stitched: two viewers' personalised playlists, each ad under a date range whoseX-AD-IDcarries itsAdServingId; a record per viewer priced from its VASTPricing(CPM 25.00, 18.00 and 30.00 USD). Presented: viewer 1's two ads (the second to its third quartile) and viewer 2's first. Viewer 2's second ad was fetched ahead of the break and never presented:claim_absent, no spend. Record controls:pod_signer_unknown,pod_response_mismatch(a price the response does not give; a universal creative identifier it does not carry),pod_duplicate,pod_input_malformed,bad_signature. Claim controls:claim_duplicate,claim_key_unbound,claim_session_unbound,claim_no_decision,claim_manifest_unknown,claim_marker_absent,stitched_claim_malformed(truncated; a signed skip with no resumption),bad_signature.hls_interstitial: one shared playlist with an interstitial date range, and the asset list a viewer was served; records under the cross-media rule with an audible run and attestation, ad-i1 at a winning bid's price (its document bound by digest), ad-i2 at CPM 20.00. Presented: viewer 11's two, attested on a television. Controls:attestation_absent,attestation_invalid(another presentation's token).squeezeback: a squeeze on a DASH channel, the program in a 1440 × 810 window in the bottom right corner and the ad in the L around it (4375 basis points of the picture), marked by an event whosemessageDatacarries the ad'sAdServingId; one shared record. Presented: viewers 21, 22 (70% of the region in view) and 23 (to the midpoint): three presentations. Controls:claim_frame_mismatch,claim_not_viewable,claim_duplicate,claim_asset_mismatch.double_box: a double box on an HLS channel, its record in EUR at a price the signer states, its VMAP response bound and not read. Presented: viewer 31 over the ad's box, viewer 32 over the player's area.form1_prefetch: a stitcher's own decision sealed in a form-1 receipt whose beacons counted ad-f2 as started when its first segment was fetched ahead of the break; viewer 41 left after ad-f1. Stated: quartiles 5 and 1, 5 000 000 µ-units; presented: ad-f1 alone, 3 000 000. Control:pod_response_mismatch(the same receipt at another price).consent: two viewers' personalised playlists, each with one stitched ad, and a record of version 2 per viewer (§4.7): viewer 51's carries the GPP string its player gave, the example the GPP string's text gives for a service reached by a URL, with section 2; viewer 52's no string and a child-directed request. Presented: both. Controls: viewer 53's record with its GPP string changed after signing (bad_signature), whose ad's claim then names no decision (claim_no_decision); a shared record carrying a viewer's string, and a record stating a section with no string (eachpod_input_malformed).
Running
cd ../../wai-rs
cargo run --no-default-features --features stitched_presentation --bin wai_stitched_presentation -- vectors verify ../live-conformance/stitched
cargo run --no-default-features --features stitched_presentation --bin wai_stitched_presentation -- vectors gen ../live-conformance/stitched # regenerate
cargo test --no-default-features --features stitched_presentation --test stitched_presentation
cd ../live-conformance
python3 -I stitched_presentation_verify.py stitched
node --test ../../joule-code/joule-code-rs/crates/joule-moq-web/web/ads/stitched.test.mjs
vectors verify and tests/stitched_presentation.rs require every file to regenerate byte for
byte, no other file but this one to be there, and wai-rs to give every vector its facts; the
test also requires §9 to list exactly the codes the reference adds.
stitched_presentation_verify.py is the second implementation, written from the extension's
text and sharing no code with wai-rs: it reads every manifest, response, record and claim
itself (with the spans' quartile and run and RSASSA-PSS of ad_presentation_verify.py, a
form-1 receipt's leaves of live_ads_verify.py and the ad frame of live_compose_verify.py),
requires every reason to appear, then mutates copies of the corpus, one defect each, each of
which must fail, and drops each of its own checks in turn, each weakened verifier of which the
corpus must catch. The browser client's reference producer requires the corpus's claims from
the corpus's manifests and observation sequences. Pass = an exit status of 0 from each.
The tool's inputs
wai_stitched_presentation verify <bundle.json> (and POST /v1/verify of the service) reads one
JSON object:
| member | value |
|---|---|
records |
the pod-input records, hexadecimal |
claims |
the claims, hexadecimal, at most 2^20 |
manifests |
the manifests' texts, as strings |
responses |
the VAST and VMAP documents' texts, as strings |
receipts |
form-1 receipts in their JSON carriage (§4.5), as objects |
creatives |
as vectors.json's |
issuers |
as vectors.json's |
signers |
the accepted signers' keys, hexadecimal |
and prints record_facts, claim_facts and spend as this corpus states them, with the
capability. wai_stitched_presentation sign-pod <draft.json> --key <seed-file> reads a draft
of a record: the fields of §4.1 by name (carriage, session in hexadecimal or absent for a
shared break, avail_id, avail_ms, response_format, response_file (a path beside the
draft whose SHA-256 is taken) or response (hexadecimal), id_kind, id_attr, currency,
exponent, frame (its fields, or absent for the full picture) and requirement
(require, rule, token_type, issuer)), and ads, each with marker as its fields
(id and start for carriage 1; and index for 2; period, scheme, value and id for
3), ad_id, serving_id, creative_id, registry, creative_hash, duration_ms,
price_micros, price_source and evidence; and, for a record of version 2, consent, as
live-ads §8.6's JSON carriage writes it (gpp, gpp_sid, child_directed). It refuses a draft
that breaks §4.4, and prints the signed record in hexadecimal.