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:
glm-5.3-flash committed 2026-10-11 21:39:28 +00:00
1 parent c1d9494c11
commit 6bce301c55
10 files changed
+834 -2

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
---
id: store-put-paths
name: Store put seam — two internal paths, the three numbered rules, Batch, kv-only rejection
status: pending
depends_on: [gc-protocol]
scope: moderate
risk: medium
impact: component
level: implementation
tags: [wave-2, facade, write-path]
---
## Description
Implement the facade's put seam on the `Store` type (store-api.md
§Write path): **`put(len: Option<u64>, stream) → (Key, Pin)`** — two
internal paths behind one signature, with pin-before-publish from the
`gc-protocol` registry.
- **Known-length path** (encouraged, documented as such on the API):
the preamble (`"blob <len>\0"`) is known before content flows, so
the hash initializes with it and one pass suffices — no staging
needed for hashing. Routing by the dispatch seam: ≤ threshold → the
kv tier's whole-value put; > threshold → the large tier's staged put
(content streams into the staging cursor while hashing; the
derivation completes at stream end; commit-rename publishes).
- **Unknown-length path**: content buffers in memory up to the
dispatch threshold. ADR-003's **three numbered rules** (option (d)),
each a test-asserted behavior:
1. **Threshold exceeded mid-stream** (non-restartable sources are
normal): the buffered prefix flushes *into a fresh stage file*
and the stream continues appending into it — there is no
"restart the stream" requirement anywhere.
2. **Verification runs over the eventual stored artifact as a
whole**: the memory buffer for the sub-threshold kv commit; the
complete staged bytes for the large commit — the derivation pass
restarts over preamble + staged bytes (forced by the preamble
being inside the hashed input, ADR-002), reading the staged
artifact back through the `StagingCursor: ReadCursor` seam (the
wave-1 design-led extension). There is no stitched-input case
left ambiguous.
3. **Stream error before commit**: no entry lands and no stage file
remains — buffer discard on the failure path, exactly like stage
discard (the stage-hygiene invariant extends to the buffered
case).
- **Pin-before-publish** (ADR-005): the pin refcount is acquired under
the arbitration lock *before* the entry becomes visible — publish
and protection are one step; an entry cannot appear in a sweep's
`list()` without already carrying its pin.
- **Dedup**: a re-put of existing content acquires no new pool entry —
the returned `Pin` refcounts the existing one under the same lock.
- **`Batch`** (store-api.md §Write path): the batching put seam —
multi-put writes group under one batch-scoped pin; member puts
publish pin-before-publish exactly as lone puts do; the batch's pins
drop together on commit or drop (the `gc-protocol` machinery drives).
- **kv-only mode rejection** (ADR-012 §6.2): known-length puts
exceeding the threshold reject **immediately**; unknown-length puts
reject **at mid-stream threshold overflow** — lengths are not known
at construction, so put time is the only possible rejection point.
Zero residue on either rejection.
- **Named design points**: (a) the stream parameter shape (`impl
AsyncRead + Unpin + Send` vs a boxed trait object — the family's
no-dyn posture vs ergonomics); (b) the declared-len mismatch case
(a known-length stream that yields fewer/more bytes than `len` —
which error family member carries it, and zero residue either way).
Record both for the review gate.
## Acceptance Criteria
- [ ] `put(len, stream) → (Key, Pin)` with both internal paths behind
the one signature; routing is the pure length function (no
content ever migrates tiers)
- [ ] The three numbered rules each behavior-tested: mid-stream
overflow flushes into a fresh stage and the stream continues;
the derivation pass runs over the eventual stored artifact as a
whole (buffer form and staged-bytes form); stream error leaves
no entry and no stage file
- [ ] Pin-before-publish holds on both paths and both tiers; dedup
re-puts refcount the existing entry
- [ ] `Batch` groups multi-put writes; member pins drop together
- [ ] kv-only mode: known-length over-threshold rejects immediately;
unknown-length rejects at mid-stream overflow; zero residue on
both
- [ ] Stream-shape and len-mismatch design points decided and recorded
- [ ] `cargo test` green; `cargo test --features mem` and `cargo test
--all-features` green; clippy/fmt gates green
## References
- docs/architecture/store-api.md (§Write path — the put seam, stage hygiene invariant)
- docs/architecture/decisions/003-backend-contract-and-dispatch.md (§Dispatch policy — the three numbered rules, option (d))
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §6.2 (kv-only put-time rejection)
- docs/architecture/decisions/005-pooled-cas-and-gc-mechanism.md (pin-before-publish, dedup refcount)
- docs/architecture/decisions/010-backend-io-seams-and-fleet-state-home.md §1 (the staged-put contract)
- src/backend.rs (StagingCursor: ReadCursor — the verification-pass seam)
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion