--- id: suite-column-mem name: Conformance suite — factory binding and the mem column (the reference column) status: completed depends_on: [store-read-paths, store-put-paths, gc-protocol] scope: moderate risk: medium impact: phase level: implementation tags: [wave-2, suite, mem] --- ## Description Bind the conformance harness to the real facade and grow the **mem column** — the contract-reference column that defines the required set every other engine's rows mirror (store-api.md invariant 7; ADR-011 §2). - **The factory binding** (the skeleton's anticipated wave-2 moment): bind `StoreFactory::Store` to the real facade type — most plausibly the associated type collapsing to the concrete `Store` across all factories. If binding reveals a shape correction, make it and record it in `tests/conformance/factory.rs` + `README.md` per the skeleton's note. The mem factory vends fresh, isolated in-memory stores (no shared state between rows) with idempotent teardown; mem never skips (README §SKIP posture — SKIP machinery stays unneeded until the SQL waves). - **The mem column's rows**, each ADR-stamped per the convention (`Contract stamp:` citing the pinning spec §/ADR §), tracing to the backlog entries: - **INV-1 round-trips**: whole-blob put/get byte-identical under the canonical derivation, over a content matrix looping both put paths (known-length, unknown-length) in-body; the git-interop test remains the derivation's source of truth. - **INV-2 dedup**: identical content twice (same and different put path) is one pool entry; the re-put's `Pin` protects exactly as a fresh put's. - **INV-3 stage hygiene**: exact counts over both put paths and both failure modes (explicit discard, failed commit) — zero residue on failure, exactly one committed entry on success (the degenerate kv stage form). - **INV-4 sweep safety**: single-node exact-count family — happy shape (exact `SweepReport` counts), abort shapes (`ProtectFailed`, `NoLivenessSources` — nothing deleted, `Ok(SweepReport)` always), and the sweep-vs-pinned-put race. - **INV-5 list correctness**: asserted through sweep outcomes (exact counts), never by comparing enumerated lists directly. - **INV-6 stat discipline**: `stat` returns length + algorithm without fetching content. - **Constructor-mode rows** (facade contract, ADR-011 §4 / ADR-012 §6.2/§6.3): mem-only mode; kv-only(mem) over-threshold put-time rejection (known-length immediate, unknown-length mid-stream). - Rows take factories, never stores (factory.rs contract); a failing assertion panics the row; teardown is idempotent against that path. ## Acceptance Criteria - [ ] `StoreFactory::Store` bound to the real facade; any shape correction recorded in factory.rs + README - [ ] The mem column green: INV-1/2/3/4/5/6 rows plus constructor-mode rows, every row ADR-stamped and traceable to the backlog - [ ] The mem column's row set is the reference set (INV-7's basis) — recorded in README as what other columns mirror - [ ] Factory isolation + idempotent teardown hold (fresh store per call; teardown safe against a panicking row) - [ ] `cargo test --features mem` green (the column runs under its feature); clippy/fmt gates green ## References - tests/conformance/README.md (the conventions this grows against) - tests/conformance/backlog.rs (INV-1…7 entries and their first-column plan) - docs/architecture/store-api.md (§Invariants — the test gate) - docs/architecture/decisions/011-vocabulary-tiers-engines-and-fleet-state.md §2 (mem's reference role) - docs/plans/implementation.md (Decided points — suite home; §Wave 2 — suite columns) ## Notes > Filled by the implementation agent (2026-10-11). - **The factory binding was already made and recorded** by the store-construction task: `open()` vends the concrete `alkblobs::Store` facade (the skeleton's `Store` associated type collapsed), recorded in `factory.rs` + README §The factory contract before this task ran. Verified; no further shape correction was needed. The wave-1 binding demonstrator (`binding.rs`) remains as the proof-of-implementability tests. - **The reference row set** lives in `tests/conformance/rows.rs` (engine-uniform, factory-generic, every row ADR-stamped and traced to the backlog): INV-1 (content matrix × both put paths, in-body), INV-2 (same-path + cross-path legs), INV-3 (both paths × both injectable failure modes — mid-stream `Io` failure and declared-len `Verification` mismatch; the kv stage form is degenerate, so residue is the pool itself, observed through exact sweep outcomes), INV-4 (happy shape over the full protection set; all three `GcAbortCause` abort shapes — `NoLivenessSources`, `ProtectFailed`, `SweeperLock`, the last completing the single-node family per ADR-013 §2/ADR-012 §5; the sweep-vs-pinned- put race over both put paths), INV-5 (exact sweep outcomes, never list comparison — honored by every row), INV-6, and the two constructor-mode rows. - **INV-6's slice through the facade**: stat's shape (len + algorithm), purity, and `None`-on-miss; the engine-level non-content-load half rides the tier `size` probes' own bodies (ADR-008 §1) — noted in the row doc; the mismatch-based proof needs a plant seam the factory contract deliberately lacks. - **The kv-only row is threshold-agnostic by discovery**: a known-length rejection reads nothing, so `Unreadable` probes distinguish rejection from acceptance and binary search finds the factory's rejection point (~64 free probes); the row then asserts immediate/mid-stream rejections and both at-threshold-lands legs. Configuration contract recorded in the README: threshold < u64::MAX and materializable (≤ 8 MiB, `MAX_BOUNDARY_MATERIALIZATION`). Any column's kv-only factory mirrors the row unchanged. - **Mem factories** (`mem_column.rs`): `MemOnlyFactory` (the reference host for the INV rows) and `KvOnlyMemFactory` at a column-declared threshold (1024) — fresh isolated store per open by construction, teardown a no-op (mem holds no external state), trivially idempotent and panicking-row-safe. Structural wiring tests (not backlog rows) demonstrate factory isolation and teardown-against-panic: `factory_open_vends_fresh_isolated_stores`, `factory_teardown_is_safe_against_a_panicking_row`. - **Row lifecycle convention recorded**: the row body owns open/assert/teardown; a failing assertion panics before teardown (README §The factory contract grew the bullet). The column runs under feature `mem`; rows.rs compiles ungated so the reference rows stay type-checked in default builds. No SKIP machinery added. ## Summary > Filled on completion (2026-10-11). Landed the **mem column** — the conformance suite's contract-reference column (ADR-011 §2). `tests/conformance/rows.rs` carries the reference row set: INV-1…6 families (12 rows total, incl. all three sweep-abort shapes and the sweep-vs-put race) plus the two constructor-mode rows (mem-only posture; kv-only put-time rejection), each ADR-stamped and traceable to the backlog. `tests/conformance/mem_column.rs` binds the factories (`mem-only`, `kv-only(mem)`) and runs every row; the factory contract's isolation and idempotent-teardown guarantees are demonstrated structurally, including the panicking-row path. README records the reference row set (INV-7's basis — what other columns mirror), the row-lifecycle convention, and the new current state. The wave-2 factory binding (concrete `Store` facade) was already made and recorded upstream of this task; verified, nothing further to correct. Verification: `cargo test --features mem` green (97 lib + 18 conformance + 4 git-interop), `cargo test` (default) and `cargo test --all-features` green, `cargo clippy --all-features --all-targets -- -D warnings` green, `cargo fmt --check` green.