### Staged delivery: refinement layers, base admission, and WAI2 refinement components

- **The extension** [staged-delivery](extensions/staged-delivery.md): a stage set is a
  base and layers, each layer its own `WAI1` envelope naming, by content hash, the
  base and the producer each unit it covers is expected to have (`refines`: `base`,
  `prev` as one producer or runs, `layer`, `span`). A sink holds per unit a stage, a
  producer and a tier, and applies a layer per unit by one algorithm with a closed
  list of reasons (§4.1, §4.2): every envelope-scoped step (well-formed `refines`, a
  refinement capability with no fallback, the base present, not through a fallback,
  admitted, attested, a well-formed payload within the sink's cost limit and its chain
  budget) before the unit steps (conflict, readiness, geometry, deadline). Layers a unit is not ready for are held
  to a declared bound and released when its stage advances; layers released together
  form a batch, so two conflicting layers released together are both refused and the
  unit frozen, whatever their order. A layer that differs from one that already passed
  for the same unit freezes it at its stage. A unit's tier is the weakest of its base
  and layers, `entropy-consistency` does not pass through a layer, and a stage hash is
  stated only at `decode-equivalence`. Deferral, live deadlines (a sink never delays a
  unit for a layer, and counts the units presented below the stage their layers would
  have reached on time), attestation (a receipt verified without the layer's bytes
  never authorizes an application) and byte counting (envelope bytes; receipts,
  framing and parameter sets separately; never JSON or base64) are stated.
- **Resource bounds** (§4.5, §14, A.5): a sink declares a chain budget per base, over
  its units' output, 32 bytes per stage, and the payload and declared working bytes of
  every layer it retains with one unit's output and 32 bytes for each unit it covers
  and has not been applied to; a layer that would pass it is refused
  (`chain-over-limit`) before any stream is decoded, and a layer no unit is held for is
  dropped. The declared working bytes count the stream index. A sink's work per layer
  is linear in its payload and declared symbols up to a logarithmic factor in its
  units, and §14 states how. A sink that drops a base's chain discards the layers held
  for it (`base-absent`) and keeps each unit's record that is not empty (its
  producers, a pending producer, its frozen flag), within a declared record budget
  whose oldest bases are forgotten first; the base decoded again advances only along
  that record, and a frozen unit replays only its own record, in order.
  Decoding a base again keeps its chain, and a receipt verified for the base, before or
  after it was decoded, makes it attested from then on, across dropped chains; a layer held for its base and offered
  again keeps the strongest receipt evidence, and over an attested base counts as
  arriving when its receipt was verified; a set split across bases shares one live
  clock (`first_unit`).
- **The residual payload `WIR1`** (Appendix A): one rANS stream per unit;
  `clamp(pred + r·q)` with the identity, up2 (the half-pel arithmetic, odd sizes
  included) and rate (linear interpolation, `rdiv`'s halves away from zero, channels
  interleaved) predictors. It follows the integer payloads' rules: a parse in a
  stated order with the closed list of their codes, caps, a declared cost a sink reads
  before decoding, refusal at the first symbol a stream runs out on, canonical stream
  ends; and it reads no parameter set.
- **Refinement capabilities** (SPEC §5, *Refinement capabilities*):
  `wai.image.int_refine`, `wai.video.int_refine`, `wai.audio.int_refine` and
  `wai.splat.int_refine`, each refinement-only, royalty-free, `StandardDefined` and
  exact given the base it refines. SPEC §8 adds the refinement-only role; SPEC §4 never
  dispatches one, and a sink that does not implement the extension finds it
  unsupported. The registry gains the `refinement` kind and role, and the export is
  regenerated. *Envelopes this makes non-conforming* (they still parse): a `WAI1`
  carrying a refinement capability without `refines`, with a fallback, or as a
  fallback; `refines` on any other capability; a refinement capability as a `WAI2`
  rendition or companion; a companion bound to one.
- **Base admission is one table** (SPEC §5, *Base admission*;
  `codecs::BASE_ADMISSION`): the bases of each refinement and of the LCEVC enhancement
  layer, whose bases are unchanged. `enhancement_bases`, `companion_applies_to` and
  `admits` read it.
- **WAI2 refinement components** (SPEC §7.1), on the component identity (`id`,
  `sha256`, `prior`; no other digest is defined): an entry with
  `role: "refinement"` carries `refines` naming entries by `id`, follows every
  selectable entry, is never selected, and is checked by `check_component_roles` in a
  stated order. *Exploding a component* writes its `WAI1` envelope, from
  `envelope_manifest` verbatim or from the `WAI2` manifest's members as written, with
  ids replaced by the content hashes of the named entries' exploded envelopes, so a
  component and the layer carried alone are the same object; `WaiMulti::pack` packs
  `WAI1` envelopes with their manifests verbatim, and they explode back to the same
  bytes; it refuses an envelope it could not give back (bytes around a manifest's JSON
  value or after a payload, or a manifest that inside a `WAI2` passes the depth limit)
  and checks its output before returning it. Each entry explodes on its own, so one
  that cannot leaves the others intact. A refinement's `envelope_manifest` names no
  fallback. A malformed `refines` or a mismatched `envelope_manifest` does not make a
  manifest unreadable.
- **SPEC §2**: member names are unique within each object of a manifest, at any depth,
  and an integer member is written as an integer (`-0`, `1.0` and `1e0` are not); both
  readers refuse a manifest that breaks either. `span: null` is `span` absent.
- **Reference implementation**: `staged::{StageChain, StageSink, wir1, predict,
  wir1_arith, tier, schedule}` (feature `staged`); `container::{Refines, Prev}`;
  `WaiMulti::{explode, explode_each, explode_all, pack, check_envelope_manifests,
  refinements_of}`; `container::check_unique_members`; `wai stage
  refine|apply|inspect|pack|explode` (`refine --out-dims` gives a layer's shape);
  `StageSink::{remove_base, forget_base, mark_attested}`; `wai wrap` refuses a refinement
  capability, and `wai inspect` shows `refines`. `RansEncoder` writes the bypass
  escape, and `int_entropy::hist_to_cdf` builds a table from a histogram in integer
  arithmetic. In `ternary::rans_encode_trits`, the encode call sat inside
  `debug_assert!`, so a release build coded no symbol; it now runs in every build.
- **Conformance**: the corpus [staged-conformance](staged-conformance/) (image, video,
  audio and splat sets; cases for every reason of §4.2 and every `WIR1` refusal code,
  in the order the steps check them, and for §3's rules, holds and their bound,
  batches, frozen units, the chain budget, a base decoded again, receipt evidence and
  live deadlines, one clock across bases included; `WAI2` cases for each refinement
  rule of SPEC §7.1, for exploding entry by entry and for what a packer refuses; the
  live schedule), written and verified by `wai_staged_vectors` and verified
  independently by `staged_verify.py`, which shares no code with `wai-rs`; the pure-
  Python BLAKE3 moves to `claim-conformance/_blake3.py`, shared by both Python
  verifiers. Cross-architecture goldens pin every stage of an image, a video and an
  audio set; Kani proves, over bounded windows, the arithmetic step, the up2 bounds,
  `rdiv` and the rate indices. `rdiv` and the rate indices are computed in checked
  64-bit arithmetic.

