docs(tasks): decompose wave 2 — mem + local engines, facade, in-process GC, first suite columns
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
This commit is contained in:
1 parent
c1d9494c11
commit
6bce301c55
10 files changed
+834
-2
No files matched your search
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: store-read-paths
|
||||
name: Store read paths — get/stat/read_range/has/list with dispatch fall-through
|
||||
status: pending
|
||||
depends_on: [store-construction]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [wave-2, facade, read-path]
|
||||
---
|
||||
|
||||
## 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`/`list` all 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-internal `ReadCursor` the 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 is
|
||||
`None` — `get` never carries `Error::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's `size` method — 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's `read_range` seam). `Err(Missing)` on a
|
||||
both-tier miss. Range reads fall through tiers exactly as `get` does.
|
||||
- **`has(key) → bool`**: the pure existence probe (ADR-008's `has`
|
||||
discipline) — a size-probe under the fall-through rule; absent on
|
||||
both tiers is `false`; 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.
|
||||
- **`KeyInvalid` at the boundary**: typed `Key` conversion happens at
|
||||
the store boundary only (ADR-002/003) — malformed key bytes on any
|
||||
read op reject with `Error::KeyInvalid`, never a guess; engines never
|
||||
see typed keys.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `get`/`stat`/`read_range`/`has`/`list` implemented with the
|
||||
fall-through general rule (kv first, then large), unit-tested
|
||||
including the both-tier-miss shapes (`None` vs `Err(Missing)` per
|
||||
op)
|
||||
- [ ] The public stream type decided and recorded; engine cursors never
|
||||
leak into the public surface
|
||||
- [ ] `stat` never fetches content (rides `size`); `EntryMeta` carries
|
||||
len + algorithm
|
||||
- [ ] `read_range` returns slice + SHA-256 slice digest per the ADR-006
|
||||
convention; verification-on-get posture decided and recorded
|
||||
- [ ] Malformed key bytes reject with `KeyInvalid` at the facade
|
||||
boundary on every key-addressed op
|
||||
- [ ] `cargo test` green; `cargo test --features mem` and `cargo test
|
||||
--all-features` green; 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
|
||||
Reference in new issue
Block a user