### Stage receipts: chains per key and track, objects verified by inclusion, `stage` and `delivery-gap` claims

- **One receipt chain per publisher key and track** ([jwp-receipts](extensions/jwp-receipts.md)
  §2.4.1, §3 step 3, §6.1). `group_id` and `parent_receipt_hash` run per
  (`signer_pubkey`, `track_alias`). The text disagreed with itself: the signing
  payload's comment and §6.1's last bullet said per track, §2.4.1 and §6.1's first
  bullets per key; all now say per key and track. Receipts issued with `track_alias`
  `0`, or chained per track, verify as before. Receipts a publisher chained per key
  across non-zero tracks, as the earlier §2.4.1 allowed, now fail at §3 step 3: each
  group whose parent is on another track names nothing its own chain holds
  (`parent_not_held`). A stage set carries each layer on a
  track of its own, and a subscriber verifies the tracks it subscribes to without the
  receipts of the ones it does not. A group that passes §3 steps 1–3 can head its chain
  whether or not its objects arrived, so a dropped object does not break its track's
  next link. §6.1's checks are now real in the reference verifier
  (`jwp_delivery::ReceiptChains`): the monotonic `group_id` guard per key and track
  (`group_id_not_increasing`) and the freshness bound on `group_end`
  (`group_not_fresh`), off by default for labelled groups.
- **A legacy link authenticates nothing** (§3 step 3, §6.1). The legacy payload signs
  neither `parent_receipt_hash` nor, through the link hash, anything that covers it, so
  a relay that rewrote one link — the first group's, to name the head — made the
  chain's whole history link again as new. The legacy payload does sign `group_id`, so a
  verifier now refuses a legacy group whose `group_id` does not exceed its chain head's,
  whatever its opt-in setting. A labelled replay fails its signature.
- **Forks are told from gaps** (§3 step 3). With a chain's head held, a `null` parent or a
  parent that is another group the verifier holds is `chain_break`; a parent naming
  nothing it holds is `parent_not_held`. A chain's live edge is the highest `group_id`
  of a group that verified and arrived inside the freshness window, linked or not; a
  group whose signed `group_id` is below it is history, exempt from the bound, so a
  group a relay delayed past the window no longer wedges the chain behind it, and a gap
  of any length fills in any order. Both payloads sign `group_id`, so no rewritten link
  earns the exemption. A previous group of another key or track
  is not held: a `null` parent beside one starts the chain, any other parent is
  `parent_not_held`. `group_chain_break` in `jwp-conformance/` now holds a second chain
  head; its earlier input, a parent that is not the previous group held, is
  `group_parent_not_the_previous` and is `parent_not_held`.
- **`inclusion-verified`** (§3, *Verified by inclusion*; §4.1, §4.4): an object receipt
  checked without the object's bytes — steps 1, 2, 3 and 5 — establishes that the
  publisher signed an object with that content hash at that position, and is never
  acceptance or delivery. A relay forwards the receipts of every object it does not
  forward, whatever the reason, and **MAY** say why in a `delivery-gap` claim (§4.2).
  `ObjectReceipt::verify_against(group, envelope: Option<&[u8]>)` returns
  `Evidence::{DeliveredVerified, InclusionVerified}`, which converts into staged
  delivery's `ReceiptEvidence`.
- **The `stage` class** (§2.4.10): what a party observed of a stage set, about its base —
  the stage requested, committed, delivered and presented, as points of staged
  delivery's vocabulary `urn:wai:staged-delivery:1` (registered in
  [energy-binding](extensions/energy-binding.md) §7.2; §2.4.9's vocabulary row names
  it); units by stage; the tier and stage hash of what was presented; every layer
  object with its units, bytes, status, evidence and staged-delivery §4.2 reason;
  conflicts, deadline misses and envelope bytes. Six rules at §3.1 step 4, in order:
  the points; the stage hash; the units; the objects (in order and within the set,
  except an object refused before its span was checked; evidence `delivered-verified`
  for an applied layer wherever a delivered stage is stated; bytes for every object
  that arrived and none for a dropped one, fewer in all than the set's; no layer applied
  twice to a unit; a partial object over at least two units); the units against the
  objects, per unit (an applied object of layer *s* lies within the spans of layer
  *s* − 1, a partial one meets them, and the units at stage *s* or above are no more
  than layer *s* can have reached, a partial object counting at most its span less
  one); and the delivered stage, which must be the
  one the objects give. Delivered and presented are separate measures: a set whose
  layers were all refused meets its commitment with stage 0 presented. A delivered stage
  may be stated with no commitment beside it, unlike §2.4.9's rule 3: the observer
  states what arrived. Whether a commitment was met is derived, never stated.
- **The `delivery-gap` class** (§2.4.11): a relay's statement that it did not forward
  the object at (`track_alias`, `group_id`, `object_id`) — `delivery-timeout`,
  `discretion` or `not-received` — checked at step 6 against the object receipt at
  those coordinates (`gap_subject_mismatch`).
- **Authorities** (§7.5): a `stage` claim needs `stage`, a `delivery-gap` claim
  `delivery-gap`; neither is pinned-only, and `delivery` grants neither.
- **staged-delivery §10** is split: §10.1 attestation of layers, which now names
  `delivered-verified` and `inclusion-verified` and the per-track chains, and §10.2
  claims. `staged::claim::StageObserver` states a sink's `stage` claim from what it
  observed: the layers that arrived, with the layer and span their own `refines`
  states, those known only by their receipts, and every report the sink gave, the
  latest deciding. Every event carries the sink's epoch for the base
  (`StageSink::base_epoch`, which counts the times the sink has forgotten it): a later
  epoch starts the observation over, keeping only the envelopes the sink still holds for
  the base, and a claim never spans two epochs. Every case of `staged-conformance/` is replayed through a
  sink and its observers, and each claim seals and states what the sink did. [http-delivery](extensions/http-delivery.md) §10.5 says what an
  abandoned refinement is: `inclusion-verified`, and `dropped` or `late` in a `stage`
  claim; [staged-measurement](extensions/staged-measurement.md) §10.2 says the same of
  an object its simulator drops.
- **Corpora.** `jwp-conformance/` gains the `chain` procedure — vector
  `v6_per_track_chain` (§5.9) and its neighbours: interleaved tracks, a track joined
  mid-chain, a link across tracks, forks, the guard and the freshness bound — and the
  `inclusion` procedure. `claim-conformance/` gains both classes (§5.10), every reason
  they add, and a context for a gap's object receipt; `signer-conformance/` gains the
  authorities they need. `jwp_verify.py`, `claim_verify.py` and `signer_verify.py`
  report every new outcome; `differential.py` generates `stage` bodies around every
  rule and gaps against receipts at and away from their coordinates, and
  `chain_differential.py` signs chains around §3 step 3 and §6.1 for both verifiers.
  Every vector already in the claim and key-discovery corpora is unchanged, and the
  claim corpus pins the ones before the new classes by a digest computed before they
  were added. In `jwp-conformance/`, `group_chain_break` alone changes, as the item on
  forks and gaps says.
- No receipt or claim byte of existing material changes; one existing vector,
  `group_chain_break`, is given a genuine chain break, as above.

