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
4.1 KiB
4.1 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| store-read-paths | Store read paths — get/stat/read_range/has/list with dispatch fall-through | pending |
|
moderate | medium | component | implementation |
|
Description
Implement the facade's read-side ops on the Store type (store-api.md
§Read path, §Lifecycle), behind the dispatch seam from
store-construction. Direct delete is not here — it lands in
gc-protocol with its arbitration.
- The fall-through general rule (ADR-012 §6.1; POC #1 finding 6):
every key-addressed op consults the kv tier first, then the large
tier.
get/stat/has/read_range/listall follow it. get(key) → Option<(len, stream)>: small tier returns a bounded read; large tier streams. The per-engine cursor shapes stay hidden behind the crate-internalReadCursorthe store core drives (ADR-010 §1) — named design point: the public stream type that wraps the cursor (the facade's(len, stream)shape is uniform across tiers; the cursor is never exposed). A miss on both tiers isNone—getnever carriesError::Missing(ADR-012 §6.5 ruling 5; the error module's behavioral-enforcement note lands here).stat(key) → Option<EntryMeta>: the cheap probe riding the trait'ssizemethod — length plus algorithm, never a content load (ADR-008's size discipline). Fall-through per the general rule.read_range(key, range) → (slice, slice_digest): slice plus the out-of-band SHA-256 slice digest (ADR-006, fixed by convention — composed through the cursor'sread_rangeseam).Err(Missing)on a both-tier miss. Range reads fall through tiers exactly asgetdoes.has(key) → bool: the pure existence probe (ADR-008'shasdiscipline) — a size-probe under the fall-through rule; absent on both tiers isfalse; virgin-store reads are no-ops.list() → stream of keys: whole-pool enumeration, complete by contract. Named design point: the return shape — store-api.md says "stream of keys"; decide Vec vs stream (the sweep consumes the same enumeration crate-internally) and record it.- Verification posture on get (named design point): ADR-006's whole-blob verification vs the slice-digest-only reading — where the store core's hash-check actually fires on the read path (kv materialized reads are verifiable cheaply; large streaming reads ride per-range slice digests). Pin the reading against ADR-006's text and record it for the review gate.
KeyInvalidat the boundary: typedKeyconversion happens at the store boundary only (ADR-002/003) — malformed key bytes on any read op reject withError::KeyInvalid, never a guess; engines never see typed keys.
Acceptance Criteria
get/stat/read_range/has/listimplemented with the fall-through general rule (kv first, then large), unit-tested including the both-tier-miss shapes (NonevsErr(Missing)per op)- The public stream type decided and recorded; engine cursors never leak into the public surface
statnever fetches content (ridessize);EntryMetacarries len + algorithmread_rangereturns slice + SHA-256 slice digest per the ADR-006 convention; verification-on-get posture decided and recorded- Malformed key bytes reject with
KeyInvalidat the facade boundary on every key-addressed op cargo testgreen;cargo test --features memandcargo test --all-featuresgreen; clippy/fmt gates green
References
- docs/architecture/store-api.md (§Read path, §Lifecycle, §Error model)
- docs/architecture/backends-and-dispatch.md (§Size-threshold dispatch — get fall-through)
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §6.1/§6.5
- docs/architecture/decisions/006-verification-posture-and-transfer-encoding.md
- docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md (size discipline)
- src/backend.rs (the ReadCursor seam this drives)
Notes
To be filled by implementation agent
Summary
To be filled on completion