The wave-2 facade skeleton and routing (tasks/store-construction.md):
the public surface consumers program against, with the ops methods
still to land against it in store-read-paths/gc-protocol/store-put-paths.
- src/store.rs — the public `Store` type (engine-blind, ADR-007/008/
010) over crate-internal tier enums (`KvEngine`{mem}, `LargeEngine`{
local}): the engine-representation design point decided as concrete
+ enum dispatch, generic rejected (pub(crate) engines, no dyn);
the three constructor modes as named constructors — `mem_only`,
`kv_only_mem`, `dual_tier_mem_local` (the ADR-012 §6.3
dispatch-coverage shape) — with `StoreMode` introspection; the
write-side routing seam (`tier_for`), the read-side fall-through
order (`kv()` then `large()`, ADR-012 §6.1), and the `GcHome`
GC-state field; the ADR-012 §3 fleet declaration ruled deferred to
the engine waves (nothing fleet-valid is constructible yet)
- src/dispatch.rs — the pure routing function (`route`, at-or-below
→ kv), `DEFAULT_DISPATCH_THRESHOLD` (128 KiB) exported at the
crate root, boundary-value unit tests (exactly-at-threshold,
degenerate tunings, purity)
- src/gc.rs — `GcHome`: the store-instance GC-state home the
gc-protocol task fills (in-process; fleet state stays on the
engine-state seam per ADR-010 §2/ADR-012 §4)
- tests/conformance — the wave-2 binding made as anticipated: the
factory's `Store` associated type collapsed into the concrete
`alkblobs::Store` (`open` vends it directly), recorded in
factory.rs + README; the wave-1 mock probe retired, replaced by
mem-gated binding demo factories (binding.rs) over both
constructible shapes
Verification: `cargo test` (default), `cargo test --features mem`,
`cargo test --all-features` green (41/53/53 unit + conformance
targets green in all three shapes); `cargo clippy --all-targets
-- -D warnings` green in all three feature shapes; `cargo fmt
--check` green; `cargo doc --no-deps` adds no warnings beyond the
pre-existing private-intra-doc-links class.
- LocalBackend: flat {hex-prefix}/{hex-prefix}/{hex} sharding over
lowercase-hex-of-Key::as_bytes filenames (self-describing; the
list-decode round-trip recorded for the review gate); virgin-store
reads are no-ops
- staged put: unique stage files under {root}/staging/, commit-rename
is the publish, CAS first-writer-wins, every failure path (discard,
failed commit, Drop cancellation) converges on zero residue
- read cursor: pread loop over the immutable committed file, EOF
clamping, provided read_range composing the slice-digest convention
- all file I/O in spawn_blocking; size is a stat, never a content load
- list walks the committed tree and is fatal (Error::Io, path named)
on anything that does not decode — complete and well-formed
- 11 in-module unit tests incl. exact-count stage hygiene over all
failure forms and the success form
Verification: cargo test (44 green), clippy --all-targets/--all-features
-D warnings, fmt --check — all clean
Task: tasks/engine-local.md
- src/mem.rs: MemBackend implements Backend (seven methods + put_staged,
name "mem") over Arc<parking_lot::Mutex<BTreeMap<..>>>; CAS
first-writer-wins puts, materializing MemCursor body, degenerate
in-memory MemStaging whose commit publishes via the same CAS clause
and self-discards on failure; discard leaves zero residue.
- CAS re-put is dedup for both put forms; reads are no-ops on the
virgin store; delete carries Missing; size is metadata-only.
- Eight in-module tests mirror the wave-1 double's assertions: method
contract, list well-formedness, cursor body read contract + ADR-006
range digest, empty-entry round-trip, staged happy path, and both
hygiene forms (fail_commit test hook stands in for media failure).
- backend.rs: clamped promoted pub(crate) — the shared EOF-clamping
arithmetic both mem cursor bodies compose (no per-engine duplicate).
Verification: cargo test --features mem (33+7 green); cargo test
(default) green; clippy --all-features --all-targets -D warnings green;
fmt --check green.
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
Every gate check read against the cited ADR text: the key encoding
holds byte-exact against ADR-002 (tags, lengths, rejects, sort order,
preamble abstraction, live git-CLI interop, lowercase oid policy
recorded); the trait + I/O seams + engine-state seam match ADR-003/
010 and ADR-012 §5's reduced table; the error model's five variants
and single-enum altitude reading match store-api.md/ADR-012 §6.5; the
feature graph matches ADR-013 §4; all named design points audited
consistent; the suite convention and backlog are traceable; family
conventions clean. One inline fix: publish keyword `bao` -> `git`
(excluded technology named in metadata). Wave 2 decomposition
unblocked, no amendments.
Verified: cargo test (26 lib + 4 conformance + 3 git-interop passed),
cargo clippy --all-targets -- -D warnings, cargo clippy --all-features
--all-targets -- -D warnings, cargo fmt --check, cargo check
--all-features, cargo check --no-default-features --features pg-lo.
- tests/conformance/README.md: the convention doc — row naming (property-
stated names, engine dimension is the column), the Contract stamp:
format (the alkstore ADR-017 §4.2 convention adapted), the one-
normative-owner-per-property rule, the factory contract (fresh
isolated instance per open, idempotent teardown, safe over an
abandoned instance), the SKIP posture (SQL-attached columns skip
cleanly server-less; acceptance requires green against the server),
the invariant backlog (the seven store-api.md §Invariants registered
as the rows-to-grow table with pinning citations), and the mem-first
column plan (mem is the contract-reference engine, ADR-011 §2)
- harness skeleton, compile-able with zero rows: StoreFactory (fresh
+ isolated + idempotent-teardown contract; the Store associated type
is wave 2's binding point for the facade type), stamp.rs (the
marker + convention anchor), backlog.rs (in-code registry with a
traceability gate asserting INV-1..7 mirror §Invariants in order)
- no engine-specific code; no dependencies added
Verification: cargo test (33 passed across lib + 3 targets),
cargo clippy --all-targets -- -D warnings, cargo fmt --check
The wave-1 contract surface: everything engine-blind that waves 2-6
implement against. No engine bodies, no facade behavior logic.
- src/backend.rs: the pub(crate) Backend trait — seven methods +
put_staged, opaque byte keys/values, size metadata-only, list
complete-and-well-formed, virgin-store reads as no-ops (ADR-003,
ADR-008); the ReadCursor/StagingCursor I/O seams with the read_range
slice-digest convention (ADR-006) at one seam; unit tests against
both body-family doubles, a test-double engine, and the stage-hygiene
invariant's two forms (discard; commit failure self-discards).
- src/gc.rs: the engine-state companion seam as EngineWindowState /
EngineFleetState — ADR-012 §5's applicability table expressed
structurally (no dead machinery); JointTx ownership rule pinned in
the signature (store holds the tx; engine contributes mechanics).
- src/facade.rs: EntryMeta, Pin, Batch, SweepReport, GcAbortCause
(x3, #[non_exhaustive]), PinState with lifecycle contracts
(ADR-005, ADR-012 §1); re-exported from lib.rs.
- Design points pinned for the wave-1 review gate in
tasks/core-trait-and-types.md: pub(crate) trait visibility,
associated-type put-form shapes, AFIT + associated types (no dyn).
Verification: cargo test (26 lib + 3 git-interop), cargo test
--all-features, clippy --all-targets -D warnings (default and
--all-features), cargo fmt --check, cargo doc --no-deps — all green.
Wave 1 task core-hashing-keys: the crate's declared one-way door,
implemented byte-exact to ADR-002.
- src/hashing.rs: Algorithm (exactly GitBlobSha256 canonical /
GitBlobSha1 tolerated; BLAKE3 absent), Digest (known-length
derivation H("blob <len>\0" + content) as primary constructor;
from_git_oid_hex interop constructor, lowercase-only acceptance),
and the hashing::registry constants (0x01/0x02, 0x00 reserved; new
algorithm = new ADR)
- src/keys.rs: typed Key wrapper; as_bytes/from_bytes are the only
backend-boundary conversions; 1 algorithm byte + digest bytes
(33/21 total); rejects-never-guesses validation -> Error::KeyInvalid
- tests/git_interop.rs: the load-bearing test — byte-exact derivation
against the `git hash-object` CLI, both algorithms, small and
75-KiB content; external-oid round-trip into pool keys; both oid
formats coexisting in one flat pool
- named design point (oid hex policy): lowercase-only acceptance,
recorded in the task Notes and on from_git_oid_hex
Verified: cargo test (15 passed), cargo clippy --all-targets -- -D
warnings, cargo fmt --check, cargo test --all-features — all green.
- docs/plans/implementation.md: the meta plan (alkstore pattern) — nine
waves, dependency logic, decided points, review gates. Scope authority:
v0.1.0 ships the full surface (all five engines, fleet GC, ops).
- Wave 1 decomposed: scaffold-crate-features, core-error-model,
core-hashing-keys, core-trait-and-types, suite-scaffold,
review-wave-1 (the one-way-door gate).
- Waves 2-9 shaped in the plan; each decomposes after the prior wave's
review gate.
Verification: cargo test / clippy -D warnings / fmt --check green
(docs-only change).
- OQ-09 resolved closed-by-default (deny-unlisted), decided on risk
asymmetry in hand, not on a first deployment the crate itself must
create; named reopen condition instead of a parked wait
- delete oq-09-ops-visibility-tracker.md (watch-task for an event the
crate itself gates — never collapses)
- fix doc-lifecycle circularity: externally-owned OQs no longer block
a spec's `reviewed` promotion
- gc-and-namespaces: "until a consumer names a requirement" reframed
as re-entry via a new ADR, not a parked question
- README: state the corollary explicitly — facts this crate must
create (its own first deployment/consumer) are never deciding inputs
Verified: full-text sweep for stale OQ-09 deferral/tracker references
comes up clean across docs/ and tasks/.