Files
alkblobs/tasks/suite-column-sqlite.md
T
glm-5.3-flash 97cdf682c4 docs(review): the wave-3 review gate — every gate check green
Reviewed the wave-3 commits (engine-sqlite, engine-sqlite-window,
store-sqlite-construction, store-sweep-durable-window,
suite-column-sqlite) against the cited ADR/spec text line by line:
ADR-003/007/008 §2, ADR-010 §2, ADR-012 §1/§5/§6.7, store-api.md,
implementation.md §Review gates — the engine-vs-contract conformance
(suite column green server-less in the default build; the window
family contract-tested per its applicability row; virgin-store
semantics incl. the no-tables-yet form; the size metadata-only
discipline proven index-riding), the durability posture (WAL +
synchronous=NORMAL verified at open; the single-writer ceiling posture,
not hedge), the durable sweep form vs ADR-008 §2/ADR-012 §6.7 (stage at
mark_end + window; next-sweep execution with raced execution-time
re-arbitration; schedule-relative exact counts; aborts stage and
execute nothing), the seam reduction (gc_window only; no pin rows, no
sweep-lock body, no EngineFleetState), and the blocking discipline
(all rusqlite in spawn_blocking). Named design points audited as
resolved; family conventions clean; no wave-4 amendments arise.

Inline fixes (review-of-record):
- src/gc.rs: the seam's window_stage doc retired the wave-1
  lazy-create hedge for the shipped constructor-at-open posture
  (a tableless database surfaces the engine error on stage;
  per-engine tolerances are each engine's recorded posture)
- tasks/engine-sqlite-window, store-sweep-durable-window,
  suite-column-sqlite: stray placeholder lines above the filled
  Notes/Summary removed (the wave-2 gate's same cleanup)
- tests/conformance/README.md: trailing newline added

Verification (all re-run green after the fixes):
- cargo test (default): 69 lib + 19 conformance + 3 git-interop
- cargo test --features mem / --all-features: 124 lib + 54
  conformance + 4 git-interop each
- cargo clippy --all-targets -- -D warnings (default + all-features)
- cargo fmt --check
- cargo doc --no-deps at the pre-existing warning baseline (26)

Wave 4 (postgres) decomposition is unblocked.
2026-10-12 05:22:29 +00:00

179 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: suite-column-sqlite
name: Conformance suite — the sqlite column (the first SQL-backed column)
status: completed
depends_on: [store-sweep-durable-window]
scope: moderate
risk: medium
impact: phase
level: implementation
tags: [wave-3, suite, sqlite]
---
## Description
Grow the **sqlite column** — the suite's first SQL-backed column,
server-less (never skips; README §SKIP posture: server-less engines'
columns must always be green in every environment). The column runs in
the default build (feature `sqlite` is default-on).
- **Factories** (`tests/conformance/sqlite_column.rs`):
- dual-tier `kv = sqlite + large = local` at a column-declared
threshold and the **test tuning of the window delay (`0` —
execute-on-next-sweep)**;
- `kv-only(sqlite)` at a column-declared threshold (the rejection
row's host; threshold materializable per the README's
configuration contract).
Fresh isolated sqlite file per `open()` (temp file), idempotent
teardown (remove the file), panicking-row-safe — the local column's
instance-tracks-its-own-root pattern.
- **Mirror the form-independent reference rows** (README §The
reference row set): INV-1 round-trips (content matrix × both put
paths, in-body), INV-2 dedup (same-path + cross-path legs), INV-3
stage hygiene (the degenerate kv stage form via the injectable
failure modes — mid-stream `Io`, declared-len `Verification`), INV-6
stat discipline, and the kv-only rejection row (threshold-agnostic
by discovery, unchanged).
- **The sweep rows are schedule-relative on this column.** The
reference set's single-sweep exact-count rows are the inline-form
host's (mem); the durable form's semantics differ (staged this
sweep, executed by the next — ADR-012 §6.7). The sqlite column grows
its own **durable-schedule rows** (concrete-factory per README
§Columns beyond the reference set, ADR-stamped, traced):
- exact counts across two sweeps (sweep 1 stages N, deletes nothing;
sweep 2 executes exactly N — `deleted + cancelled == N` against
the staged set) over the full protection set;
- the sweep-vs-put race across the window delay (a put landing
during the window survives the executing sweep; the unpinned twin
deletes);
- the abort shapes (`NoLivenessSources`/`ProtectFailed`/
`SweeperLock` — form-independent, abort before staging; these
mirror directly);
- INV-5 list correctness through durable-schedule outcomes (exact
counts, never list comparison).
- **The dual-tier dispatch rows** mirror the local column's family
(pure-function routing, threshold boundaries, fall-through per op)
with the placement oracle adapted: both tiers are on disk now — kv
entries live in the sqlite file, large entries under the local root;
the oracle distinguishes by medium (the sqlite file vs the root's
committed files).
- **Virgin-store rows**: reads are no-ops on a fresh file; the
no-tables-yet tolerance form.
- **README amendments** (the convention's normative test-side home):
- the **schedule-relative reading of INV-4/INV-5 for SQL-backed
columns** — the durable form's exact counts are asserted relative
to the staged schedule (ADR-012 §6.7); the reference set's
single-sweep rows are the inline-form host's, and SQL-backed
columns run the durable-schedule equivalents (the mirror
convention's recorded amendment);
- the column inventory (§Columns beyond the reference set grows the
sqlite rows table);
- current state (three columns; the default-build column).
- **Structural factory tests** (the mem column's pattern): factory
isolation (fresh file per open, nothing shared) and
teardown-against-a-panicking-row.
## Acceptance Criteria
- [ ] The sqlite column green server-less: the mirrored
form-independent reference rows + the durable-schedule sweep
rows + the dispatch rows + the virgin-store rows, every row
ADR-stamped and traceable to the backlog
- [ ] The schedule-relative INV-4/INV-5 reading recorded in README
(the mirror convention's amendment, citing ADR-012 §6.7)
- [ ] Factory isolation + idempotent teardown hold (fresh file per
open; teardown safe against a panicking row), structurally
exercised
- [ ] `cargo test` (default) green — the column runs in the default
build; `cargo clippy --all-targets -- -D warnings` and
`cargo fmt --check` green
## References
- tests/conformance/README.md (the conventions this grows against;
§SKIP posture, §Columns beyond the reference set)
- tests/conformance/rows.rs (the reference row set being mirrored)
- tests/conformance/local_column.rs (the dual-tier column pattern)
- tests/conformance/backlog.rs (INV-1…7 entries)
- docs/architecture/store-api.md (§Invariants — the test gate)
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §6.7 (the schedule the sweep rows assert against)
- docs/architecture/decisions/011-vocabulary-tiers-engines-and-fleet-state.md §2 (mem's reference role; INV-7)
## Notes
The column as it landed (`tests/conformance/sqlite_column.rs`, 17 tests):
- **Factories**: `dual-tier sqlite+local` (the default-build
production shape, `DualTierSqliteFactory`) and `kv-only(sqlite)`
(`KvOnlySqliteFactory`), each instance-tracking the temp sites it
vends (a private temp directory per open holding `pool.db` and the
local root; teardown `remove_dir_all`s it — idempotent, NotFound
tolerated, panicking-row-safe, one runner per instance), with the
column-declared threshold (1024) and the **test tuning of the
window delay (`Duration::ZERO` — execute-on-next-sweep)**. The
module is `#[cfg(feature = "sqlite")]` — **default-on**, so the
column runs in every default `cargo test`.
- **The medium oracle distinguishes by medium**: the dual-tier rows
count the sqlite file's `blobs` rows (the kv tier) vs the local
root's committed files (the large tier), plus `gc_window` rows (the
durable schedule observer) — via the test's own independent
connection. The shared helpers (`committed_file_count`,
`staging_file_count`, `slice_digest`, `LatchProtect`) moved to
`rows.rs` (`pub(crate)`, the columns' shared fixtures) so the
sqlite column reuses them without the mem gate.
- **Mirrored verbatim** (form-independent, from `rows.rs`): INV-1
round-trips, INV-6 stat discipline, the `NoLivenessSources`/
`ProtectFailed` abort shapes, and the kv-only rejection row
(against `kv-only(sqlite)`; unchanged, threshold-agnostic by
discovery).
- **Durable-schedule rows** (the column's own, concrete-factory,
ADR-stamped, traced): INV-2 dedup and INV-3 stage hygiene with
counts read against the staged schedule (the sweep-counting rows'
amendment), the two-sweep exact-count row over the full protection
set (both tiers, the window observed), the race across the window
delay (a re-put landing during the window survives the executing
sweep via execution-time re-arbitration; the unpinned twin
deletes; both put paths in-body over both tiers), the
holder-stages-only lease shape (the reference `SweeperLock` row's
schedule-relative form), and INV-5 list correctness through
durable-schedule outcomes.
- **Dispatch rows** mirror the local column's family (pure-function
routing, threshold boundaries at the tuned + shipped-default
thresholds, fall-through per op) with the placement oracle adapted
by medium. **Virgin-store row**: reads are no-ops on a fresh file
(pool, window, and committed tree all empty); the no-tables-yet
tolerance itself is engine-instrumented (src/sqlite.rs — the
constructor always ensures the schema), this row being the facade
form. **Structural factory tests**: fresh isolated opens
(distinct private sqlite files and roots, medium-observable) and
teardown-against-a-panicking-row (files really removed).
- **README amendments**: §The schedule-relative reading for
SQL-backed columns (the mirror convention's amendment, citing
ADR-012 §6.7 — staged-this-sweep / executed-next-sweep, which rows
carry it, which mirror verbatim), the sqlite rows table in §Columns
beyond the reference set, and Current state (three columns; the
default-build column). main.rs's module doc names the column.
## Summary
The sqlite column — the suite's first SQL-backed column — is green:
the default-build production shape (`kv = sqlite` + `large = local`,
feature `sqlite` default-on) runs the form-independent reference rows
verbatim against its factories, grows the durable-schedule sweep rows
whose exact counts are asserted relative to the staged schedule
(ADR-012 §6.7: staged this sweep, executed by the next — two-sweep
counts over the full protection set, the race across the window delay,
the holder-stages-only lease shape, INV-5 through outcomes, and the
schedule-relative INV-2/INV-3 readings), and the dispatch rows with
the medium oracle distinguishing the sqlite file's rows from the
root's committed files. Every row ADR-stamped and traced; the
schedule-relative INV-4/INV-5 reading is recorded in the README (the
mirror convention's amendment); factory isolation (fresh site per
open) and idempotent panicking-row-safe teardown hold structurally.
The column never skips and runs in the default build (17 tests).
Verification: `cargo test` green (default: 69 lib + 19 conformance +
3 git-interop), `cargo test --features mem` green (124 lib + 54
conformance), `cargo check --all-features --tests` green,
`cargo clippy --all-targets -- -D warnings` green, `cargo fmt --check`
green (fmt applied).