Files
alkblobs/tasks/store-sqlite-construction.md
T
glm-5.3-flash 2993df0e36 feat(store): the sqlite constructor wiring — the default-build store shapes
- KvEngine::Sqlite slots in; all six kv ops dispatch; the kv cursor
  body dispatches through a new KvCursor sub-enum behind AnyCursor's
  one kv arm (the kv-arm-over-multiple-kv-engines design point,
  recorded)
- dual_tier_sqlite_local (kv = sqlite + large = local, the
  default-build production shape) and kv_only_sqlite constructors —
  both feature-gated on sqlite (default-on), both taking the
  threshold and the delete-window delay, fallible where I/O is
  fallible (Err(Error::Io) per the dual_tier_mem_local pattern)
- ensure_gc_schema runs at construction via the engine-neutral
  KvEngine call (sqlite's body creates gc_window only); the
  window-delay shipped default is the pinned
  DEFAULT_DELETE_WINDOW_DELAY (5 min, ADR-008 §2), constructor-
  tunable, Duration::ZERO legal — the store carries the value for
  the sweep's durable form to consume
- the one-window-host posture recorded in the module doc (the
  durable window hosts on the kv engine when it is SQL-backed; wave
  5's pg-lo dormancy slots in without reshaping)
- stale empty-set scaffolding updated to the landed state: the
  #[allow(unused_variables)] attrs off the KvEngine methods; the
  scope notes in store.rs, backend.rs, sqlite.rs, gc.rs
- constructor unit tests: mode/threshold/window-delay introspection,
  the GC schema observed in the fresh database (window table present,
  gc_pins never), kv-only rejection wiring unchanged, and the
  dual-tier shape round-tripping end-to-end through both tiers

Verification: cargo test 62 passed (default; 5 new tests), cargo test
--all-features 117, cargo test --features mem 117, --no-default-
features --features mem 97; cargo clippy --all-targets -- -D warnings
clean (default + all-features); cargo fmt --check clean; cargo doc
--no-deps at the pre-existing warning baseline.
2026-10-12 04:50:22 +00:00

8.3 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
store-sqlite-construction sqlite constructor wiring — the default-build store shapes completed
engine-sqlite
engine-sqlite-window
narrow low component implementation
wave-3
store
sqlite
construction

Description

Slot sqlite into the facade's engine representation — the slotting-in pattern src/store.rs's module doc pinned ("adding an enum variant and a named constructor is slotting in"):

  • KvEngine::Sqlite variant behind #[cfg(feature = "sqlite")] + the dispatch arms (put/get/has/size/delete/list). The kv cursor dispatch (AnyCursor's kv arm) carries the sqlite materializing body — the kv-arm shape over multiple kv engines (a KvCursor sub-enum vs per-engine variants) is a recorded design point. The #[allow(unused_variables)] empty-set scaffolding on the KvEngine methods shrinks (the kv set is no longer empty in default builds); backend.rs's #![allow(dead_code)] scope note about "the kv engines' whole-value put before wave 3" is updated to the landed state.
  • Named constructors, feature-gated on sqlite (default-on — the default build constructs them):
    • dual-tier kv = sqlite + large = local — the default-build production shape; fallible (file I/O: opening/creating the database, creating the local root). Size-threshold dispatch at the constructor-tunable threshold as in the mem+local shape.
    • kv-only(sqlite) — no large tier; threshold is the put-time rejection point (ADR-012 §6.2; the rejection machinery is the put seam's, already landed — only the constructor slots in).
    • Both take the delete-window delay parameter (ADR-008 §2: the delete window's delay, default 5 min, constructor-tunable per deployment — a named shipped-default constant; Duration). This is the durable window's cadence knob the sweep's SQL-backed form consumes (store-sweep-durable-window); 0 is a legal degenerate tuning (execute-on-next-sweep — the test tuning). The mem/local constructors are unchanged: the inline form has no delay in effect.
  • ensure_gc_schema at construction — the store-core call (engine-neutral; sqlite's body creates gc_window only). A construction failure is Err(Error::Io) per the fallible-constructor pattern dual_tier_mem_local set.
  • The one-window-host rule's store-core posture (ADR-012 §5): the durable window hosts on the kv engine when it is SQL-backed — sqlite hosts. Recorded (code shape or doc note) so wave 5's pg-lo dormancy (the dual-SQL instance stages on the kv engine only) slots in without reshaping.
  • Constructor unit tests: the modes construct and introspect correctly (mode()/threshold()), ensure_gc_schema ran (the window table exists in the fresh database), the window-delay default is the pinned constant, kv-only rejection wiring unchanged, the dual-tier shape round-trips end-to-end (a smoke put/get through both tiers).

Acceptance Criteria

  • KvEngine::Sqlite slots in; all six kv ops dispatch; the kv cursor body dispatches (design point recorded)
  • dual_tier_sqlite_local + kv_only_sqlite constructors exist behind feature sqlite, take threshold + window delay, fallible where I/O is fallible
  • ensure_gc_schema runs at construction; the window-delay shipped default is 5 min (pinned constant) and constructor-tunable; 0 legal
  • The one-window-host posture recorded (sqlite hosts when the kv engine is SQL-backed)
  • The stale empty-set scaffolding/allow notes updated to the landed state
  • cargo test (default) green — the default build constructs and exercises sqlite stores; cargo clippy --all-targets -- -D warnings and cargo fmt --check green

References

  • src/store.rs (the engine-representation design point; the constructor modes; the slotting-in pattern)
  • docs/architecture/decisions/011-vocabulary-tiers-engines-and-fleet-state.md §4 (modes)
  • docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §6.3 (dual-tier shapes), §5 (the one-window-host rule)
  • docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md §2 (the window delay, default 5 min)
  • docs/architecture/decisions/013-family-composition-reactive-boundary-and-feature-graph.md §4 (the feature graph)

Notes

  • KvCursor sub-enum (the recorded design point). The kv cursor dispatch went with a KvCursor sub-enum behind AnyCursor's one Kv arm (rather than a per-engine AnyCursor::Kv* variant pair): per-engine variants would copy the kv materializing arm and its consumers (the verification-on-get body, Blob's drive) per engine without adding a behavior; the sub-enum keeps AnyCursor a two-arm tier dispatch. Postgres (wave 4) slots one arm into KvCursor.
  • KvEngine::ensure_gc_schema — the engine-neutral store-core call lives on the kv-tier enum itself: the sqlite arm forwards to the EngineWindowState clause; the mem arm is structurally nothing (the in-process engines execute the ADR-005 window protocol inline and carry no GC schema). Both sqlite constructors dispatch through it — the store core calls the kv engine, never a typed sqlite path, which is the recording shape the one-window-host posture wanted.
  • The window delay is a named shipped constant (DEFAULT_DELETE_WINDOW_DELAY, 5 min, ADR-008 §2) re-exported from lib.rs; both sqlite constructors take it explicitly (Duration, Duration::ZERO the legal degenerate tuning) and the store carries it as a window_delay field with a crate-internal accessor (Store::window_delay) for the durable sweep form (store-sweep-durable-window) to consume. The mem/local constructors are signature-unchanged; they carry the constant, never consulted (the inline form has no delay in effect — same posture as the mem-only threshold field).
  • Fallibility split: dual_tier_sqlite_local(database, root, threshold, window_delay) is fallible on the database file I/O, ensure_gc_schema, and the local root creation (all Err(Error::Io) via ?); kv_only_sqlite(database, threshold, window_delay) on the first two. WAL engagement failure (e.g. :memory:) is a construction error, per the engine's recorded posture.
  • SqliteBackend gained a #[cfg(test)] table_exists probe (the sqlite_master instrument) so the store tests can observe the schema from the facade side; sqlite.rs's own test helper now delegates to it.
  • The stale empty-set scaffolding is updated to the landed state: the #[allow(unused_variables)] attrs came off the KvEngine methods; the scope notes in store.rs, backend.rs (whole-value put now has its in-tree callers), sqlite.rs (nothing-constructs-the-engine), and gc.rs (the window family's first caller) reflect the landed state. --no-default-features builds (kv set genuinely empty again) still compile under their own cfg arithmetic — verified along with the default, mem-only, and all-features builds.

Summary

Sqlite slotted into the facade's engine representation (wave 3 construction; commit pending at write time): KvEngine::Sqlite with all six kv-op dispatch arms, the KvCursor sub-enum carrying the sqlite materializing body behind AnyCursor's kv arm (design point recorded), the two named constructors (dual_tier_sqlite_local — the default-build production shape, and kv_only_sqlite) taking threshold + the constructor-tunable delete-window delay (DEFAULT_DELETE_WINDOW_DELAY pinned at 5 min, 0 legal), ensure_gc_schema running at construction through the engine-neutral KvEngine call, the one-window-host posture recorded in the module doc (the durable window is the kv engine's when the kv engine is SQL-backed — wave 5's pg-lo dormancy slots in without reshaping), and all stale empty-set allow/scope notes updated to the landed state. Verification: cargo test 62 passing (default build — the 5 new sqlite-construction tests construct, introspect, schema-probe, rejection-check, and end-to-end round-trip both tiers), cargo test --all-features 117, cargo test --features mem 117, --no-default-features --features mem 97, clippy -D warnings (default + all-features) clean, cargo fmt --check clean, and cargo doc --no-deps at the pre-existing warning baseline.