open-standards/wai/live-conformance/impressions/README.md
Transaction Science 61320c8641 A report an aggregator committed and was sent again is not rejected, and a reader takes one statement of no count
telemetry-aggregation §6.1's rule that `rejected` counts no report the aggregator aggregated had no
test, and impression_aggregate_verify.py did not apply it. The flight flow now sends the helper a
report it committed, and the Python flow filters as the Rust does. impression-aggregates §7.3 says
what a reader does with a statement of version 1 beside one of version 2, and the corpus adds a
receipt and a table of each.

The ledger's corpus takes these receipts, so it is regenerated by the commit after this one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-07 08:35:01 -05:00

74 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# live-conformance/impressions — ad presentations counted over a bearer with no return path
The corpus of [`extensions/impression-aggregates.md`](../../extensions/impression-aggregates.md)
§11, in one file, `vectors.json`.
**Provenance.** Generated here by `wai_impression_aggregate_vectors gen` (`wai-rs`, feature
`impression_aggregate`), from Ed25519 keys, salts, report ids, Prio3 randomness, HPKE ephemeral
seeds and token nonces and salts that are SHA-256 of a fixed label and a name; constant instants;
and manifests, records and claims written by the generator. The issuer key is RFC 9578 Appendix
A.2's first test vector, as the presentation corpora use it, and every token is signed with it by
RSASSA-PSS over a salt from a seed. The reference aggregators of `wai-rs` run every flow. No media
and no input from outside this repository.
`flight` gives the flight's first hour (`first_hour`, in `time_precision` units), its length and
its start in milliseconds. `keys` names every key by its role, in hexadecimal: the task origin's
keys `t1` and `t2` (`aggregate/task`) and `d1` (`delivery` alone), a stranger origin's `s1`, the
stitcher and a stranger stitcher, the three statement keys and a stranger's, each aggregator's and
the collector's HPKE configuration and private key, the verification keys' seed, and the issuer.
`fixtures` holds what cases name: the creatives `A`, `B` and `C`; the manifests as text (`mpd`,
`mpd_short` without the first two events, `playlist`); the pod-input records with what each is;
the catalogues `flight`, `open` and `bound` (the flight's with a hold of 3,599 s); the tasks; the
key logs (`rev0`, `rev1`, which revokes `t2` and arrives on the bearer, and `stranger`); the
anchor records (`pinned` at `rev0`, `fetched`); `receiver`, the revisions and anchors a receiver
holds; and the task files `flight`, `open` and `twin`.
- `catalogues` (§4.3) are each a catalogue's `bytes`; `outcome` is `read`, with its `digest`, its
`cells` and its `chunk` length, or `refuse` and its `reason`.
- `tasks` (§5.3) are a TaskConfiguration (`task`) and a `catalogue`; `outcome` is `accept`, with the
`task_id` and the `retention_s`, or `refuse`.
- `task_files` (§5.4) are a file's `bytes`, the `revisions` and the `anchors` held, by fixture name;
`outcome` is `accept`, with the file's `digest`, the `task_id` and the `confirmation` as
jwp-receipts §7.4 reports it, or `refuse`.
- `contributions` (§6.2) name a `task_file` and a `record`, and give the session's `claims` (the
last is the one judged), the `region`, `at_ms` and the `pool`; every manifest and creative of
`fixtures` is held, and the task file is accepted under `receiver`. `outcome` is `report`, with
the `cell`, `creative`, `column`, `quartile`, `time`, the report `id` (`fresh` without
attestation) and the pool ids `discarded`, or `no_report` with its `reason`.
- `flows` (§6–§7) are end to end: `reports` lists each report, a presentation with its `record`,
`claim`, `region`, `at_ms` and its contribution's cell, or a report written to fail with the
`error` and the WAI `reason` it meets; `steps` are, in order, each upload (the `WIU1` `file`, the
leader's `response` as DAP UploadErrors and its `errors`, and for a relay's merge its `sources`
and each source's `shares` of the response), the aggregation job (its request, response and each
report's `outcome` and `reason`), and each collection at `now_s` (`processing`, a DAP problem
type, or `completed` with every message, the `result` and the signed `receipt`). The `flight`
flow's `late` report is uploaded after its batch's collection, and its `replay` step sends the
helper again, by `id`, a report it committed: the `init_req` and the helper's `resp`, refusing it
`report_replayed`. The helper's statement does not count it (telemetry-aggregation §6.1).
- `uploads` (§6.4) are a file's `bytes`; `outcome` is `read`, with the `task_id` and the `ids`, or
`refuse`.
- `plans` (§6.5) are the `stored` reports, the instant `t_ms` and the `budget`, under the open task
file; `outcome` gives `send` (each id and its class), `defer`, `drop` and the `file`.
- `settles` (§6.6) are the file `sent` and the `response`; `outcome` gives whether it `settles`,
and the ids to `delete` and to `keep`.
- `receipts` (§8.1) are a `receipt`, a `catalogue` and the batch's `reports` (or `null`); `outcome`
is `accept`, with telemetry-aggregation §8.2's fields, `rejected` (the `leader`'s and the
`helper`'s, each `null` for a statement of version 1) and `reports_checked`, or `refuse` with its
`reason` and where (`at`).
- `tables` (§8.2) are a `catalogue`, a `task` and `receipts`, each with its reports or `null`;
`outcome` gives each receipt's `digest` and `verdict`, a standing one's batch, instants, count,
`rejected` and `rows`, and the `totals`, with each aggregator's `rejected` summed; or `refuse` and
its `reason`.
Everything is synthetic: keys attest nothing, the key logs are test logs, origins are reserved
example domains, and regions are ISO 3166-1's user-assigned codes and subdivisions of them. Each
case states the outcome it was written to have, declared in the generator, never copied from a
verifier. The size bounds of §5.4 and §6.4 are carried by no vector; both implementations check
each at its edge: a file of exactly the bound that reads in every other respect is read, and the
same file one byte longer is refused. §4.3's bound decides no outcome, so neither checks it.
`wai_impression_aggregate_vectors verify` and `tests/impression_aggregate.rs` check that the file
regenerates byte for byte and that `wai-rs` reaches every stated outcome; the test also checks
the equivalence the extension's §11 describes, which is not stored. `../impression_aggregate_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.