Skip to main content

WAI Extension: Timeliness

Mirrored from the canonical text at commit 260cbd09 ().

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 renditions a receiver presents in its place when it does not hold it by the deadline, a ladder in order of falling value. 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 a rung of 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); and a sink runs plans against its own clock, deciding what it fetches, presents and states, and when (§7.5). 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 and the sink’s run of a plan in timeliness::scheduler; 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, and a sink’s run of its plans against its own clock (§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

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:

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

membertypemeaning
objectsarrayThe objects stated, one entry each (below).
attestsstringMUST be "valued". Any string passes step 2; another value is refused at step 4.

Each entry of objects has exactly these members:

membertypemeaning
leaf_indexintegerThe object’s position in the group (jwp-receipts §2.2).
content_hash32 B hexThe object’s content hash (jwp-receipts §2.1).
from_msintegerThe instant from which the object is of use. Holding it earlier is no fault and no gain.
by_msintegerThe deadline: the last instant at which a receiver that first holds the object has it at its full value.
decayarray1 to 16 points, each exactly { "at_ms": integer, "value_ppm": integer }: the object’s value at instants after by_ms (§5).
fallbackobject, array or nullThe ladder: the objects to present in the primary’s place when the primary is not held by by_ms (§5.3), each a rung, 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. One rung is written as that object; two to eight as an array of them, in order of falling value_ppm (§4.2 rule 3.4). 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 each rung, in the tables’ order (field_type); an element of the array that is not an object is field_type too.

A ladder of one rung has one form, the object: an array of one is refused (§4.2 rule 3.4). So an entry with one fallback object, the form before ladders, is a ladder of one rung, read, judged and planned as it was, and two entries that state one ladder are written alike (§6.2 step 3). The rung a ladder’s position gives is its index, from 0; a ladder of one rung has rung 0.

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}]}

The same entry with a ladder of two rungs, the higher valued first:

"fallback":[{"content_hash":"<64 hex>","group":"<64 hex>","leaf_index":0,"value_ppm":700000},
 {"content_hash":"<64 hex>","group":"<64 hex>","leaf_index":0,"value_ppm":400000}]

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. each rung of its fallback is well formed (timeliness_fallback_invalid), in the ladder’s order: 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);
    4. its ladder is well formed (timeliness_ladder_invalid): where fallback is an array, it has 2 to 8 rungs, their value_ppm strictly decrease, and no two of them have one content_hash, or one group and one leaf_index.

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. A ladder states one order too: each rung is worth less than the one before it, so the first rung a sink holds is the most it can present in the primary’s place (§5.3), and no object is valued twice.

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 a run, what a plan holds of these is what §7.5.1 gives it. 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 rung is a layer (timeliness_on_layer): an envelope the verifier holds whose content hash is an entry’s or a rung’s is not a WAI1 envelope whose capability is refinement-only (SPEC §5, Refinement capabilities; staged-delivery §3);
  7. each rung is where it says (timeliness_fallback_mismatch): where the verifier holds the group receipt whose link hash is the rung’s group, the rung’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 rung’s;
  8. each rung is a rendition of its primary (timeliness_fallback_not_derived): an envelope the verifier holds whose content hash is a rung’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. Every rung of a ladder derives from the primary itself, not from the rung before it.

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 or envelope it does not hold, or a rung whose 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:

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 and runs, for a sink that follows this rule; a sink MAY present otherwise, and its session claim records what it did. At by_ms:

A rung first held after by_ms is not presented in the primary’s place, and a primary first held after a rung was presented does not replace it. 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 rung 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.

With that entry’s ladder a rung at 700,000 and a rung at 400,000: a sink that holds both at D, and not the primary, presents the first, at 700,000; one that holds only the second presents it, at 400,000; one that holds the first only from D + 1 and the second only from D + 500 has passed both at D, and presents a primary it first holds at D + 1000 at 800,000, or nothing when no primary comes before D + 10,000.

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 a rung’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 fk the least for rung k of the ladder; any may have none. Its outcome and value are the first of these that holds:

outcomewhenvalue
on_timep is at most by_ms1,000,000
replacedsome fk is at most by_msthe value_ppm of the first such rung in the ladder’s order
after_deadlinep is after by_msthe primary’s value at p (§5.1)
not_shown§6 only: none of the above0
no_source§7 only: §7.3 rule 40

A line reports its holder, p and f (each null where none), its outcome and its value: f is f0 for a ladder of one rung, and for a ladder of two or more the list of every fk, in the ladder’s order. 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 the primary nor a rung 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; optionally the asker’s symbols, what it holds of objects on bearer instances, each a bearer_id, a group’s link hash, a position and one number for each source block of the object, in the order carousel §5 divides it, as carousel §7 takes a holding; and the asker’s sources, in the order it prefers them, each one of:

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 not an integer from 0 to the last instant (instant_invalid); 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; the symbols (symbols_invalid) when they are not a list, one is not an object, its bearer_id is not an absolute URI, its group is not 64 lowercase hexadecimal digits, its index is not an integer from 0 to 253 − 1, its numbers are not a list of at least one, a number is not an integer from 0 to 253 − 1, or two state one object on one instance; and the wanted objects (wanted_invalid) when they are not a list, one is not an object, its group is not 64 lowercase hexadecimal digits, or its index is not an integer from 0 to 253 − 1. 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 each rung of the ladder, is:

A plan counts what its asker holds, as carousel §7 does, and a code and its parameters are the instance’s schedule’s, so symbols held on one instance count for that instance alone. A statement of symbols that does not fit the entry standing for its object on its instance, by carousel §7’s rule for a holding, refuses the plan (holding_invalid), whichever sources and objects the plan names; one with no such entry is compared with nothing.

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: the first rung, in the ladder’s order, whose value_ppm is at least the greatest value (§5.1) of any arrival of the primary and whose arrival from some source is at most by_ms: that rung, from the first such source in the asker’s order;
  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 rung by its index (null unless the object is fallback), 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 rung, and one whose choice is a rung fetches no other: no higher rung arrives from any source by by_ms, a lower one is worth less, and a sink that holds any rung by by_ms presents the first it holds (§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, with no symbols, 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).

7.5 Running a plan

A sink runs its plans: from them and from its own clock it decides what it fetches, what it presents in each object’s place and when, and what it states. A run is a function of its inputs alone, so a verifier given a sink’s inputs derives its decisions, and two sinks given the same inputs decide the same things at the same instants.

7.5.1 Inputs

L and h where given, shared by every plan of the run; §7.1’s groups, claims and records, with, where stated, the instant from which the sink first holds each, on its own clock (groups_at_ms, claims_at_ms, records_at_ms: a list with one entry for each, an instant or null), and each object receipt given with a group (receipts_at_ms: a list for each group, with one such entry for each of its object receipts); the run’s plans, in order, each an instant t with sources and wanted objects as §7.1 gives them; the sink’s arrivals, each a group’s link hash, a position and the instant from which the sink first holds that object, on its own clock; and, where stated, its symbols on its own clock, each §7.1’s statement with the instant from which the sink holds that many. An arrival is the sink’s own observation of whatever reached it: an object it fetched, or one a bearer it listens to brought. An instant of any other input is the same observation of what it states.

These are checked first, in this order, and refuse the run:

  1. the plans (plans_invalid): there is none; one is planned from from_ms rather than from an instant, since a sink runs from its clock; their instants do not strictly increase, one that is not an integer reading as above every other; or one wants an object twice, an entry §7.1 refuses naming none;
  2. each plan in order, by §7.1, refused with its reason;
  3. the arrivals (arrivals_invalid): an instant is not an integer from 0 to the last instant; the instants, in the order given, decrease; or two arrivals name one object, since an arrival is the first holding;
  4. the claims’ instants, where stated (claims_invalid): they are not a list with one entry for each claim; an entry is neither null nor an integer from 0 to the last instant; one claim is given twice, since the instant is the first holding; or a claim that passes jwp-receipts §3.1 steps 1 to 4 is held before it was signed: the instant’s whole seconds are below those jwp-receipts §2.4.3 reads from its issued_at, by §2’s rule for a statement before its group. A claim that fails those steps is not known to be its signer’s, so its issued_at is compared with nothing;
  5. the records’ instants, where stated (records_invalid): the same, of each record, a record that holdings §4.4 reads and verifies being held before it was stated when the instant’s whole seconds are below its as_of_ms’s;
  6. the groups’ and object receipts’ instants, where stated (groups_invalid): the same, of each group, a group that passes jwp-receipts §3 steps 1 and 2 being held before it starts when the instant’s whole seconds are below those jwp-receipts §2.4.3 reads from its group_start, and a group that fails them being compared with nothing; and receipts_at_ms is not a list with a list for each group, with one entry for each of its object receipts, each null or an integer from 0 to the last instant;
  7. the symbols, where stated (symbols_invalid): they are not a list; an instant is not an integer from 0 to the last instant; the instants, in the order given, decrease; a statement fails §7.1’s rule for one; or, of one object on one instance, a statement has the instant of the one before it, another count of source blocks, or a number below that one’s, since a sink does not unlearn a symbol.

A run compares the sink’s clock with instants others state, a deadline and a pass among them, so a clock that places a statement before its signer made it is one those comparisons cannot be read against, and the run is refused rather than read.

Each plan is then derived by §7.2 and §7.3 from L and h, its own t, sources and wanted objects, and the groups, claims and records the sink holds by its t, in the order given: those whose instant is at most t, and those with none. These are §7.1’s inputs for that plan, what its asker holds when it plans. A group a plan reads that fails refuses the run as it refuses a plan. The first plan is in force from its t, and each later one replaces the one before it at its own t, wholly: an object only an earlier plan wants is no longer run.

7.5.2 State

For each object, a group’s link hash and a position, the run keeps whether it is settled (presented, or ended), whether it has passed (§5.3), and its fetch, or none: the object it takes (the primary or a rung), its source, and the plan it serves, by that plan’s index and the source’s index in that plan’s list. A fetch is outstanding from its decision until the sink holds the object it takes, or until it is abandoned. Two sources are the same where both name one bearer instance or one holder’s key, or both are the origin, whatever their fetch_ms. The objects run are those the plan in force wants whose choice is not refused (deadline_not_stated), in its wanted order. The sink holds an object from its arrival’s instant, and holds it by that instant and any later one.

7.5.3 Decisions

The run reads, in increasing order, every instant that is a plan’s t, an arrival’s, or the by_ms or the end (§5.2) of an object a plan wants with a choice; at each, n, it takes these steps in order, each over the objects run in their wanted order. At no other instant does it decide anything.

  1. Arrivals. The sink holds from n each object that arrives at n, and a fetch of it is no longer outstanding.
  2. Plans. Where a plan’s t is n, it replaces the one in force. First, for each object run under the earlier plan that is not settled and has a fetch outstanding: abandon it, unless the new plan continues it, its choice for the object taking the same object from the same source; a fetch continued serves the new plan from then on. Then, for each object now run that is not settled and whose choice takes an object from a source: fetch it, unless the sink holds that object or the new plan continues the fetch. A choice of no_source fetches nothing.
  3. Deadlines. For each object run, neither settled nor passed, whose by_ms is at most n, by §5.3 with what the sink holds by by_ms: where it holds the primary, present it at 1,000,000; else, where it holds a rung, present the first of the ladder that it holds, at that rung’s value_ppm; else passed. A present settles the object, then abandons its fetch where one is outstanding (abandon); passed abandons its fetch where one is outstanding and takes a rung, since no rung can be presented in the primary’s place from then on.
  4. Late primaries. For each object run that has passed and is not settled, where the sink holds the primary and the primary’s value (§5.1) at its arrival’s instant is at least 1: present the primary at that value, which settles the object.
  5. Ends. For each object run that has passed and is not settled, whose end is at most n: abandon its fetch where one is outstanding, then ended, which settles the object.

A plan given after an object’s by_ms meets that object at step 3 at the plan’s own t, by what the sink held by by_ms, as §6 would grade it; one given at or after its end meets steps 3 to 5 at that instant.

Each decision reports its instant n; a plan’s index: for abandon the plan the fetch served, for every other action the plan in force; its action; the object’s group and position; for fetch and abandon, the object the fetch takes (primary or fallback, with the rung’s index or null) and its source’s index in that plan’s list; and for present, the object presented, with the rung’s index or null, and its value. A member that does not apply is null. A run reports each plan’s choices (§7.3), then its decisions in the order it takes them. A run that states instants of its groups, object receipts, claims or records also reports what each plan read: each claim’s label and each record’s as §7.2 gives them over what the plan read, and not-held for the rest. Symbols take no label: what they change is a choice’s arrival, which the plan already reports.

7.5.4 What a run states

Each decision is the sink’s own statement of its session. None is signed here, and none is graded: §6 grades from signed held-at statements alone. A carriage reports them as it reports any request: fetch is delivery-telemetry’s request, abandon its abandon (delivery-telemetry §2; §8.2 here, at the end), and present its present; a rung presented on another path is also §8.6’s switch. passed states, at by_ms, that no rung will be presented in the primary’s place; ended states, at the end, that nothing was presented for the object. Neither is a switch.

A passed stands whatever a later plan reads. One that reads a differing entry for the object finds its intent set aside (§6.2 step 3), and the object is no longer run: a fetch still outstanding is abandoned at that plan (§7.5.3 step 2), a primary that arrives after is held and not presented, and no ended follows, since an intent set aside states neither a value nor an end. The passed was true of the plan in force at by_ms, when the sink stated it.

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)

8.2 HTTP

8.3 Broadcast

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

8.6 Presentation

A sink that presents a rung 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 rung presented on the primary’s path is no switch, and neither is a primary presented after the sink passed every rung.

9. Reasons

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

reasonraised 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_ladder_invalid§4.2 rule 3.4
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
symbols_invalid§7.1, §7.5.1
wanted_invalid§7.1
plans_invalid§7.5.1
arrivals_invalid§7.5.1
claims_invalid§7.5.1
records_invalid§7.5.1
groups_invalid§7.5.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, schedule_on_bidirectional and holding_invalid (carousel §9) at §7.2. A run raises a plan’s codes at §7.5.1.

10. Conformance

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

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