- Public `(len, stream)` shape: `Store::get` returns
`Option<(u64, Blob)>`; `Blob` (src/facade.rs) is a bounded, re-entrant
windowed reader over the new crate-internal `AnyCursor` tier dispatch
(mem materializing / local pread body families) — engine cursors
never leak onto the surface; no chunk-iterator machinery.
- Verification-on-get pinned against ADR-006: kv-tier materialized
reads whole-blob hash-check at get time (mismatch = Err(Verification),
never a further fall-through); the large tier's streaming open is
metadata + handle only (put-path verification + slice digests are its
story); `read_range` carries slice digests only, on both tiers.
- `stat` rides the trait's `size` probe (never a content load) into
`EntryMeta { len, algorithm }`; `has` is the pure existence probe;
both fall through kv -> large like every key-addressed op (ADR-012
§6.1) — consult order, not routing (never consults `tier_for`).
- Miss shapes enforced (the error module's behavioral note): both-tier
misses are Ok(None) on get/stat, false on has, Err(Missing) on
read_range; `src/error.rs` wave-2 deferral notes updated to enforced
state.
- `list` decided Vec<Key>: materialized, sorted total-order union of
both tiers (the sweep consumes the engines' enumeration directly);
malformed pool bytes are fatal `Err(KeyInvalid)`, never a silent
skip.
- `KeyInvalid` at the facade boundary: ops take opaque key bytes and
convert via `Key::from_bytes` once (`boundary_key`); engines never
see typed keys.
- Twelve read-path tests: virgin-store shapes per mode (dual-tier,
mem-only, kv-only), the `(len, stream)` windows, fall-through,
kv-first (decoy content in the large tier), both verification
postures, list union/sort/pool-fatality, and malformed-key
rejection on every op.
Task: tasks/store-read-paths.md (design points recorded in Notes for
the wave-2 review gate).
Verification: cargo test (default), cargo test --features mem, cargo
test --all-features green; cargo clippy --all-targets -- -D warnings
green in all three feature shapes; cargo fmt --check green; cargo doc
--no-deps clean beyond the pre-existing private-intra-doc-links class.
Nine tasks against the wave-1 contract surface as reviewed (no
amendments from the gate):
- engine-mem / engine-local (parallel, dependency-free): the two
engines; local owns the stage-hygiene exact-count tests and the
Drop-cancellation story the wave-1 review recorded
- store-construction: the Store type, constructor modes, size-threshold
dispatch; binds the conformance factory's Store associated type
- store-read-paths ∥ gc-protocol: read ops with the ADR-012 §6.1
fall-through rule; the ADR-005 in-process protocol (pins, liveness,
delete windows, abort-as-data, GcRefuse with the full protection set)
- store-put-paths: the two put paths behind one signature, ADR-003's
three numbered rules, pin-before-publish, Batch, kv-only rejection
- suite-column-mem → suite-column-local: the reference column, then the
dual-tier dispatch-coverage shape mirroring it
- review-wave-2: the gate (facade/dispatch/GC vs ADR-003/005/012)
Verification: dependency graph validated (all ids resolve, no cycles,
topological order clean); docs-only change.
Refs: docs/plans/implementation.md §Wave 2