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]>
87 lines
6.1 KiB
Markdown
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.
|