- A layer's WIR1 payload is parsed once, at §4.1 step 6. Wir1 keeps its tables
flat and its streams as end offsets beside the payload, so a parse holds its
declared working bytes (which now count 8 bytes per unit for the stream
index), and a unit's output is allocated at its exact size.
- Step 7 compares a unit's key with the producers of its stages (a unit's stage
rises by one per application) and a batch is grouped by unit; held units are
kept per unit and counted per layer; prev's runs are indexed once and
bisected. An offer's work and memory grow linearly with the layer's units
(tests/staged_resources.rs, a counting allocator, in both CI profiles).
- The chain budget (§4.5; chain-over-limit at step 6, before any stream is
decoded) bounds the units' output, 32 bytes per stage, and every retained
layer's payload, declared output and declared working bytes. A layer no unit
is held for is dropped at the end of the offer, release or expiry.
- Decoding again a base the sink holds keeps its chain and reports nothing;
StageSink::remove_base drops a chain.
- Shape products are checked: one past u64 is geometry-mismatch.
- A layer whose manifest names a fallback is refused at step 1.
- A layer refused when its base arrives has one report.
- BaseInfo::first_unit places a base's units on the clock a set split across
bases shares.
- A layer held for its base and offered again with stronger receipt evidence
keeps it; over an attested base it counts as arrived when its receipt was
verified.
- A payload whose unit count is not the span's is payload-malformed with the
code field_range; A.6 states how step 6 and step 9 split A.4.
- span: null is absent; SPEC §2 states what a JSON integer is.
- base_never_waits plays random arrival traces through a live StageSink.
The corpus is regenerated through its generator (the config's budget, each
base's first_unit); every case keeps its outcome.
Co-Authored-By: Claude Opus 5.5 <[email protected]>