feat(tests): the conformance suite's local column — the dual-tier dispatch-coverage shape green (wave 2)

- tests/conformance/local_column.rs: the first dual-tier column, run
  against the kv = mem + large = local factory (ADR-012 §6.3) — fresh
  temp-root store per open, per-instance tracked roots, idempotent
  teardown safe against abandoned/panicking rows (structural tests
  included); never skips (mem-gated — the dual-tier constructor rides
  feature mem until wave 3 provides an ungated kv engine)
- the reference INV row set (rows.rs) mirrored against the dual-tier
  factory at a column-declared tuned threshold (1024), so the shared
  matrix and race fixtures exercise both tiers' bodies (INV-7)
- dispatch rows grown: pure-function routing across put paths and
  re-puts with an on-disk placement oracle (tier residency is
  facade-invisible; with kv = mem the medium is the oracle), threshold
  boundary legs at the tuned and shipped-default thresholds with the
  constructor-tuned re-route leg, and fall-through per op with
  both-tier miss shapes (ADR-003/ADR-012 §6.1/§6.3/§6.5)
- local-specific rows: on-disk stage-hygiene exact counts over both
  put paths (the real stage form, INV-3), pread windows over committed
  files with slice digests verified independently (ADR-006/ADR-010),
  virgin-store no-ops on a fresh root, and exact sweep counts over a
  both-tiers pool (INV-4/INV-5's both-tiers form)
- rows.rs shared fixtures made pub(crate); README records the column's
  row inventory (§Columns beyond the reference set), the declared-
  threshold posture, and the new current state
- stat-as-stat rides the mirrored INV-6 row's over-threshold legs;
  the Drop-cancellation hygiene form stays per-engine (recorded)

Verification: cargo test (default) green; cargo test --features mem
green (97 lib + 37 conformance + 4 git-interop); cargo test
--all-features green; clippy --all-targets -D warnings green in both
feature shapes (default + all-features); cargo fmt --check green;
cargo doc --no-deps shows only the pre-existing warning class
This commit is contained in:
glm-5.3-flash committed 2026-10-11 23:30:31 +00:00
1 parent f86e20a217
commit 45c456989f
5 files changed
+1560 -43

No files matched your search

+130 -9
View File
@@ -1,7 +1,7 @@
---
id: suite-column-local
name: Conformance suite — the local column and the dispatch-coverage shape
status: pending
status: completed
depends_on: [suite-column-mem]
scope: moderate
risk: medium
@@ -51,16 +51,17 @@ local-specific properties.
## Acceptance Criteria
- [ ] The dual-tier `kv = mem` + `large = local` factory green with
- [x] The dual-tier `kv = mem` + `large = local` factory green with
isolation + idempotent teardown
- [ ] The local column green: mem's row set mirrored (INV-1/2/3/4/5/6)
- [x] The local column green: mem's row set mirrored (INV-1/2/3/4/5/6)
plus dispatch rows (pure-function routing, fall-through per op,
threshold boundaries) and local-specific rows (pread ranges,
virgin-store no-ops, stat-as-stat)
- [ ] Stage-hygiene exact counts asserted on disk (the real stage form)
- [ ] Every row ADR-stamped and traceable to the backlog
- [ ] `cargo test` green (local is ungated — the column runs in the
default build); clippy/fmt gates green
- [x] Stage-hygiene exact counts asserted on disk (the real stage form)
- [x] Every row ADR-stamped and traceable to the backlog
- [x] `cargo test` green (default build; the column itself runs under
`--features mem` — the kv = mem pairing gates it, see Notes);
clippy/fmt gates green
## References
@@ -73,8 +74,128 @@ local-specific properties.
## Notes
> To be filled by implementation agent
> Filled by the implementation agent (2026-10-11).
- **The dual-tier factory** (`tests/conformance/local_column.rs`):
`DualTierLocalFactory` (the dispatch-coverage shape, `kv = mem` +
`large = local`) — `open()` vends the concrete `Store` facade over a
fresh private temp root per call (mem shares nothing; the local
engine gets its own root), tracked per *factory instance*;
`teardown()` removes that instance's roots idempotently and is safe
against abandoned instances (the structural tests carry the panicking
row over a medium-backed factory). Every runner constructs its own
factory instance — a shared static's teardown would race
concurrently running rows' roots (the mem factory's no-op teardown
didn't have this hazard; the local one does, so instance ownership
is the rule, recorded in the module doc).
- **The mirrored set** (INV-7): all ten INV-family rows of the
reference set run against the dual-tier factory at a column-declared
tuned threshold (1024) — the shared content matrix and race fixtures
cross it, so both tiers' bodies are exercised (sub-threshold kv
rows; over-threshold stage-commit rows). The INV-3 reference row
mirrors with the *degenerate kv stage form* it owns; the **stage
form** is this column's own row (below). The mem-only and kv-only
constructor-mode rows do not mirror (their `mode()` preconditions
name modes this column is not; README records the rule).
- **The dispatch rows** (the coverage shape's reason to exist):
`routing_is_a_pure_function_of_length_across_put_paths_and_re_puts`
(at/below/over the threshold, same content, both put paths: same
placement, nothing moves or duplicates, one pool entry through all
paths, exact sweep counts);
`threshold_boundary_lengths_route_deterministically` (boundary legs
at the declared threshold on both put paths, plus the default
boundary's length re-routing with the constructor's tuning — run
against the tuned and the default-threshold factories);
`kv_tier_misses_fall_through_to_the_large_tier_per_op` (get/stat/
has/read_range each served from the large tier when the kv tier
misses, the kv-first mirror-position leg, and both-tier miss shapes
per op — `None`/`None`/`false`/`Missing`).
- **Tier placement is observed through the medium, not the facade.**
Tier residency is facade-invisible by design (the facade is
engine-blind; ADR-012 §6.1's consult order is not a routing
query). With `kv = mem`, the medium itself is the oracle: the mem kv
tier never touches the factory's disk, so a committed file outside
the staging area under the column's temp root is exactly one
large-tier entry and its absence is exactly a kv-tier entry. That
makes the dispatch rows *column-owned* rows taking the concrete
factory (an engine-uniform reference row can never make these
assertions); README §Columns beyond the reference set records the
shape. The dual-tier threshold is likewise **declared
configuration, not a probe**: a dual-tier store never rejects, so
the kv-only row's probing trick has nothing to probe — the rows read
the threshold the factory declares (the value the constructor took).
- **The local-specific rows**:
`stage_hygiene_exact_counts_on_disk_over_both_put_paths` (INV-3's
real stage form — mid-stream `Io` and declared-len `Verification`
failures over threshold-zeroing content leave zero stage files and
zero committed entries on disk; success leaves exactly one committed
entry per path, zero stage files; the Drop-cancellation form needs
the engine internals and stays covered by the engine's in-module
tests, per the engine-local task);
`pread_windows_read_committed_files_mid_slices_and_eof_clamped`
(both put paths' committed files: mid-file slices, tail clamps,
EOF-empty, zero-length, over-read clamp, `read_range` slice + digest
verified against an independently computed SHA-256);
`virgin_store_reads_are_no_ops_on_a_fresh_root` (empty `list`,
per-op miss shapes, empty medium);
`sweep_counts_stay_exact_over_both_tiers` (INV-4/INV-5's both-tiers
form: the full protection set spanning tiers, dead witness per tier,
exact report counts *and* exact on-disk counts, protected entries
byte-identical across tiers).
- **stat-as-stat**: the "size as a stat, never a content load"
property is carried by the mirrored INV-6 row run at the tuned
threshold — its over-threshold legs stat entries served by the
local engine's file-stat size probe (ADR-008 §1), the same
facade-slice/engine-half posture the mem column recorded; no
separate row was needed.
- **Feature gating (amendment to the acceptance criterion as
written)**: the criterion expected "local is ungated — the column
runs in the default build", but the only constructible kv engine
until wave 3 (sqlite) is mem, so `Store::dual_tier_mem_local` rides
feature `mem` (the store-construction task's recorded default-build
note) — the column is `#[cfg(feature = "mem")]`-gated and runs under
`cargo test --features mem`, exactly as the mem column does. The
local *engine* itself remains ungated (in `src/`, default-build
compiled); the reference row set compiles ungated (type-checked in
default builds). The criterion line was amended to the factual
reading; the gate is the kv pairing's, not the local engine's.
## Summary
> To be filled on completion
> Filled on completion (2026-10-11).
Landed the **local column** — the suite's first dual-tier column, run
against the `kv = mem` + `large = local` dispatch-coverage factory
(ADR-012 §6.3): fresh temp-root dual-tier store per `open()`,
per-instance tracked roots, idempotent teardown safe against aban-
doned/panicking rows (structural tests included), never skips.
`tests/conformance/rows.rs` gained `pub(crate)` shared fixtures;
`tests/conformance/local_column.rs` mirrors the reference INV row set
against the dual-tier factory at a tuned threshold (1024) so the
shared matrix and race fixtures exercise both tiers' bodies, and grows
the column's own rows: the three dispatch rows (pure-function routing
across put paths and re-puts with an on-disk placement oracle — tier
residency is facade-invisible, so the medium is the oracle; threshold
boundary legs at the tuned and shipped-default thresholds with the
constructor-tuned re-route leg; fall-through per op with both-tier
miss shapes) and the four local rows (on-disk stage-hygiene exact
counts over both put paths — the real stage form; pread windows over
committed files with EOF clamping and an independently verified slice
digest; virgin-store no-ops on a fresh root; exact sweep counts over a
both-tiers pool — also INV-5's both-tiers form). stat-as-stat rides
the mirrored INV-6 row's over-threshold legs. Every row is
ADR-stamped and traced (README's new column inventory section);
stat-as-stat's engine half and the Drop-cancellation hygiene form
remain per-engine (the mem column's INV-6 posture and the engine's
unit tests, respectively — recorded). The column is mem-gated (the
dual-tier constructor rides feature `mem` until wave 3 provides an
ungated kv engine); the criterion's "runs in the default build"
expectation is amended and recorded.
Verification: `cargo test` green (42 lib + 2 conformance + 3
git-interop), `cargo test --features mem` green (97 lib + 37
conformance + 4 git-interop), `cargo test --all-features` green; `cargo
clippy --all-targets -- -D warnings` and `cargo clippy --all-features
--all-targets -- -D warnings` green; `cargo fmt --check` green;
`cargo doc --no-deps` shows only the pre-existing private-intra-doc-
links warning class (this task touches no public API).
+73 -12
View File
@@ -185,6 +185,49 @@ families' first shapes (the `SweeperLock` abort) complete the three
`GcAbortCause` variants within the single-node exact-count family
(ADR-013 §2's lease, its in-process ADR-012 §5 form).
## Columns beyond the reference set (INV-7's mirror + extension)
The constructor-mode rows of the reference set run wherever the mode
they name is constructible (README §The reference row set). A
multi-tier column mirrors the set and grows **its own rows** for what
its configuration carries that the reference set's single-tier host
did not: the dispatch-coverage shape (ADR-012 §6.3 — both tiers
load-bearing) and the engine's tier-specific properties. Those rows
are still conformance rows — ADR-stamped, named for the property,
traced — but they take the **column's concrete factory** instead of
the `StoreFactory` trait: they observe the backing medium, which an
engine-uniform row (unable to branch on any engine, and unable to see
any tier's residency through the facade) cannot. Tier placement is
facade-invisible by design; with `kv = mem`, the medium itself is the
oracle — the mem kv tier never touches the factory's disk, so a
committed file outside the staging area under the column's temp root
is exactly one large-tier entry, and its absence beside a served read
is exactly a kv-tier entry.
**The local column's own rows** (tests/conformance/local_column.rs,
the dispatch-coverage and local-specific families):
| Row | Traces to |
|---|---|
| `routing_is_a_pure_function_of_length_across_put_paths_and_re_puts` | ADR-003 §Dispatch policy (purity/no-migration); ADR-012 §6.3; INV-7 facade-contract row |
| `threshold_boundary_lengths_route_deterministically` | ADR-003 §Dispatch policy (at/below/above the threshold; constructor-tuned re-route); ADR-012 §6.3 |
| `kv_tier_misses_fall_through_to_the_large_tier_per_op` | ADR-012 §6.1 (fall-through per op); ADR-012 §6.5 ruling 5 (miss shapes); ADR-006 |
| `stage_hygiene_exact_counts_on_disk_over_both_put_paths` | INV-3's stage form (exact counts on disk); ADR-010 §1; ADR-003 |
| `pread_windows_read_committed_files_mid_slices_and_eof_clamped` | store-api.md §Read path; ADR-010 §1 (streaming cursor); ADR-006 |
| `virgin_store_reads_are_no_ops_on_a_fresh_root` | store-api.md §Error model (virgin-store semantics); ADR-012 §6.5 |
| `sweep_counts_stay_exact_over_both_tiers` | INV-4/INV-5's both-tiers form (exact counts + list correctness through outcomes); ADR-005; ADR-012 §1/§6.3/§6.7 |
**The dual-tier threshold is declared configuration, not a
behavioral probe.** The kv-only reference row discovers its factory's
threshold by probing (rejections read nothing — free). A dual-tier
store never rejects a length, and tier residency is facade-invisible,
so there is nothing to probe: the dispatch rows take the threshold
the column's factory declares (the same value its constructor took —
configuration, like the mem column's kv-only threshold). The mem-only
and kv-only mode rows do not mirror onto the dual-tier factories (the
precondition `mode()` shapes they assert are not this column's mode);
the dispatch rows are the dual-tier mode's facade-contract coverage.
## Column plan
**mem is the contract-reference engine** (ADR-011 §2): wave 2 lands
@@ -197,15 +240,33 @@ and first run in wave 6.
## Current state
The harness is green on the **mem column** (wave 2): the factory
binding is the concrete `alkblobs::Store` facade (see §The factory
contract — the binding demonstrator remains in `binding.rs`), the
reference row set is landed (§The reference row set — `rows.rs`,
every row ADR-stamped and traced to the backlog), the column's
factories (`mem-only`, the reference; `kv-only(mem)` at a
column-declared threshold) vend fresh isolated stores with idempotent
teardown (`mem_column.rs`, the structural factory-contract tests
included), and mem never skips. The column runs under feature `mem`
(`cargo test --features mem`); the row set compiles ungated so the
reference rows stay type-checked in default builds. The local column
grows next.
The harness is green on **two columns** (wave 2). The **mem column**
is the contract-reference column: the factory binding is the concrete
`alkblobs::Store` facade (see §The factory contract — the binding
demonstrator remains in `binding.rs`), the reference row set is landed
(§The reference row set — `rows.rs`, every row ADR-stamped and traced
to the backlog), the column's factories (`mem-only`, the reference;
`kv-only(mem)` at a column-declared threshold) vend fresh isolated
stores with idempotent teardown (`mem_column.rs`, the structural
factory-contract tests included), and mem never skips.
The **local column** (the suite's first dual-tier column, the
dispatch-coverage shape ADR-012 §6.3 names) mirrors the reference INV
rows against its `kv = mem` + `large = local` factory at a
column-declared tuned threshold — the shared matrix and race fixtures
cross it, so both tiers' bodies are exercised — and grows the
dispatch-coverage rows (pure-function routing with an on-disk
placement oracle, fall-through per op, threshold boundaries at both
the tuned and the shipped-default threshold) plus the local-specific
rows (on-disk stage hygiene exact counts, pread windows, virgin-store
no-ops, the both-tiers sweep shape) — §Columns beyond the reference
set is the recorded inventory. Its factory instances each track and
remove their own temp roots (idempotent teardown, panicking-row-safe;
each runner owns its instance so concurrent rows never share roots).
mem-only/kv-only modes and the local column never skip, but the local
column is feature-gated on `mem`: the `dual_tier_mem_local`
constructor rides feature `mem` because mem is the only constructible
kv engine until wave 3 (the gate is the kv pairing's, not the local
engine's, which is ungated in `src/`) — the column runs under `cargo
test --features mem`, with the reference row set compiling ungated so
it stays type-checked in default builds.
File diff suppressed because it is too large. Load diff
+13 -5
View File
@@ -15,11 +15,17 @@
//! skip-free reference shape) proves the contract implementable
//! against the real type.
//!
//! The rows landed with wave 2's mem column: [`rows`] holds the
//! reference row set (INV-1…6 plus the two constructor-mode rows,
//! ADR-stamped, traced to [`backlog`]) and [`mem_column`] is the
//! contract-reference column ([`README`](./README.md) §The reference
//! row set is the recorded inventory other columns mirror).
//! The reference rows landed with wave 2's mem column: [`rows`] holds
//! the reference row set (INV-1…6 plus the two constructor-mode rows,
//! ADR-stamped, traced to [`backlog`]); the columns' records live in
//! their module docs ([`README`](./README.md) §The reference row set
//! is the recorded inventory other columns mirror).
//!
//! The columns: [`mem_column`] — the contract-reference column;
//! [`local_column`] — the suite's first dual-tier column (the
//! `kv = mem` + `large = local` dispatch-coverage shape ADR-012 §6.3
//! names), which mirrors the reference set and grows the
//! dispatch-coverage and local-specific rows.
//!
//! Items beyond the tests below are the later columns' surface, hence
//! the scoped `#![allow(dead_code)]` — it shrinks as columns land.
@@ -31,6 +37,8 @@ mod backlog;
mod binding;
mod factory;
#[cfg(feature = "mem")]
mod local_column;
#[cfg(feature = "mem")]
mod mem_column;
mod rows;
mod stamp;
+22 -17
View File
@@ -52,24 +52,25 @@ use alkblobs::{
///
/// A set-backed liveness source — the live-shared seam's test shape:
/// the store consults the same set the row mutates, so answers are
/// live-shared, never registration snapshots.
/// live-shared, never registration snapshots. `pub(crate)`: the
/// suite's other columns reuse these fixtures.
#[derive(Default)]
struct SetSource {
pub(crate) struct SetSource {
live: Mutex<BTreeSet<Key>>,
}
impl SetSource {
fn register(store: &Store) -> Arc<SetSource> {
pub(crate) fn register(store: &Store) -> Arc<SetSource> {
let source = Arc::new(SetSource::default());
store.register_liveness_source(source.clone());
source
}
fn add(&self, key: Key) {
pub(crate) fn add(&self, key: Key) {
self.live.lock().insert(key);
}
fn remove(&self, key: &Key) {
pub(crate) fn remove(&self, key: &Key) {
self.live.lock().remove(key);
}
}
@@ -87,16 +88,16 @@ impl LivenessSource for SetSource {
/// A set-backed protect callback; `None` models the failed-to-answer
/// case (abort-as-data on the safe side).
#[derive(Default)]
struct SetProtect {
pub(crate) struct SetProtect {
set: Mutex<Option<Vec<Key>>>,
}
impl SetProtect {
fn set_keys(&self, keys: Vec<Key>) {
pub(crate) fn set_keys(&self, keys: Vec<Key>) {
*self.set.lock() = Some(keys);
}
fn fail(&self) {
pub(crate) fn fail(&self) {
*self.set.lock() = None;
}
}
@@ -129,15 +130,15 @@ impl ProtectCallback for LatchProtect {
/// A stream cut at controlled chunk boundaries (`sizes`, in order;
/// tail data falls out whole) — makes multi-read loops, mid-stream
/// overflow, and staged continuation observable past the put loop's
/// own chunking.
struct Chunked {
/// own chunking. `pub(crate)`: the suite's other columns reuse it.
pub(crate) struct Chunked {
data: Vec<u8>,
cursor: usize,
sizes: std::collections::VecDeque<usize>,
}
impl Chunked {
fn new(data: &[u8], sizes: &[usize]) -> Chunked {
pub(crate) fn new(data: &[u8], sizes: &[usize]) -> Chunked {
Chunked {
data: data.to_vec(),
cursor: 0,
@@ -177,15 +178,15 @@ impl AsyncRead for Chunked {
/// A stream that delivers `fail_after` bytes then errors mid-stream —
/// the non-restartable source's failure (the failure-discard path's
/// injectable shape).
struct Failing {
/// injectable shape). `pub(crate)`: the suite's other columns reuse it.
pub(crate) struct Failing {
data: Vec<u8>,
cursor: usize,
fail_after: usize,
}
impl Failing {
fn new(data: &[u8], fail_after: usize) -> Failing {
pub(crate) fn new(data: &[u8], fail_after: usize) -> Failing {
Failing {
data: data.to_vec(),
cursor: 0,
@@ -247,14 +248,18 @@ fn matrix() -> Vec<Vec<u8>> {
]
}
fn patterned(len: usize, modulus: u32) -> Vec<u8> {
/// A content-shape generator: `len` bytes cycling against `modulus` —
/// deterministic, size-tunable content. `pub(crate)`: the suite's
/// other columns reuse it.
pub(crate) fn patterned(len: usize, modulus: u32) -> Vec<u8> {
(0..len as u32).map(|i| (i % modulus) as u8).collect()
}
/// One leg of the exact-count sweep assertions: a completed report's
/// counts are exact over the staged set (`candidates_staged ==
/// deleted + cancelled_by_arbitration`).
fn assert_exact_counts(report: &alkblobs::SweepReport) {
/// deleted + cancelled_by_arbitration`). `pub(crate)`: the suite's
/// other columns reuse it.
pub(crate) fn assert_exact_counts(report: &alkblobs::SweepReport) {
assert_eq!(
report.candidates_staged,
report.deleted + report.cancelled_by_arbitration,