open-standards/wai/live-conformance/opportunity/README.md
Transaction Science 372f063bcb wai: the opportunity report and the statement check (wai.delivery.opportunity)
extensions/opportunity-report.md: the ad breaks a channel's own signed records
prove, per owner and period (WOR1): the cues of a room a share contract names,
made into breaks by live-ads and their SCTE 35 sections read for slots, and the
program-as-run's ad entries no cue covers, each attributed by its start to the
programme on air; a documented JSON and CSV form for a platform's reported
figures, never evidence; and the check (WCK1) setting them side by side, with
the operator's signed revenue-share statement where given.

wai-rs: the opportunity_report module (feature opportunity_report), its SCTE 35
subset reader, the reported statement's reader, the corpus generator
wai_opportunity_vectors and tests/opportunity_report.rs with the worked example.
revenue_share's the_runs and asset_at become pub(crate), unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:12:30 -04:00

87 lines
6.1 KiB
Markdown

# live-conformance/opportunity — the opportunity report and the statement check
The corpus of [`extensions/opportunity-report.md`](../../extensions/opportunity-report.md) §14, in
one file, `vectors.json`:
- `contracts`: share contracts (revenue-share §3), by name, each hexadecimal;
- `runs`: the channel's program-as-run windows, by name, each in its carriage (revenue-share §4.1);
- `rooms`: rooms, by name, each as a report's document holds one (§8.1): its `descriptor`, `grants`,
`key_log`, `chains` and `policy`;
- `ledgers`: ledger documents (receipt-ledger §7.1), by name, each whole, for the signed
statements;
- `reported`: reported statements (§9), by name, each its `form` and `text`;
- `vectors`: verification documents, each of `kind` `report` (§8.1: the names of its `contract`,
other `contracts`, `runs` (or `null`) and `rooms`, and its `report` in hexadecimal) or `check`
(§11.1: such a `report`, the name of its `reported` statement, its signed `statement` (the name
of its contract, the statement in hexadecimal, the names of its runs and ledgers) or `null`, and
its `check` in hexadecimal), with the `outcome` §8.3 or §11.3 gives it;
- `keys`: the operator's, the two owners', the channel signer's, the auditor's, the room
producer's and the ad decider's public keys.
**Equivalence.** For each vector, a conforming verifier given its parts, resolved by name, reaches
the outcome the vector states:
- `refuse`: the `reason` and where, `at`: `[]` for the document; `["contract"]` and the places
revenue-share §8.2 gives; `["report"]`; `["run", k]`; `["room", k]`, followed by live-ads' own
place for a room live-ads refuses; `["room", k, "break", i]` for a cued break (its index in its
room's schedule); `["run", k, "entry", e]` for a scheduled break; for a check, `["report", …]`,
`["reported"]`, `["statement", …]` and `["check"]`;
- `accept`, for a report: its digest, the contract's, the `issuer`, the `party` and its `role`,
`start` and `end`, the `rooms` and `runs`, each break in the period (its class, its room and
index or the run and entry it was taken in, its opening `cue`, its `start`, `duration_ms`,
whether it is `open`, its `slots` and where they came from, what its `section` states, its run,
entry, asset and split, and the records it `cites`), each line (split, class, breaks,
`break_ms`, slots, unslotted, `ppm`, `cites`), and the `totals`;
- `accept`, for a check: its digest, the `issuer`, the report's digest, `party`, `start` and
`end`, the reported statement's digest, `form` and `basis`, the signed `statement`'s digest or
`null`, the bounds, and each line with its figures, its `signed` figures or `null`, and the names
of its `flags`.
The channel, `fast-9`, airs two windows of 2026-10-16: the first hour (owner A's `a/ep-1`, the ad
slot `slate-90`, owner B's `b/doc-1`) and the second (A's `a/ep-2`, the ad slot `mid-60`, B's
`b/doc-2`). Its contract maps each owner's programmes to a split of its own (a third to A and two
thirds to the operator; three fifths to B and two fifths to the operator), names a between split
of halves to the two owners, and the rule preceding. The room's producer cues eight breaks: an out
and its in carrying a `splice_insert()` with a break duration (slots from the room's policy, two),
breaks of type 4 carrying `time_signal()`s with provider and distributor placement opportunities
stating three or four slots, one of them inside `slate-90`, an out and its in with such a section,
a `splice_insert()` carrying a placement opportunity of three slots, a provider advertisement
start (a type that states no slots), and a cue of form 0. No cue covers `mid-60`, which is a
scheduled break, unslotted. The ledger document bills three viewers' receipts for every break,
two impressions each; the signed statements are the operator's, of the same day.
The accepted vectors:
- `owner_a_day`, `owner_b_day`, `operator_day`: the day's reports, each signed by the party it is
for;
- `owner_a_runs_alone`: A's day from the runs alone, both ad slots scheduled;
- `owner_b_two_rooms`: B's day under a contract naming a second room, whose break overlaps none;
- `check_owner_b_under_reported`: B's platform reports twelve impressions for `b/doc-1` and two for
`b/doc-2`, which holds as many slots: `b/doc-2` is `below` the day's rate, and the day is below
the signed statement's twenty-four impressions and B's signed part;
- `check_owner_a_csv`: A's reported statement in CSV, per day, as the signed statement states it:
nothing flagged;
- `check_owner_b_without_statement`, `check_owner_b_reports_a_programme`: B's report alone beside
the same figures, and beside figures listing A's episode, which is `unproved` (no break of B's
aired in it).
Every other vector is refused, a control of one defect: each reason of §13, each code it reuses,
and a refusal at a contract, a run, a room and a signed statement, at its place.
**Provenance.** Generated here: `wai_opportunity_vectors gen` writes `vectors.json` from fixed
seeds (the operator, the owners, the channel signer, the auditor, the buyer, and the room's
authority, clock, producer and decider). Nothing here was fetched from outside the repository.
Regenerate and check:
cd wai/wai-rs
cargo run -q --no-default-features --features opportunity_report --bin wai_opportunity_vectors -- gen ../live-conformance/opportunity
cargo run -q --no-default-features --features opportunity_report --bin wai_opportunity_vectors -- verify ../live-conformance/opportunity
cargo test -q --no-default-features --features opportunity_report --test opportunity_report
python3 -I ../live-conformance/opportunity_report_verify.py ../live-conformance/opportunity
The second implementation, `opportunity_report_verify.py`, shares no code with `wai-rs`. It reads
every report, check, section and reported statement itself, verifies contracts, runs and signed
statements with `revenue_share_verify.py` and rooms with `live_ads_verify.py`, recomputes every
break, attribution, line, citation and flag, requires every mutated copy of the corpus to fail, and
requires the corpus to catch it with each of its own checks dropped.