Six tasks against the wave-2 contract surface as reviewed (no amendments from the gate): - engine-sqlite: the default kv engine — WAL + synchronous=NORMAL, prepared statements, the indexed size column probe (B5's row shape), has-as-EXISTS, virgin-store no-tables-yet tolerance, spawn_blocking discipline - engine-sqlite-window: the engine-state seam's window family only (ADR-012 §5's reduction — gc_window, stage/take; no pin rows, no sweep-lock body) - store-sqlite-construction: KvEngine::Sqlite slots in, the dual-tier/kv-only constructors with the constructor-tunable window delay (default 5 min), ensure_gc_schema at construction, the one-window-host posture - store-sweep-durable-window: the sweep's SQL-backed form — overdue rows execute with re-arbitration before/alongside marking, candidates stage at mark_end + window, counts exact relative to the schedule (ADR-012 §6.7); the inline form preserved verbatim - suite-column-sqlite: the first SQL-backed column, server-less — form-independent reference rows mirror directly; the sweep rows are schedule-relative (the recorded INV-4/5 mirror amendment) - review-wave-3: the engine-wave gate (engine-vs-contract conformance) Verification: dependency graph validated (all ids resolve, no cycles, topological order clean); docs-only change. Refs: docs/plans/implementation.md §Wave 3
88 lines
4.0 KiB
Markdown
88 lines
4.0 KiB
Markdown
---
|
|
id: engine-sqlite-window
|
|
name: sqlite engine-state window family — the durable single-node delete window
|
|
status: pending
|
|
depends_on: [engine-sqlite]
|
|
scope: narrow
|
|
risk: low
|
|
impact: component
|
|
level: implementation
|
|
tags: [wave-3, engines, sqlite, gc]
|
|
---
|
|
|
|
## Description
|
|
|
|
Implement the engine-state companion seam's **window family** on the
|
|
sqlite backend (`src/sqlite.rs` or its seam module): the
|
|
`EngineWindowState` impl per ADR-010 §2 **as reduced by ADR-012 §5** —
|
|
the window family only. The pin clauses and the sweep-lock body are
|
|
**dropped dead machinery** for sqlite (ADR-012 §5's table: pin clauses
|
|
**no**, sweep-lock clause **no** — the single-flighter is the
|
|
in-process lock; a sqlite fleet is a recorded non-option, ADR-010 §3).
|
|
Nothing of `EngineFleetState` may exist on this engine.
|
|
|
|
- **`ensure_gc_schema`** — creates **`gc_window` only**
|
|
(`gc_window (key BLOB PRIMARY KEY, visible_after INTEGER)`; the
|
|
timestamp encoding — `SystemTime` ↔ integer, sub-second precision
|
|
for the test tunings — is a recorded design point). Never `gc_pins`;
|
|
the embedder's liveness table is never created here (ADR-008's
|
|
schema-ownership rule — the sweep reads it and never owns it).
|
|
Called at store construction by the store core
|
|
(`store-sqlite-construction` wires the call); the clause body is
|
|
engine-side.
|
|
- **`window_stage`** — stage candidates into the durable window,
|
|
**idempotent per `(key, deadline)`** (`INSERT OR IGNORE` semantics —
|
|
the body's discipline; the store stages each candidate once per
|
|
sweep, and a re-stage of the same key at a new deadline updates the
|
|
row). Virgin store: tolerated (the table exists from construction;
|
|
a no-tables-yet database stages lazily or errors nothing — the
|
|
Backend trait's engine posture carries here).
|
|
- **`window_take(now)`** — take overdue candidates
|
|
(`visible_after <= now`): the rows **leave the window table and
|
|
return as keys** for the calling sweep to re-arbitrate and delete —
|
|
the executor is the next sweep (ADR-012 §6.7). Empty when nothing is
|
|
overdue; virgin store: empty. The take is one atomic step (selected
|
|
rows removed and returned together — a row is never handed out
|
|
twice).
|
|
- **Contract tests** per the applicability row (ADR-012 §5's table is
|
|
the contract-test matrix): the schema creates the window table only
|
|
(assert `gc_pins` does not exist); stage idempotence per
|
|
`(key, deadline)` incl. the re-stage-at-new-deadline form; take
|
|
returns exactly the overdue set, removes it, leaves future rows;
|
|
empty/virgin shapes; the timestamp encoding's boundary
|
|
(`visible_after == now` is overdue — `<=` per the seam doc).
|
|
|
|
The store core drives these clauses (`store-sweep-durable-window`);
|
|
this task ships the clauses and their engine-level contract tests.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] The sqlite backend implements `EngineWindowState` — the window
|
|
family only; no pin-clause or sweep-lock body exists anywhere in
|
|
the sqlite engine
|
|
- [ ] `ensure_gc_schema` creates `gc_window` only; `gc_pins` is never
|
|
created by sqlite (contract-tested)
|
|
- [ ] `window_stage` is idempotent per `(key, deadline)`; a re-stage
|
|
at a new deadline updates the row
|
|
- [ ] `window_take` returns exactly the overdue set (`<= now`
|
|
boundary), removes it atomically, leaves future rows; empty on
|
|
none/virgin
|
|
- [ ] Clause contract tests green; `cargo test` (default) green;
|
|
`cargo clippy --all-targets -- -D warnings` and
|
|
`cargo fmt --check` green
|
|
|
|
## References
|
|
|
|
- src/gc.rs (`EngineWindowState` — the seam contract and its clause docs)
|
|
- docs/architecture/decisions/010-backend-io-seams-and-fleet-state.md §2
|
|
- docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md §5 (the applicability table; the sqlite reduction), §6.7 (the executor)
|
|
- docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md §2 (the durable window's semantics)
|
|
- docs/architecture/decisions/005-pooled-cas-and-gc-mechanism.md (the delete-window protocol)
|
|
|
|
## Notes
|
|
|
|
> To be filled by implementation agent
|
|
|
|
## Summary
|
|
|
|
> To be filled on completion |