open-standards/wai/extensions/timeliness.md
Transaction Science 793ed1f2dc
All checks were successful
wai-app and Create / wai-app · does this change touch it (pull_request) Successful in 7s
wai-audit collector and player integration / does this change touch it (pull_request) Successful in 10s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 12s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (pull_request) Successful in 14s
WAI operation catalogue / does this change touch it (pull_request) Successful in 13s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 13s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 14s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 7s
WAI HTTP delivery / WAI HTTP · does this change touch it (pull_request) Successful in 6s
wai-fleet service / does this change touch it (pull_request) Successful in 14s
WAI neural sink gates / does this change touch it (pull_request) Successful in 13s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 12s
wai-quantum for JavaScript / does this change touch it (pull_request) Successful in 9s
wai-ledger service / does this change touch it (pull_request) Successful in 14s
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Successful in 14s
wai-key-proxy / does this change touch it (pull_request) Successful in 16s
WAI conformance / does this change touch it (pull_request) Successful in 31s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 32s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 6s
WAI energy receipts / does this change touch it (pull_request) Successful in 33s
wai-sink-android native sink library / does this change touch it (pull_request) Successful in 8s
wai-sink-swift native sink package / does this change touch it (pull_request) Successful in 7s
WAI Studio / does this change touch it (pull_request) Successful in 8s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 9s
wai-web wasm32 / does this change touch it (pull_request) Successful in 25s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 5s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (pull_request) Successful in 55s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 1m11s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 1m58s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 1m22s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m51s
wai-audit collector and player integration / collector · linux (pull_request) Successful in 1m32s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 2m31s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m51s
WAI neural sink gates / the exact JPEG-AI decoder reports its path (pinned inputs, required) (pull_request) Successful in 2m2s
WAI conformance / fast integer kernels, every x86_64 kernel set (AVX-512 silicon) (pull_request) Successful in 3m36s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 4m32s
wai-fleet service / service · linux (pull_request) Successful in 2m42s
wai-key-proxy / proxy · linux (pull_request) Successful in 57s
wai-pack / wai-pack · linux (pull_request) Successful in 3m19s
WAI conformance / faces from keypoints under wasm32-wasip2 (wasmtime) (pull_request) Successful in 1m30s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 27s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 5m59s
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Successful in 4m11s
WAI operation catalogue / the catalogue and every door · linux (pull_request) Successful in 5m56s
wai-ledger service / service · linux (pull_request) Successful in 1m50s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Successful in 7m18s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 1m7s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 3m48s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 7m43s
wai-quantum for JavaScript / javascript · linux (pull_request) Successful in 3m41s
wai-fleet service / service · macos (pull_request) Successful in 48s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 3m39s
wai-quantum studio and desktop / desktop app · linux (pull_request) Successful in 4m54s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 3m2s
wai-pack / wai-pack · macos (pull_request) Successful in 3m27s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 5m55s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 13m52s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 5m28s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 16m34s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 11m38s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 27s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m7s
wai-ledger service / service · macos (pull_request) Successful in 1m6s
wai-quantum studio and desktop / desktop app · windows (pull_request) Successful in 9m35s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 10m56s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 17m20s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 18m48s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 24m50s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 18m38s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m31s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 7m3s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m46s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 8m4s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m47s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 17m16s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m47s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 34m23s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 21s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 16s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m5s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 18s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 37m20s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 10m52s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 18m17s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 11m18s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 39m59s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 15s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 40m12s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 50s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 2m42s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 3m47s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 17m30s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 18m34s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 14m28s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 14m15s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 30m4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h18m5s
wai/one-way-delivery, converted to the layout of the fix: no shared append point
The change of wai/one-way-delivery (f1258784d..987625394, 28 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.

- 25240c4f0 wai: timeliness — when each object of a group is of use, and whether each holder held it in time
- c84992362 wai: timeliness_verify.py — the timeliness corpus's second implementation
- 44036fcdc wai: timeliness in the registry, SPEC §5, the changelog and CI; http_receipts.py checks its claims
- 27ce6754c wai: claim_verify.py lists not-held-by-deadline, and the claim corpus holds a session that switches for it
- 73d8d8eb9 wai: timeliness corpus — each holder's own line in key order, a holder's earliest fallback, and §7.2–§7.3's unreached plan rules
- 64c735f0c wai: the files timeliness changes are clippy-clean — a let chain, and the fetch callback's type allowed
- b72dc36bf wai: rung price — what delivering a rung costs, by bearer and direction, and which option a comparer takes
- 4e905e213 wai: rung_price_verify.py — the rung price corpus's second implementation
- 711fa6126 wai: rung price in the registry, SPEC §5, the changelog and CI
- 8ab70654e wai: rung price corpus — a refusal for every form rule 1 and §6.1 set, and the neighbour order a plan gives
- 1bc465959 wai: rung price ranks energy by checked evidence — a class counts only on the seller's own per-hop records, current and under a confirmed key
- 9e97997d9 wai: rung_price — the evidence text bound at its exact sizes, and a key confirmed for another class confirming nothing
- 8f1168683 wai: rung price corpus — a key confirmed for another class, the uncertainty product, each edge and order of the evidence verdict, and the evidence a plan read
- 7330e26ff wai: rung price — §6.1 links jwp-receipts at its first mention, and §10 says a record's age is its room's word
- 12c099457 wai: cache authority — who served what a node holds, and on whose authority
- f8f5d3e09 wai: cache_authority_verify.py — the cache authority corpus's second implementation
- 354146619 wai: cache authority in the registry, SPEC §5, the changelog and CI; its corpus holds what §12 states
- 55c7f3031 wai: timeliness §6 reads holdings records alone; cache-authority §9 derives the lines that read every kind
- b8fc6f02b wai: cache authority's lines read records as timeliness does, its deadline claim meets the envelopes held, and its corpus fixes each order and instant
- 91c5291cf wai: the files cache authority changes are clippy-clean — a boxed envelope, the base's names named once, slices borrowed
- 8e479daff wai: a held envelope boxes both its forms, so neither outweighs the other
- 3ec8da807 wai: impression aggregates — ad presentations counted over a bearer with no return path
- 0433a35c3 wai: impression_aggregate_verify.py — the impression aggregates corpus's second implementation
- 7d8e150e4 wai: impression aggregates in the registry, SPEC §5, the changelog and CI; its corpus states each receipt whole and a control for every malformed file
- d5e8ace02 wai: impression aggregates' size bounds are checked at their edge, and §4.3's decides no outcome
- 4bc8e13bd wai: impression aggregates' table totals are exact, and a receipt given twice is checked when either occurrence was
- 3c9f20524 wai: key_log's two result enums keep their public form, and say so to clippy
- 987625394 wai: Item::with_authority and Count::instance_received build only with the feature that calls each

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-05 01:45:32 -05:00

40 KiB
Raw Permalink Blame History

WAI Extension: Timeliness

Status: Draft. Registers the record wai.delivery.timeliness: a publisher's signed statement, for each object of a group, of when the object is of use: the instant it is useful from, the deadline by which a receiver must hold it for its full value, how that value falls after the deadline, as a stated function in integers, and the rendition a receiver presents in its place when it does not hold it by the deadline. It is a jwp-receipts claim of class timeliness (jwp-receipts §2.4.17, §4 here), signed by the group's key beside the group receipt, one statement for every bearer. From it and from a holder's signed holdings record, the signed evidence WAI has that a party held an object at an instant, a verifier judges each object for each holder: on time, replaced by its fallback, held only after its deadline and at what value at least, or not shown (§6). An asker plans, from an instant it states, which of its sources, in its own order, delivers each object by its deadline: a pass of a carousel, a neighbour, or the origin (§7). WAI defines no transport: the deadline is mapped onto the delivery timeouts, request keys, carousel and window parameters and bundle lifetimes the bearers already define (§8). The reference implementation is the timeliness module of wai-rs (feature timeliness), with the class's body in claim_receipt::timeliness; the corpus is live-conformance/timeliness/, and its second implementation is live-conformance/timeliness_verify.py. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

Texts read for this revision: draft-ietf-moq-transport-23 (MOQT; the clauses cited here, §5.1, §5.2 and §10.1 to §10.4, have the same numbers and meaning in -22, which moq-streaming-format binds), CTA-5004-B (CMCD), RFC 9218, RFC 9171 (BPv7), RFC 6726 (FLUTE), ETSI TS 103 769 V1.2.1 (DVB multicast ABR), ATSC A/331:2026-04, and 3GPP TS 26.346 §11.2A.1.1 as a mirror of Release 19 gives it. Read and not bound (§8.1): draft-sharma-moq-end-to-end-delivery-timeout-00 and draft-frindell-moq-timestamp-00. A clause number of one of them in this text is that text's.

1. Scope

In scope: the timeliness claim (§4); an object's value at an instant, and the rule by which a sink that does not hold it by its deadline is graded (§5); judging, from holdings records, whether each object was held by its deadline (§6); planning which source delivers it by its deadline (§7); and the values a carriage derives from it (§8).

Out of scope: a transport; how a sink in fact presents, which is its own and is recorded in its reconstruct-session claim (jwp-receipts §2.4.12), but for the switch reason of §8.6; who may sign as a holder, and whose word a relying party counts; counting holders, receivers, regions or rates of missing; and prices. A value here is a fraction of the object's full value to its publisher. It is not money, and no tariff grades a charge by it: a tariff prices the quantities that records state (receipt-ledger §4). This text states no energy.

A layer of a stage set (staged-delivery §3) has no entry here and is no fallback: whether a layer is late is decided by staged-delivery §8 alone (moq-streaming-format §4.1), and a layer is not presented on its own (http-delivery §2). §4.3 step 6 refuses both.

Relationship to the core spec: wai.delivery.timeliness is a record (SPEC §5). It names no payload format and is not dispatchable.

2. Terms

  • Group, link hash, leaf count, content hash: as jwp-receipts §2.1, §2.4.1 and §3 step 3. Object i of a group is its object at position i, from 0.
  • Instant: a count of milliseconds since 1970-01-01T00:00:00Z, leap seconds not counted, as channel-lineup §2 writes one. Last instant: 253,402,300,799,999 (9999-12-31T23:59:59.999Z), as carousel §4.2 bounds a pass.
  • Value: an integer from 0 to 1,000,000, parts per million of an object's full value.
  • Entry, primary: an entry of a timeliness claim (§4.1), and the object it names. Fallback: the object an entry names to present in the primary's place. End: §5.2.
  • Holder: a node named by its Ed25519 key that signs holdings records (holdings §2).
  • Held-at statement: a key, a group's link hash, a position and an instant: the key's signed word that it held that object no later than that instant. Its instant is the latest that word allows, in milliseconds, rounded up where the word is finer. It is before its group when the whole seconds of the time its word states, any fraction dropped, are below the seconds jwp-receipts §2.4.3 reads from the group's group_start. Such a statement states what cannot be, and is refused held_before_group. This revision derives held-at statements from holdings records (§6.2 steps 4 and 5). Another extension that derives them from other signed records states them in this form, under this rule.

3. Why a statement beside the receipt

WAI has deadlines that are relative leads (lead_ms, staged-delivery §8; a refinement's deadline_ms, packaging §3, its paragraph 3.3), timeouts that each hop restarts (moq-streaming-format §4.1), a sink's own schedule (jwp-receipts §2.4.12 deadline_us), a job's billing term (route-record §5.2), and a one-way bearer's plan of when a receiver holds an object, at an instant the relying party supplies (carousel §6.4). None is the publisher's signed statement of when an object is of use. That statement is made beside the receipt:

  • It is the publisher's, about its own group. The claim is signed by the group's key and names the group by its link hash, as a transmission claim (bearer-receipts §4) and a schedule (carousel §4) do, and it is chained and confirmed as every claim is (jwp-receipts §3.1, §7).
  • It is one statement for every bearer. An object's value to a receiver does not depend on the path that brought it. Whether a bearer can meet it is a question about that bearer, which its schedule (carousel §6.4) and an asker's plan (§7) answer.
  • It changes no byte of what it times. A group carried before this extension, or by a party that does not use it, verifies exactly as before. An object with no statement has none, and is never judged on time (§6.4).
  • It is a statement of value, not of delivery. Nothing in it says that anything was sent or received: that is the evidence §6 reads.

4. The timeliness claim (class: "timeliness")

A publisher MAY state the timeliness of objects of a group it signed in a timeliness claim. Its subject_type is receipt and its subject the group receipt's link hash (jwp-receipts §3 step 3). It is signed by the key that signed the group. A publisher MAY state the objects of a group in one claim or in several; §6.2 step 3 reads them together.

4.1 Body

member type meaning
objects array The objects stated, one entry each (below).
attests string MUST be "valued". Any string passes step 2; another value is refused at step 4.

Each entry of objects has exactly these members:

member type meaning
leaf_index integer The object's position in the group (jwp-receipts §2.2).
content_hash 32 B hex The object's content hash (jwp-receipts §2.1).
from_ms integer The instant from which the object is of use. Holding it earlier is no fault and no gain.
by_ms integer The deadline: the last instant at which a receiver that first holds the object has it at its full value.
decay array 1 to 16 points, each exactly { "at_ms": integer, "value_ppm": integer }: the object's value at instants after by_ms (§5).
fallback object or null The object to present in the primary's place when the primary is not held by by_ms (§5.3): exactly { "group": 32 B hex, "leaf_index": integer, "content_hash": 32 B hex, "value_ppm": integer }, the link hash of its group receipt, its position in that group, its content hash, and the value of presenting it in the primary's place. null when there is none.

Every integer is one of jwp-receipts §2.4.3, read at §3.1 step 2 with the members of each point and of fallback, in the tables' order (field_type).

An example body (wire form has no whitespace; jwp-receipts §2.4.3):

{"attests":"valued","objects":[{"by_ms":1793664060000,
 "content_hash":"<64 hex>","decay":[{"at_ms":1793664062000,"value_ppm":600000},
 {"at_ms":1793664070000,"value_ppm":0}],"fallback":{"content_hash":"<64 hex>",
 "group":"<64 hex>","leaf_index":0,"value_ppm":400000},"from_ms":1793664000000,
 "leaf_index":0}]}

4.2 Rules

Checked at jwp-receipts §3.1 step 4, in this order:

  1. attests MUST be "valued" (timeliness_not_valued).
  2. objects has at least one entry, and its leaf_index values strictly increase (timeliness_objects_malformed).
  3. Each entry in order, the first of these to fail:
    1. its window is well formed (timeliness_window_invalid): from_ms is at most by_ms, and by_ms is below the last instant;
    2. its decay is well formed (timeliness_decay_invalid): 1 to 16 points; their at_ms strictly increase, the first above by_ms and the last at most the last instant; each value_ppm is below 1,000,000 and none above the one before it; the last is 0 and every other at least 1; and no point but the last is on the line through its neighbours: with (t0, v0) = (by_ms, 1,000,000) and the points (t1, v1) … (tn, vn), for each k from 1 to n − 1, (vk−1 − vk) · (tk+1 − tk) differs from (vk − vk+1) · (tk − tk−1), computed without overflow (the products reach 268);
    3. its fallback is well formed (timeliness_fallback_invalid): null, or a value_ppm from 1 to 1,000,000, a content_hash other than the entry's, and a position other than the entry's own (a group other than the claim's subject, or a leaf_index other than the entry's).

So a stated line has one form. by_ms is the last instant of full value, since no point after it holds full value; nothing is implied, since a hard deadline is the one point (by_ms + 1, 0); a step is a fall over one millisecond; and every point is a change of slope, since none but the last lies on the line its neighbours give. Two entries that state different lines are two statements, even where their floored values (§5.1) agree at every instant.

4.3 Against the group

Checked at jwp-receipts §3.1 step 6 against the group receipt the verifier holds, which has passed jwp-receipts §3 steps 1 and 2 and whose group_start is an RFC 3339 date-time (context_invalid otherwise; another receipt is context_mismatch); the object receipts it holds under that group, each of which has passed jwp-receipts §3 step 5; the other group receipts it holds, each having passed §3 steps 1 and 2, with the object receipts it holds under them; and the envelope bytes it holds, each known by its content hash. In order:

  1. the group's link hash is the claim's subject (timeliness_subject_mismatch);
  2. the claim's signer_pubkey is the group's (timeliness_signer_mismatch): only the publisher states the value of its own objects;
  3. every leaf_index is less than the group's leaf_count (timeliness_leaf_out_of_range);
  4. no entry is of use before the group begins (timeliness_before_group): ⌊from_ms / 1000⌋ is at least the seconds jwp-receipts §2.4.3 reads from group_start, its fraction dropped, as carousel §4.3 step 4 reads it. Nothing is of use before it exists;
  5. for each entry whose object receipt the verifier holds, the receipt's content_hash is the entry's (timeliness_content_mismatch);
  6. no entry and no fallback is a layer (timeliness_on_layer): an envelope the verifier holds whose content hash is an entry's or a fallback's is not a WAI1 envelope whose capability is refinement-only (SPEC §5, Refinement capabilities; staged-delivery §3);
  7. each fallback is where it says (timeliness_fallback_mismatch): where the verifier holds the group receipt whose link hash is the fallback's group, the fallback's leaf_index is less than that group's leaf_count; and where it holds the object receipt at that position, the receipt's content_hash is the fallback's;
  8. each fallback is a rendition of its primary (timeliness_fallback_not_derived): an envelope the verifier holds whose content hash is a fallback's is a WAI1 envelope whose manifest carries derived_from (SPEC §7.1, Derived renditions) with motif the entry's content_hash, as packaging writes on every floor object (packaging §7, its paragraph 7.2). A WAI2 envelope is refused here: it offers renditions a sink selects among (SPEC §7.1), so it names no one rendition the publisher has valued.

What the verifier does not hold is not checked: a claim checked without its group stops at step 5 and is not counted by §6; an entry whose receipt, envelope or fallback group it does not hold passes the steps that need them, and the publisher's word stands there.

4.4 Authority

Confirmed under jwp-receipts §7, a timeliness claim needs the authority timeliness, which is not pinned-only and is not delivery. An origin gives it to the keys that publish its groups, as it gives transmission and schedule.

5. Value over time

5.1 The value at an instant

An entry's value at an instant h is:

  • 1,000,000 when h is at most by_ms;
  • otherwise, with the points of decay preceded by the point (by_ms, 1,000,000), for the two consecutive points (ta, va) and (tb, vb) with ta < h ≤ tb: ⌊(va · (tb − h) + vb · (h − ta)) / (tb − ta)⌋, computed without overflow (the products reach 268);
  • 0 when h is past the last point.

The value is floored, so it is never above the line the publisher stated, and it never increases with h (§4.2 rule 3.2).

5.2 The end

An entry's end is the at_ms of its last point: the instant from which an object first held is of no value. Flooring can bring the value to 0 a little before the end; §8 derives from the end, never from an earlier zero.

5.3 The sink's rule

§6 judges, and §7 plans, for a sink that follows this rule; a sink MAY present otherwise, and its session claim records what it did. At by_ms:

  • a sink that holds the primary presents it, at full value;
  • one that does not, and holds the fallback, presents the fallback in the primary's place, at the fallback's value_ppm;
  • one that holds neither presents the primary when it holds it, at its value then (§5.1). A fallback first held after by_ms is not presented in the primary's place.

The rule needs nothing the sink does not hold at by_ms. No sink knows at its deadline when a primary it lacks will arrive, so nothing is graded by what arrived after a fallback was due.

5.4 Example

With by_ms D and points (D + 2000, 600,000) and (D + 10,000, 0): the value is 1,000,000 at D; 999,800 at D + 1; 800,000 at D + 1000; 600,000 at D + 2000; 300,000 at D + 6000; 75 at D + 9999; and 0 from D + 10,000, its end. A hard deadline is the one point (D + 1, 0): 0 from D + 1, its end.

6. Judging delivery

6.1 Inputs

The group receipts the verifier holds, in an order it chooses (the first is the one a claim about none of them is checked against, §6.2 step 2), each with the object receipts it holds under it and their envelope bytes where it holds them; the timeliness claims it holds about them, each signer's in the order of its chain; the holdings records it holds; and optionally a statement offered (§6.4). These are the verdict's inputs, and the only ones its lines and its statement read. cache-authority §9 derives lines for an entry by §6.3 from its own inputs, which add acknowledgements and the reconciliations a bearer verdict counts.

6.2 Steps

  1. The groups and their objects: each group under jwp-receipts §3 steps 1 and 2, and each of its object receipts as bearer-receipts §6.2 step 2 checks it. A group that fails refuses the verdict with that step's reason.
  2. The claims: each claim, in order, under jwp-receipts §3.1 steps 1 to 5, then step 6 by §4.3 here against the group whose link hash is its subject, or the first group when none is (so a claim about a group not given is refused timeliness_subject_mismatch). A claim of another class is context_mismatch at step 6: a schedule is a plan, which carousel §6.4 and §7 here read, and a reconciliation attests no timeliness (bearer-receipts §5.4), so this verdict reads it nowhere. Its signed instant is a held-at statement only in the lines cache-authority §9 derives, once that text's verdict counts it (cache-authority §7.2, §8.3). A claim refused at any step takes no further part.
  3. The intents: the entries of the accepted claims, by group and leaf_index. Two entries for one object that differ set aside every entry for it (timeliness_contradicted): a publisher that states two values for one object has stated neither, and a relying party holds no statement that can change under it. Entries that are the same are one. Otherwise the entry stands.
  4. The records: each holdings record as holdings §4.4 reads and verifies it. A record that reads and verifies is refused whole when, for a group given, its entry's leaf_count is not the group's (holdings_leaf_count_mismatch, holdings §5.2), or its as_of_ms is before the group begins (held_before_group): ⌊as_of_ms / 1000⌋ is below the seconds read from the group's group_start, as §4.3 step 4 reads them. A holder that states it held an object before the object existed misstates its holdings. Of one holder's other records, two with one as_of_ms and different digests set both aside (holdings_contradicted, holdings §5.3), and records with one digest are one. Every other record stands at its own as_of_ms, and at no other instant: holdings §5.1 holds a record at its as_of_ms, which is below its expires_ms (holdings §4.4 rule 2), and holdings §5.3 at that instant keeps it alone, since no later record of its holder stands yet.
  5. Held-at statements: for each record that stands and each object it holds (holdings §5.4, held): the record's holder, the object's group and position, and the record's as_of_ms. It is the holder's word that it held the object then; it says nothing of when the object arrived, but that it was no later. These are the held-at statements (§2) this verdict derives, and the only ones its lines and its statement (§6.4) read. Cache-authority §8.3 derives two more kinds, from acknowledgements and counted reconciliations, and its §9 reads all three. Step 4 refused a record dated before its group, by §2's rule.
  6. Lines, by §6.3; the statement, by §6.4.

6.3 Lines

For each intent that stands, in the order of the groups given and then of leaf_index, a verifier derives a line for each holder with a record that stands and has an entry for the intent's group or its fallback's group, in increasing order of key bytes. The lines cache-authority §9 derives by this rule also have one for each key with a held-at statement of cache-authority §8.3's kinds for an object of the group. For a holder, p is the least instant of its held-at statements for the primary, and f the least for the fallback; either may have none. Its outcome and value are the first of these that holds:

outcome when value
on_time p is at most by_ms 1,000,000
replaced f is at most by_ms the fallback's value_ppm
after_deadline p is after by_ms the primary's value at p (§5.1)
not_shown §6 only: none of the above 0
no_source §7 only: §7.3 rule 4 0

A line reports its holder, p and f (each null where none), its outcome and its value. Each instant is the latest the holder's word allows for the object's arrival, and §5.3 grades what a sink holding exactly what the evidence shows would present, so every value is the least the evidence shows. after_deadline says the holder held the object by p, not that it arrived after by_ms; not_shown says only that this evidence shows neither object held in time, nor the primary at all.

A publisher's promise to a receiver within a loss bound that hears every pass is carousel §6.4's statement with t the entry's by_ms; to one that tunes in at an instant, a plan (§7). Neither is evidence that anyone held anything, and §6 reads neither.

6.4 A statement offered

A verifier MAY be asked to judge object i of a group for a holder. The answer is the outcome and value of that holder's line; not_shown and 0 when the holder has none; and refused deadline_not_stated when no intent of that object stands (§6.2 step 3): an object with no deadline is never on time.

7. Planning

7.1 Inputs

§6.1's inputs, without a statement, and with the transmission and schedule claims the asker holds about the groups, each signer's in the order of its chain; optionally a loss bound L and an overhead h (carousel §2); an instant t at which the asker plans, or the word from_ms, under which each object is planned from its own entry's from_ms; the wanted objects, each a group's link hash and a position; and the asker's sources, in the order it prefers them, each one of:

  • a bearer instance, by its bearer_id;
  • a holder, by its key, with fetch_ms: the asker's estimate of the time from asking that holder to holding an object from it;
  • the origin, with fetch_ms.

These are checked first, in this order, and refuse the plan: L and h as carousel §6.2 checks them (loss_bound_invalid, overhead_invalid); t above the last instant (instant_invalid); and the sources (sources_invalid) when there is none, when one names a kind not listed, a bearer_id that is not an absolute URI, a key that is not 64 lowercase hexadecimal digits or a fetch_ms that is not an integer from 1 to 253 − 1 (no fetch completes in no time); when two name one bearer instance or one holder, or two are the origin; or when a bearer instance is among them and L and h are not given. An estimate is the asker's own and is never signed: a plan says what follows from it, not that it will hold.

7.2 Arrivals

§6.2 steps 1 to 4 run as there, but that step 2 also checks a transmission claim by bearer-receipts §4.3 and a schedule by carousel §4.3; then the declarations (bearer-receipts §6.2 step 4) and the schedules (carousel §6.2 step 4). A schedule that stands there stands here. For a wanted object whose intent stands, from the instant s (t, or its entry's from_ms), each source's arrival of the primary, and of the fallback where there is one, is:

  • bearer instance: where a schedule of the object's group stands on it with an entry for the object, the complete_ms of carousel §7's plan from s, at L and h, holding nothing of it; none when that is null or there is no such entry;
  • holder: s + fetch_ms where a record of that holder stands at s (holdings §5.1 to §5.3, and §6.2 step 4 here) and holds the object (holdings §5.4); none otherwise;
  • origin: s + fetch_ms.

7.3 The choice

For each wanted object, in order: refused deadline_not_stated when no intent of it stands; otherwise the first of these that holds, with the outcomes of §6.3:

  1. on_time: the first source, in the asker's order, whose arrival of the primary is at most by_ms;
  2. replaced: when the fallback's value_ppm is at least the greatest value (§5.1) of any arrival of the primary, the first source whose arrival of the fallback is at most by_ms;
  3. after_deadline: the source whose arrival of the primary has the greatest value, the first in the asker's order among equals, when that value is at least 1;
  4. no_source.

A plan reports for each object its outcome, which object (primary, fallback or null), the source by its index in the asker's list, the arrival and the value. A plan whose choice is a late primary fetches no fallback: a sink that holds the fallback by by_ms presents it (§5.3). An asker that has no path back lists no holder and no origin; one whose plan for an object is no_source has no source that reaches it with any value.

7.4 The publisher's check

Planned from from_ms over one bearer instance alone, a plan states what the publisher's schedule promises a receiver within L that starts listening when each object becomes of use: on_time for every object is the promise. after_deadline names the objects for which such a receiver is not served in time, though one that heard every pass may be (carousel §6.4, at t the entry's by_ms).

8. Mappings

Each value below is derived from an entry that stands, for an object that is not a layer (§1). A carriage derives these values and adds no field of its own. Lateness is judged only by §6, never from them. A claim travels as a receipt file on every bearer (bearer-receipts §9.1; http-delivery §8.1), listed in the receipt index of each object of its group (http-delivery §8.2); no track carries it, so a party derives these values only from a claim it holds.

8.1 MoQ (MOQT, draft-ietf-moq-transport-23)

  • Per hop. A publisher SHOULD set an object's OBJECT_DELIVERY_TIMEOUT (MOQT §5.2, §10.2, Property 0x02) to no more than its slack at publication: its end (§5.2), less the instant the publisher passes it to transport, less the publisher's estimate of the path. Set on a subgroup's first object, the property governs the subgroup and is ignored on any other object (MOQT §5.2): a publisher derives a subgroup's timeout only where every object of the subgroup has an entry that stands, at no more than the least of their slacks, and otherwise puts each such object first in a subgroup of its own, as moq-streaming-format §4.1 does for layers. A slack of 0 or less cannot be set, since 0 is no timeout (MOQT §5.2): the object cannot reach anyone with value, and a publisher MAY withhold it. On the base track of a stage set, moq-streaming-format §4.1's floor stands: no timeout is shorter than the time from the base's publication to the presentation of its last unit, and where the slack is shorter, the floor is set. The timeout runs at each hop (MOQT §5.2) and is not an end-to-end deadline.
  • Priority. Unchanged. A publisher's priorities are moq-streaming-format §4.1's and packaging §8's, in its paragraph 8.5; MOQT's default of 128 (§10.4) is never relied on. A priority orders objects within a session (MOQT §5.1.1, §5.1.2) and states no instant; the timeout carries the deadline.
  • MAX_CACHE_DURATION (MOQT §10.3) is a Track property that bounds caching, not use, and is not derived.
  • End to end: not derived. draft-sharma-moq-end-to-end-delivery-timeout-00 defines its timeout for MOQT -22 alone, measures it from the first object a publisher forwards on that publisher's own clock (§4, §5 there), and reads object timestamps whose meaning draft-frindell-moq-timestamp-00 (§5 there) does not state; a timeout derived from an end could expire an object that still has value. Both are individual drafts, and this text follows them without binding to them.

8.2 HTTP

  • Abandoning at the end. A client MAY abandon its request for an object at the object's end, on its own clock as http-delivery §10.2 runs a deadline (a clock that steps back has not passed it): past its end the object is of no value. http-delivery §10.1 admits this abandonment of a base and no other; the fetch then ends as one never answered (base_unanswered). The client fetches the fallback where its plan (§7) chooses it. Request priority (RFC 9218 §4.1, §4.2; http-delivery §10.1) is unchanged.
  • CMCD. For an object no buffer level governs (a file, a creative, a still, an application package), a sink's object.dl_ms, which delivery-telemetry §3 maps to CMCD dl (CTA-5004-B §4.3, Table 1: "Deadline from the request time until the first sample of this Segment/Object needs to be available"), is by_ms less the request's instant, 0 when that is past; for an object within a buffered timeline, the lesser of that and the buffer level. A sink that holds an object whole by by_ms has its first sample by then, so the value is never later than CMCD's own. CTA-5004-B rounds dl to the nearest 100 ms, so it can be up to 50 ms late: it is a hint, and nothing is judged from it. Nothing here sets su.
  • CMSD. Nothing is derived: CMSD's at is an observation of availability at the origin, and from_ms a statement of use. A node that discards an object at a timeout derived here counts it in science.transaction.wai-drop (delivery-telemetry §6, its paragraph 6.3).

8.3 Broadcast

  • Carousel. carousel §6.4's statement "object i is held by t", with t the entry's by_ms, is the publisher's plan against its own deadline for a receiver that hears every pass, with carousel's reasons; §7.4 is the plan for one that tunes in at from_ms.
  • DVB multicast ABR (ETSI TS 103 769 V1.2.1). A deployment that carries an object as an ancillary resource of an object carousel (§10.2.3.14.3) and states its @targetAcquisitionLatency (§10.2.3.14.0: how often it is repeated "so that they can be acquired by a Multicast gateway within the indicated target time") states no more than by_ms less from_ms: a longer target does not serve a gateway that joins at from_ms. The attribute is a repetition target, not a bound under loss; the schedule (carousel §4) is the signed plan. Objects carried as media segments (bearer-receipts §9.3) have no such attribute.
  • ATSC 3.0 (A/331:2026-04). A Distribution Window (§7.1.9, Table 7.7) is the broadcaster's schedule of when NRT files are sent, as a carousel schedule is the publisher's signed one; it is read as a plan and nothing is derived. An object that is a broadcaster application's entry package is loaded from its HELD's @validFrom (§7.1.8, Table 7.6), and its files are available when the HELD names them (§7.1.8.2): a HELD that names an object whose entry stands sets no @validFrom before that entry's by_ms.
  • MBMS (3GPP TS 26.346 §11.2A.1.1, fileSchedule). A file's delivery windows are the bearer's own schedule, read as a plan; nothing is derived.
  • FLUTE (RFC 6726): an FDT instance's Expires (§3.4.2) is the expiry of the description, not of a file, and is not derived.

8.4 Bundles (RFC 9171)

A node that creates a bundle carrying an object sets its Lifetime (§4.3.1) to the object's end less the bundle's creation time (§4.2.7), both in milliseconds, the end converted to DTN time (§4.2.6: from 2000-01-01T00:00:00Z, leap seconds not counted, so less 946,684,800,000). It does not send a bundle for an object whose end is not after the creation time, and a node whose creation time is 0, an unknown clock (§4.2.6), derives no lifetime from the entry.

8.5 WAI

  • Ads. An entry for a creative of a break states a by_ms no later than the break's splice: its cue's t on the room clock (live-ads §4.1, §4.3), as an instant ⌊(t0 + t) / 1000⌋ with t0 the room's start in microseconds since 1970-01-01T00:00:00Z (live-events §2). The policy's preload_ms is when a player may fetch the break's asset list (live-ads §3.1, §5.3, §6.2), not when a creative is of use, and nothing is derived from it.
  • Floors. A packaged piece's floor object (packaging §7, its paragraph 7.2) is its base's natural fallback.
  • Holders. No one gains by holding an object past its end: a holder MAY drop it then (holdings §1 leaves what to keep to the node), and lists it in no later record.

8.6 Presentation

A sink that presents a fallback in a primary's place under §5.3, and whose path (path, delivery-telemetry §2, its paragraph 2.2) changes with it from primary to fallback, records the switch with the reason not-held-by-deadline (delivery-telemetry §5, its paragraph 5.1; jwp-receipts §2.4.12 switches). A fallback presented on the primary's path is no switch.

9. Reasons

The codes this extension adds, each with where it is raised:

reason raised at
timeliness_not_valued §4.2 rule 1
timeliness_objects_malformed §4.2 rule 2
timeliness_window_invalid §4.2 rule 3.1
timeliness_decay_invalid §4.2 rule 3.2
timeliness_fallback_invalid §4.2 rule 3.3
timeliness_subject_mismatch §4.3 step 1
timeliness_signer_mismatch §4.3 step 2
timeliness_leaf_out_of_range §4.3 step 3
timeliness_before_group §4.3 step 4
timeliness_content_mismatch §4.3 step 5
timeliness_on_layer §4.3 step 6
timeliness_fallback_mismatch §4.3 step 7
timeliness_fallback_not_derived §4.3 step 8
timeliness_contradicted §6.2 step 3
held_before_group §6.2 step 4
deadline_not_stated §6.4, §7.3
instant_invalid §7.1
sources_invalid §7.1

A verdict or plan also raises a group's or object's codes of jwp-receipts §3.3; a claim's codes of jwp-receipts §3.1 steps 1 to 5 and those of step 6 named in §4.3, and in a plan in bearer-receipts §4.3 and carousel §4.3; a record's codes of holdings §7; and a plan loss_bound_invalid and overhead_invalid (carousel §9) at §7.1, and bearer_contradicted, bearer_not_declared (bearer-receipts §10), schedule_contradicted and schedule_on_bidirectional (carousel §9) at §7.2.

10. Conformance

live-conformance/timeliness/ holds the corpus, written from fixed seeds by wai_timeliness_vectors gen as vectors.json. It has:

  • Claims: an entry at each bound of §4.2 on both sides — a window of one instant and an inverted one, a deadline one millisecond before the last instant and at it, a decay of one, of sixteen and of seventeen points and an empty one, a point at full value, a step, a plateau and a plateau with an interior point, three points on one line and three just off it, a last point at the last instant and past it, a fallback valued at 1 and at full value — and one negative control for each rule, for the order of the rules within an entry and between entries, and for a body's members at step 2.
  • Values: §5.1 at the deadline, a millisecond after, on and between points, at and past the end, a value floored to 0 before the end, a hard deadline, and a span whose products pass 264.
  • Verdicts: holders on time, at the deadline, a millisecond after, after the end, not shown; a fallback in time, at the deadline, after it, before a late primary of lower and of higher value, and a fallback after the deadline before a late primary; a holder's earliest record counting, for the primary and for the fallback; lines from several holders on one intent, each from its own records alone and in key order where the records come in another; records contradicting each other, a record at the start of its group's second and one before it, a record misstating a leaf count and one whose signature fails; intents contradicting and repeating; a schedule given as evidence and refused; and one negative control for each step of §4.3, each beside the case that shows the step passing at its edge.
  • Plans: on time in the asker's order before an earlier source, at the deadline and a millisecond after, a neighbour when the carousel is late, a holder's record expired and not yet standing, a holder asked when only another holder's record holds the object, a fallback chosen and refused on value, chosen at a value equal to the late primary's, from the first source in the asker's order before an earlier one, and arriving at the deadline, late sources chosen by value and order, an arrival only after the end, no source on a path with no return, the origin alone, a schedule with no declaration and one on a two-way instance, every pass heard from the first, the publisher's check from from_ms passing and failing, an object with no deadline, an instant at and past the last instant, and each rule of §7.1.

A conforming verifier gives every case the outcome, the reason and everything else the corpus states. wai_timeliness_vectors verify and the test tests/timeliness.rs check that the file regenerates byte for byte, that wai-rs gives every case its outcome, that every reason of §9 and every outcome of §6.3 appears, that §9 lists exactly the reference's codes and §6.3 its outcomes, that jwp-receipts §3.1 lists the class's codes at their steps, and that delivery-telemetry §5, in its paragraph 5.1, lists the switch reason of §8.6. live-conformance/timeliness_verify.py is the second implementation, written from this text: it shares no code with wai-rs; it verifies groups and objects with the JWP corpus's second implementation (jwp-conformance/jwp_verify.py), claims through steps 1–5 with the claim corpus's (claim-conformance/claim_verify.py, whose step 4 holds §4.2), schedules and passes with the carousel corpus's (live-conformance/carousel_verify.py) and records with the holdings corpus's (live-conformance/holdings_verify.py); it writes §4.3, §5, §6 and §7 itself, reads §9 and §6.3 from this text, mutates copies of the corpus and requires every copy to fail, and drops each of its own checks in turn and requires the corpus to catch the weakened verifier.

11. Security and privacy considerations

  • A statement is its publisher's word, and binds it. Two statements of one object set both aside (§6.2 step 3), so a publisher cannot move a deadline once a deliverer holds it, and a key that signs a second statement after a miss has stated two things under one key, which is evidence of it. A relying party that agreed to a deadline keeps the claim it agreed to. A deliverer that takes on a deadline checks it first (§7.4).
  • A record is its holder's word. A holder that signs an early as_of_ms makes a false statement under its key; one earlier than its group's start is refused (§6.2 step 4). Whose word a relying party counts is its own, and nothing here scores holders.
  • Unknown is never on time. An object with no statement is refused (§6.4), never on time; nothing in an entry is implied; a value is floored; a sink is graded only by what it held at its deadline (§5.3); evidence that does not show an object held is not_shown at 0; and every value is the least the evidence shows.
  • It discloses a value, not an audience. A statement names objects and instants that a carriage already exposes through its timeouts and windows. A receiver that plans (§7) over a bearer sends nothing, and a unidirectional bearer's property that the source learns nothing of its receivers (unidirectional-delivery §2) is kept. A record used as evidence discloses what holdings §9 says it does.
  • Bounded work. An entry has at most 16 points; a value or a rule is a few 128-bit products; a verdict is linear in entries times holders, and a plan in wanted objects times sources.