open-standards/wai/live-conformance/ledger
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 6e03ec7fa5
All checks were successful
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 38s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 34s
wai-app and Create / wai-app · does this change touch it (push) Successful in 33s
wai-audit collector and player integration / does this change touch it (push) Successful in 21s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 30s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 2m3s
wai-quantum for JavaScript / does this change touch it (push) Successful in 33s
wai-quantum studio and desktop / does this change touch it (push) Successful in 37s
WAI operation catalogue / does this change touch it (push) Successful in 1m31s
wai-fleet service / does this change touch it (push) Successful in 1m23s
wai-ledger service / does this change touch it (push) Successful in 1m6s
wai-sink-android native sink library / does this change touch it (push) Successful in 49s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 1m18s
wai-sink-swift native sink package / does this change touch it (push) Successful in 49s
WAI Studio / does this change touch it (push) Successful in 1m16s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Successful in 2m13s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 3m11s
wai-audit collector and player integration / collector · linux (push) Successful in 2m43s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m33s
wai-ledger service / service · linux (push) Successful in 2m56s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m54s
wai-quantum for JavaScript / javascript · linux (push) Successful in 3m55s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 1m8s
wai-quantum studio and desktop / studio · browser (push) Successful in 4m57s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 6m58s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 5m6s
wai-fleet service / service · linux (push) Successful in 3m28s
wai-ledger service / service · macos (push) Successful in 1m7s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 3m44s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 7m38s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 9m55s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 8m36s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 5m22s
wai-fleet service / service · macos (push) Successful in 35s
WAI Studio / Studio in WebKit · linux (push) Successful in 12m20s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 17m53s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 19m20s
joule-moq-room room service / joule-moq-room, every target (push) Successful in 18m38s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 11m20s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 10m2s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 14m27s
Tariff version 8 bills storage held over time by byte-days, each record's byte-seconds recomputed from the holder's signed snapshots
WAI's receipt ledger had no source for storage that is not a package:
a stream's DVR window, whose objects change with every segment admitted
and evicted, and a clip cut from it and kept. waiTransport meters both
(wai-additions §38) and cannot bill them. Version 8 is that source.

- A snapshot, WLS1: what one stored set lists at one instant, signed by
  its holder when the listing changes: its objects, their bytes, and the
  digest of its listing (each object by SHA-256 and length).
- A storage record, WLH1: the bytes the set held over an interval, in
  byte-seconds, naming its snapshots by digest.
- The rule: the snapshots cover the interval (the first at its start,
  each after the one before, none at or past its end), and the record's
  byte-seconds are floor(sum bytes x (next instant - instant) / 10^6).
  Any other figure is storage_mismatch; snapshots that do not cover it,
  outside_interval; snapshots not the record's, snapshot_mismatch; a
  record or snapshot breaking its rules, storage_invalid.
- A tariff of version 8 adds `storage` (per 10^9 byte-days) and a holder
  in its scope (kind 9). One line per holder in byte_days, rounded down
  once per line, citing records (kind 26) and snapshots (kind 27), each
  billed once in a chain. A record lies in the period that holds its
  interval: overlapping records of one set on one invoice are
  record_overlap, and one reaching into a billed period outside_period.
  Report §8.4 states each set's byte-seconds. Versions 1 to 7 unchanged.

Why snapshots: the ledger's evidence model bills a figure of a record its
party signed, recomputed by the verifier and placed in time by the time
the record states. Snapshots are signed as the listing changes and bind
bytes to objects by content hash; the record is a pure function of them.
A package's byte-days stay billed from the chain, since its bytes do not
change while it is kept.

Gates (Framework, [email protected], Rust 1.99.1):
- cargo test --release --no-default-features --features receipt_ledger,
  revenue_share,opportunity_report,impression_aggregate: lib
  receipt_ledger:: 23 of 23 (5 new), --test receipt_ledger 15 of 15 (2
  new: version 8's figures and refusals, a changed copy of a storage day
  refused), --test revenue_share 7 of 7, --test opportunity_report 6 of
  6, lib codecs::registry 15 of 15; wai-ledger 11 of 11 (one new: the two
  storage days issued byte for byte, a set's time held once).
- wai_receipt_ledger_vectors verify: regenerates byte for byte, every
  vector its outcome.
- receipt_ledger_verify.py (python3.14 -I): every vector agrees with
  wai-rs; 352 mutated copies fail; each of its 88 checks dropped is
  caught (12 new for version 8). Both read the same vectors.json.
- Planted faults, each alone, 10 plants of the 5 faults: caught by the
  Rust tests 10 of 10 and by the Python verifier 10 of 10.
- wai registry export --check, wai ops export --check: up to date.
- wai breaking --against b3f0aeb4e: no unacknowledged break (8
  acknowledged in the change note).
- clippy -D warnings on wai-ledger: clean; the new wai-rs code clippy
  clean.
- changelog-assemble --check, check-changelog-fragment, check-tests-in-
  ci, wai-conformance-lists check, check-workflow-concurrency.sh,
  check-comparative-prose.sh, check-public-names.sh
  --maintainer-products-only, check-wai-quantum-names, check-wai-
  section-refs, check-spec-refs, check-orphan-sources.py: pass.

Not built: waiTransport's side (it still meters and does not bill).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-10 10:42:44 -05:00
..
README.md Tariff version 8 bills storage held over time by byte-days, each record's byte-seconds recomputed from the holder's signed snapshots 2026-11-10 10:42:44 -05:00
vectors.json Tariff version 8 bills storage held over time by byte-days, each record's byte-seconds recomputed from the holder's signed snapshots 2026-11-10 10:42:44 -05:00

live-conformance/ledger — the receipt ledger

The corpus of extensions/receipt-ledger.md §11, in one file, vectors.json:

  • sources: the sources the vectors bill from, by name, each a source document of §5.1;
  • vectors: verification documents (§7.1), each a tariff, an invoice, the previous invoice or null, and the names of its sources in order, with the outcome §7.3 gives it;
  • keys: the seller's, the buyers', the two delivering parties', the broadcaster's, the cache node's, the agent's, the collector's and the holder's public keys.

Ledger equivalence. For each vector, a conforming verifier given its tariff, its invoice, its previous invoice and its sources, resolved by name, reaches the outcome the vector states:

  • refuse: the reason and where, at: ["tariff"], ["tariff", "seller"] or ["tariff", "buyer"], ["invoice"], ["previous"], ["source", k] for source k, or ["source", k, …] followed by the place the source's own extension gives (live-metering §5.1, settlement §8.2, packaging §9, live-ads §9.2), for a group (§4.10) ["source", k, "group"], ["source", k, "objects", i], ["source", k, "parent"] or ["source", k, "claims", i], for a cache source also ["source", k, "declarations", i], and for an aggregated source (§4.11) ["source", k, "receipt"], ["source", k, "task"], ["source", k, "leader"] or ["source", k, "result"], and for a storage source (§4.13) ["source", k, "record"], ["source", k, "snapshots"] or ["source", k, "snapshots", i];
  • accept: the invoice's digest, its tariff, currency, start and end, the number of records, each line (its source kind, source, unit, quantity, price, amount and the records it cites, each [kind, identity]), each energy row (scope, class, figures, joules and max_ppm), the unmetered figures and coverage of each scope, the amount, and the reports of §8: ads, one per ads source, and delivery, the parties and their overlaps; in versions 7 and 8, transmission, one per group or cache source; in version 8, storage, one per storage source (§8.4).

The accepted vectors:

  • a_day: one day's invoice over a lesson room, two delivering parties (one viewer acknowledges part of one object from both, in windows that overlap; one party serves a fetch free; the other declares delivery to viewers with no key), a viewer that forwarded sealed objects and states no tariff of its own, a package, ads under a policy that requires presentation claims and under one that does not;
  • the_next_invoice: the next invoice of the chain, over a relay's session whose hop is unmetered (its room energy is partial) and a second package;
  • room_hops_of_three_classes: a room whose hops are a model, a counter and an estimate, under a tariff of its own: one row each;
  • streams_stitched_by_others: presentations of ads another party stitched, from three vectors of stitched/ (hls_stitched; form1_prefetch, whose form-1 receipt states its own quartiles and spend beside the presented ones; and squeezeback, a shared break whose sessions' own claims are not all presented), under a tariff whose ad scope is the stitchers that corpus accepts; its report is stitched-presentation §7.5's statement, unchanged;
  • jobs_routed_and_served (version 2, §4.5): a month of media jobs routed by the route corpus's router, beside a package, under a tariff of version 2 that prices wai.video.int_motion per job and per subpixel and wai.video.av1 per job: the served int_motion jobs are billed from their billed hop and their output's decode receipt (work_pixel_ops); the failover is billed at the fallback's price; the job served past its deadline and the one every allowed hop failed bill nothing; the jobs' energy is the serving hops' figures, a counter row and a model row, and the job whose serving hop was unmetered is counted unmetered (coverage partial);
  • jobs_priced_per_operation (version 3, §4.6): the same jobs under a tariff of version 3, which prices each job by its serving capability and its operation, with a decode of wai.video.int_motion beside the encodes: the encodes and the decode are billed per job and per subpixel at their own prices, and the failover at the fallback's encode price;
  • a_rerun_billed (version 3, §6.9): the next invoice of that chain bills job-0001 run again two days later, a new route record and a new hop receipt, its output the decode receipt the first invoice already lists: the work is billed once, and the output is the evidence, cited again;
  • one_output_under_two_hops (version 3): job-0001 and its re-run in one invoice: both billed, the output receipt they share cited once and its subpixels billed for each hop;
  • an_operation_the_tariff_does_not_price (version 3): a tariff that prices int_motion's encode and not its decode: the decode bills nothing, and its hop's energy is stated;
  • version_2_routes_under_version_3 (version 3, §5.1): jobs routed under the route record's version 2, its price book pricing each operation apart with measured failures and each served hop stating its outputs: an encode, a failover whose failed hop was metered, billed at the endpoint that served, a decode, a hop past the deadline and three that failed, which bill nothing, and a failover whose failed hop's figure states no class, which version 3 does not read; each output receipt is of the clip its hop states it delivered;
  • version_4_by_the_byte_and_the_work (version 4, §4.7): the lesson room's receipt of version 2 (metering/'s bytes_out_priced) billed by its bytes out beside its time, a package listed, no storage yet, and the run of package.build that made it (package_run) billed per run and per work unit of the package, its receipt cited, and those jobs at their own prices, with every hop's energy: the billed hops' in jobs, the failed and late hops' in unbilled_hops, one of them unmetered;
  • version_4_storage_held_through_a_period (version 4): the next invoice of that chain bills the package the first holds for the byte-days of its own period, and the same package made again by a new run (package_run_again), its work billed again and its receipt cited again, beside a second package listed;
  • version_5_a_decode_held_to_its_frames (version 5, §4.8): an int_motion decode (job_v5_decode) whose served hop states it delivered one animated PNG of the clip's frames, its receipt re-derived from the codestream it read and each frame's samples hashing to the receipt's frame, billed at the decode's prices beside an encode held to its codestream as in version 4. The animation is written here by png_still::encode_animation from the clip the decode reads, and each refused animation is that one with one rule broken, its chunks rewritten with good CRCs.
  • route_record_3_outputs_proved_among_what_was_delivered (route-record §3.4, §6.1; §5.1 here): jobs routed here under the route record's version 3, whose served hops state what they delivered by its count and root, each output giving its inclusion proof: an encode (job_v3r_encode) whose clip is the second of two objects, a decode of version 5 (job_v3r_decode) whose animation is its one object, and a package's run (package_run_v3r) whose receipt is the first of 1,501 objects, the rest standing for the package's own; billed under the tariff of version 5.
  • version_6_a_third_partys_usage_per_endpoint (version 6, §4.9): a third party's jobs, each third_party record naming what the provider bills, billed per job and by that usage at its endpoint's price: gen.alpha (job_tp_alpha), gen.beta (job_tp_beta), a failover whose failed hop's billed usage reaches no line (job_tp_failover), a job given no record, billed by the job alone (job_tp_unrecorded), one in another unit at that unit's price (job_tp_images), and one in a unit no price names (job_tp_a_unit_no_price_names).
  • version_6_holds_what_version_5_holds: the encode, decode and package run of version 5's route records of version 3, at prices of any endpoint.
  • version_6_an_upscale_and_a_tone_mapping: an upscale of two pictures (job_upscale) and two tone mappings, one of whose records states two pictures of one rendering (job_tonemap_two_pictures_of_one_rendering), each re-derived from what it read; and version_6_an_upscale_run_again, the next invoice, billing the upscale's new hop and citing its records again.
  • version_6_re_derived_jobs_under_a_list: an upscale and a tone mapping whose route records are of version 2, so that no output gives a proof.
  • version_7_week_1 to version_7_week_4 (version 7, §4.10): a month of a broadcaster's transmissions, four invoices chained a week apart over October 2026, under a tariff that prices multicast octets at two ceilings and pass time at one, and broadcast octets at one ceiling and pass time at two. Week 1 (group_week_1): a group of four objects simulcast on a broadcast and a multicast instance, its envelopes held, each entry billed at the price of its class whose ceiling is the least at or above its pass rate, each declaration's energy in its class's row. Week 2: a faster broadcast (group_week_2), one entry above the ceiling of the class's octets, which bills its pass time alone, and the first week's group sent again on a new instance (group_week_1_again), its group receipt listed again. Week 3 (group_week_3): a multicast entry above every ceiling of its class, billing nothing and reported with no price, and a declaration with no figure. Week 4 (group_week_4): a broadcast and a relay chain declared and scheduled nowhere, which bills nothing. Each week's group names the claim of the broadcaster's chain its first claim follows (parent).
  • version_7_week_5 (version 7, §4.10 to §4.12): the invoice after the month, in the first week of November. A broadcast whose schedule a later one extends (group_week_5), billed in the last schedule's passes alone; a node's own multicast instance of that group (cache_week_5), its plan naming three objects and its claim saying it sent two, with its settlement declaration; the counts of the flight's two receipts (aggregated_r0, aggregated_r12), each from the impressions corpus, on one line of the collector's; and an agent's two chained consumption claims (consumption_week_5) of three objects and two.
  • version_7_one_group_on_two_instances (§5.2): group_week_1 and group_week_1_again on one invoice of the two weeks, two sources of one group, its receipt the head of neither.
  • version_7_two_groups_on_one_service (§5.2): group_week_5 and group_1_on_the_service_of_group_5, two groups on one broadcast service, an instance of a group being that group's.
  • version_7_aggregated_its_batch_is_the_period (§5.3): aggregated_r0 in the hour its batch fills, from its first instant to the end of its last.
  • version_7_aggregated_of_statements_of_version_1 (§4.11): aggregated_r0_of_version_1, whose statements state no rejected count, its count billed as any other.
  • version_7_a_node_s_unsent_entry_past_the_period (§5.3): a node's plan with an entry past the period that its claim does not say it sent, billing what the claim says it sent.
  • version_8_storage_day_1 (version 8, §4.13): a day of a holder's storage, 16 October 2026, under a tariff that prices storage at the corpus's package price per 10^9 byte-days. A stream's window (storage_window_day_1), empty at 00:00 and listing three segments from 06:00, five from a microsecond after 12:00 and four from 18:00, two evicted and one admitted, its byte-seconds rounded down; and a clip cut at 13:00 (storage_clip_day_1), three segments' copies and its playlist. One line of the holder's byte-days, citing both records and their five snapshots.
  • version_8_storage_day_2: the next day of the chain, each set's record from a snapshot at the day's start (storage_window_day_2, storage_clip_day_2), the window's listing changing at 08:00 and the clip's record ending at its deletion at 05:00.
  • version_8_storage_at_a_price_of_0: the first day under a storage price of 0, a line whose amount is 0.
  • version_8_storage_under_a_byte_day: a thumbnail of 100 bytes kept ten seconds (storage_a_moment), 1,000 byte-seconds: no line, its record and snapshot listed.
  • version_8_bills_what_version_7_bills: the window's first day beside consumption_week_5 and aggregated_r0, over one period to the end of the week after the month, each billed as version 7 bills it.

Every other vector is refused, a control of one defect: each reason of §10, the reused codes, and a refusal of each source kind by its own extension. Among them, one instance given twice over: one node's schedule in two sources (cache_twice_first, cache_twice_one_schedule), one instance of a node's or a publisher's in two sources sharing no claim (cache_twice_one_instance, group_twice_first, group_twice_one_instance), and a node naming a publisher's or another node's instance (cache_of_the_publishers_instance, cache_of_another_nodes_instance). And for version 8 (storage_*), the faults §4.13 refuses, each planted alone in the first day's records: byte-seconds over what the snapshots support (storage_window_over_its_snapshots); a record overlapping the window's day in one invoice (storage_window_overlapping) and one reaching back into the day before (storage_window_from_the_day_before); a snapshot after the interval, a first one after its start and two out of order; a clip's bytes stated as its byte-seconds; and signatures over other bytes, a snapshot's raised after it was signed, a record's, and a snapshot signed under a record's domain.

Provenance. Generated here: wai_receipt_ledger_vectors gen writes vectors.json from fixed seeds (the seller, the buyers, the two delivering parties, their viewers and objects) and from sources taken unchanged from the corpora of the extensions the ledger reads: rooms and their receipts from metering/ (lesson, mixed_classes, receipt_bad_signature, relay_recorded, bytes_out_priced), the forwarding viewer's statement and the room its hop records name from settlement/, ad rooms from ads/ (live_break, gap) and presentation/ (video_rule, ceiling_exceeded_by_presented), streams stitched by others from stitched/ (hls_stitched, form1_prefetch, squeezeback, with the manifests, responses and receipts they name, by their bytes), media jobs from routes/ (served_first_try, failover_after_a_server_error, served_after_the_deadline, served_by_an_unmetered_hop, every_allowed_survivor_failed, served_by_a_hop_whose_figure_states_no_class, a_failed_hop_billed, an_unknown_energy_ranks_last), each int_motion job's output a decode receipt sealed here over wai-rs/tests/vectors/int_video/int_video_bitstream.wiv1; the version-3 jobs (job_decode, job_rerun, job_rerun_replays_its_hop, job_claims_another_hop) routed here by that corpus's router under its price book and policy, their hop receipts sealed under its hop key, the replayed and the claimed one being served_first_try's own; the jobs of version 2 (job_v2_*) routed here by that router under the route corpus's price book of version 2, and the runs of package.build (package_run*) under a price book of version 2 of its own; the third party's jobs (job_tp_*), the upscales (job_upscale*) and the tone mappings (job_tonemap*) routed here by that router, the upscales derived under the prior generic.wsr of live-conformance/upscale/priors/ and the tone mappings' envelopes written by exact-tonemap's corpus encoder; the broadcaster's groups (group_*), their envelopes, receipts, declarations and carousel schedules, the cache node's instance (cache_*) and the agent's claims (consumption_*), and the holder's snapshots and storage records (storage_*), their segments' content hashes and lengths derived from fixed labels, written here from fixed seeds; the aggregate receipts (aggregated_*) of live-conformance/impressions/, the controls that change one's task or leader's statement signed again from a fixed seed; and the packages video-base-01 and video-staged-01 of pack-conformance/packs/. When one of those corpora is regenerated, so is this one. Nothing here was fetched from outside the repository.

Regenerate and check:

cd wai/wai-rs
cargo run -q --release --no-default-features --features receipt_ledger --bin wai_receipt_ledger_vectors -- gen ../live-conformance/ledger
cargo run -q --release --no-default-features --features receipt_ledger --bin wai_receipt_ledger_vectors -- verify ../live-conformance/ledger
cargo test -q --no-default-features --features receipt_ledger --test receipt_ledger
python3 -I ../live-conformance/receipt_ledger_verify.py ../live-conformance/ledger

The second implementation, receipt_ledger_verify.py, shares no code with wai-rs. It verifies each source with the second implementation of that source's own corpus, recomputes every line, citation, row and report, requires every mutated copy of the corpus to fail, and requires the corpus to catch it with each of its own checks dropped.