An entry's fallback is an ordered ladder: null, one rung as an object, or two to eight rungs as an array in strictly falling value, no object named twice (§4.2 rule 3.4, timeliness_ladder_invalid). One rung has one form, the object, so an entry with one fallback object is a ladder of one rung and reads, judges and plans as it did; the cache-authority corpus regenerates unchanged. §5.3 states which rung applies: at by_ms the primary held, else the first rung held; holding neither, the sink has passed every rung, states `passed`, presents the primary late at its value at arrival, and at the end, having presented nothing, abandons and states `ended`. §6.3 and §7.3 take the ladder, and a plan's choice names its rung. §7.5 and timeliness::scheduler run a sink's plans against the instants it first held each object: fetch, abandon, present, passed and ended by exact steps, a function of those inputs alone. A later plan replaces the one in force wholly. plans_invalid and arrivals_invalid refuse a run's inputs. The corpus gains the group E, ladder claims, verdicts and plans, and runs, each outcome declared in the generator. timeliness_verify.py writes the ladder and the run from the text, with mutations and weakenings for both, and claim_verify.py holds rule 3.4. Co-Authored-By: Claude Opus 5.5 <[email protected]>
761 lines
51 KiB
Markdown
761 lines
51 KiB
Markdown
# 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 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](holdings.md) 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](carousel.md), 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/`](../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](moq-streaming-format.md) 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](receipt-ledger.md) §4). This text states no energy.
|
||
|
||
A layer of a stage set ([staged-delivery](staged-delivery.md) §3) has no entry here and is no
|
||
fallback: whether a layer is late is decided by staged-delivery §8 alone
|
||
([moq-streaming-format](moq-streaming-format.md) §4.1), and a layer is not presented on its own
|
||
([http-delivery](http-delivery.md) §2). §4.3 step 6 refuses both.
|
||
|
||
Relationship to the core spec: `wai.delivery.timeliness` is a **record** ([SPEC](../SPEC.md) §5).
|
||
It names no payload format and is not dispatchable.
|
||
|
||
## 2. Terms
|
||
|
||
- **Group**, **link hash**, **leaf count**, **content hash**: as [jwp-receipts](jwp-receipts.md)
|
||
§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](channel-lineup.md) §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**, **ladder**, **rung**: an entry's fallback is its ladder, the objects it names to
|
||
present in the primary's place, each a rung, in order of falling value (§4.1); a fallback of one
|
||
rung is that rung. **End**: §5.2.
|
||
- **Holder**: a node named by its Ed25519 key that signs holdings records
|
||
([holdings](holdings.md) §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](packaging.md) §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](route-record.md) §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, array or `null` | The 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
|
||
(*t*<sub>0</sub>, *v*<sub>0</sub>) = (`by_ms`, 1,000,000) and the points
|
||
(*t*<sub>1</sub>, *v*<sub>1</sub>) … (*t*<sub>n</sub>, *v*<sub>n</sub>), for each *k* from 1
|
||
to *n* − 1, (*v*<sub>k−1</sub> − *v*<sub>k</sub>) · (*t*<sub>k+1</sub> − *t*<sub>k</sub>)
|
||
differs from (*v*<sub>k</sub> − *v*<sub>k+1</sub>) · (*t*<sub>k</sub> − *t*<sub>k−1</sub>),
|
||
computed without overflow (the products reach 2<sup>68</sup>);
|
||
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 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](packaging.md) §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:
|
||
|
||
- 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 (*t*<sub>a</sub>, *v*<sub>a</sub>) and (*t*<sub>b</sub>, *v*<sub>b</sub>) with
|
||
*t*<sub>a</sub> < *h* ≤ *t*<sub>b</sub>:
|
||
⌊(*v*<sub>a</sub> · (*t*<sub>b</sub> − *h*) + *v*<sub>b</sub> · (*h* − *t*<sub>a</sub>)) /
|
||
(*t*<sub>b</sub> − *t*<sub>a</sub>)⌋, computed without overflow (the products reach
|
||
2<sup>68</sup>);
|
||
- 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 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 sink that holds the primary presents it, at full value;
|
||
- one that does not, and holds a rung, presents in the primary's place the first rung of the
|
||
ladder that it holds, at that rung's `value_ppm`: the highest valued it holds (§4.2 rule 3.4). A
|
||
lower rung it also holds is not presented;
|
||
- one that holds neither the primary nor any rung has **passed** every rung, and states so at
|
||
`by_ms` (`passed`, §7.5). No rung is presented in the primary's place from then on. It presents
|
||
the primary when it first holds it, at its value then (§5.1), where that value is at least 1. At
|
||
the primary's end (§5.2), where it has presented nothing, it abandons any request for the
|
||
primary (§8.2) and states that the object ended unpresented (`ended`, §7.5). Its line is
|
||
`after_deadline` or `not_shown` (§6.3), and it records no switch (§8.6).
|
||
|
||
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](cache-authority.md) §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 *f*<sub>k</sub> the least for rung *k* of the ladder; any 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` | some *f*<sub>k</sub> is at most `by_ms` | the `value_ppm` of the first such rung in the ladder's order |
|
||
| `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: *f* is
|
||
*f*<sub>0</sub> for a ladder of one rung, and for a ladder of two or more the list of every
|
||
*f*<sub>k</sub>, 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; 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 2<sup>53</sup> − 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 each rung of the ladder, 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`: 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, 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
|
||
|
||
§7.1's groups, claims and records, and *L* and *h* where given, shared by every plan of the run;
|
||
the run's **plans**, in order, each an instant *t* with sources and wanted objects as §7.1 gives
|
||
them; and 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. An arrival is the sink's own observation of
|
||
whatever reached it: an object it fetched, or one a bearer it listens to brought.
|
||
|
||
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; or one
|
||
wants an object twice;
|
||
2. each plan in order, by §7.1, refused with its reason;
|
||
3. the arrivals (`arrivals_invalid`): an instant is above the last instant; the instants, in the
|
||
order given, decrease; or two arrivals name one object, since an arrival is the first holding.
|
||
|
||
Each plan is then derived by §7.2 and §7.3 from the shared inputs with its own *t*, sources and
|
||
wanted objects; a group 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.
|
||
|
||
#### 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.
|
||
|
||
## 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](bearer-receipts.md)
|
||
§9.1; [http-delivery](http-delivery.md) §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 rung its plan (§7) chooses, where it chooses one. 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](live-ads.md) §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](live-events.md) §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 rung in a primary's place under §5.3, and whose path (`path`,
|
||
[delivery-telemetry](delivery-telemetry.md) §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:
|
||
|
||
| 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_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 |
|
||
| `plans_invalid` | §7.5.1 |
|
||
| `arrivals_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` and `schedule_on_bidirectional` (carousel §9) at
|
||
§7.2. A run raises a plan's codes at §7.5.1.
|
||
|
||
## 10. Conformance
|
||
|
||
[`live-conformance/timeliness/`](../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, a ladder of two and of
|
||
eight rungs and one of nine, of one rung written as an array and an empty one, rungs a part per
|
||
million apart, equal and rising — and one negative control for each rule, for each rung, for
|
||
the order of the rules within an entry and between entries, and for a body's and a rung'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
|
||
2<sup>64</sup>.
|
||
- **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. With a ladder: the first rung held, a lower rung alone, a
|
||
lower rung in time before a higher one late, every rung late with the primary later and with no
|
||
primary, the primary on time over held rungs, a holder of a lower rung's group alone, a ladder
|
||
and a single fallback stating one object, and steps 6 to 8 refused at a rung other than the
|
||
first.
|
||
- **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. With a ladder: the first rung, both rungs in
|
||
time, a lower rung when the first is late, no rung when the late primary is worth more, the
|
||
first rung over a late primary worth less, a lower rung refused on value, the first source in
|
||
order, the primary on time over rungs, and no rung in time.
|
||
- **Runs** (§7.5): on time on the plan's own trace, over the origin and over a bearer; held at the
|
||
deadline and a millisecond after; a late object, presented at its value then; a hard deadline
|
||
missed; every rung passed, with the primary later and with none; a rung chosen and presented, a
|
||
lower rung held in its place, both rungs held, a rung at the deadline and a millisecond after
|
||
it; a primary in time over a rung chosen, and one after a rung presented; no source; an object
|
||
with no deadline; several objects in their wanted order; a plan replaced mid-run that continues
|
||
a fetch, changes its source, changes it to a rung, finds that rung held, finds no source,
|
||
re-plans after the deadline, drops an object, wants a dropped one back, finds an object already
|
||
presented or a rung already presented, and arrives at the deadline itself; a first plan after a
|
||
deadline, with the primary held before it and after it and with a rung held before it, and one
|
||
after an end; and each rule of §7.5.1, in its order.
|
||
|
||
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](unidirectional-delivery.md) §2) is kept. A record used
|
||
as evidence discloses what holdings §9 says it does.
|
||
- **Bounded work.** An entry has at most 16 points and 8 rungs; a value or a rule is a few 128-bit
|
||
products; a verdict is linear in entries times holders times rungs, a plan in wanted objects
|
||
times sources times rungs, and a run in its plans times their plans' work, with its instants
|
||
times the objects run.
|