10 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sqlite-engine-integration | SQLite engine — integration (lint removal, full-surface wiring, suite adoption) | completed |
|
moderate | medium | phase | implementation |
|
Description
Close the wave's integration gaps once every mechanism is wired:
- Remove the two lint suppressions in
alkstore-sqlite/src/substrate/mod.rs(#![allow(dead_code)],#![allow(unused_imports)]) — the waves-1–2 review's explicit wave-3 obligation. With the engine layer wired, every substrate surface should be reachable; genuinely dead ported code must be cut, not suppressed (and the cut registered in PROVENANCE.md if it diverges from the lineage's kept set — ADR-018's delta discipline). Fix whatever the lints surface; do not re-add allows. - Full-surface sweep: every
Store/TxHandle/mechanism trait method implemented (notodo!/unimplemented!anywhere); the engine crate's lib re-exports its public surface (open,SqliteOpts, the concrete store type) per the module-per-file convention. - Contract-suite adoption (the plan's "waves 3 and 4 adopt the
harness"): implement
StoreFactoryfor the SQLite engine (fresh temp-file store peropen, idempotent teardown) and wire the engine's backlog column — the rows this engine owns now, per ADR-023's verification-backlog additions and the engine-scoped backlog rows:- Extent-clamp semantics (
claim_batch(n <= 0), stream readslimit <= 0) — stampedADR-023 §2 - Duration-refusal (
try_lock/renewwithttl <= 0) — stampedADR-023 §2 encode_payloadtyped-failure round-trip (enqueue/publish store- decode the exact serialization) — stamped
ADR-023 §1
- decode the exact serialization) — stamped
- Plain-path open (
?name=valuesuffix = literal filename) — stampedADR-023 §3 - Poll-cadence default + knob (config-surface accounting, not
wall-clock) — stamped
ADR-023 §4 - The engine-scoped rows core-contract.md assigns this engine:
PayloadTooLargenever produced (ADR-016 §5), drop = rollback no-ghosts (ADR-021 §4), in-tx read-your-own-writes (ADR-021 §1), enqueue-opts resolution (ADR-020 §1–§3), receiver close arms (ADR-021 §5) — each stamped per the suite's convention. Rows run against the SQLite factory now; wave 5 runs the same rows against pg (the factory-parameterized point).
- Extent-clamp semantics (
- Crate docs: the engine crate's lib-level doc comments state the single-host posture and the writer-parking honesty note (ADR-016, ADR-007's negative consequence) — the identity statements this crate owns.
- Gates: full workspace build/test/clippy/fmt; coverage spot-check on the engine crate (no large uncovered regions outside error arms).
Acceptance Criteria
- Both
#![allow]lints removed fromsubstrate/mod.rs; any code the removal surfaces is cut (and registered) or wired — clippy-D warningsgreen without them - No
todo!/unimplemented!in the engine crate; full trait surface implemented StoreFactoryimplemented for SQLite; the backlog-column rows listed above exist, version-stamped, and run green against the SQLite factory- Engine crate lib docs carry the single-host + writer-parking posture statements
- Workspace gates green:
cargo build,cargo test, clippy-D warnings, fmt clean
References
- docs/reviews/001-waves-1-2-general-review.md (§2 smells, §7)
- docs/architecture/decisions/023-fourth-review-round.md (Verification backlog additions)
- docs/architecture/core-contract.md (§Verification backlog)
- docs/architecture/decisions/022-contract-suite-layout.md
- docs/architecture/decisions/016-deployment-honesty.md
- alkstore-contract-suite/src/factory.rs
Notes
Decisions of record the description didn't pin:
- Lint removal cut six substrate items, registered D-32..D-36 —
lifting the two
#![allow]s surfaced six genuinely dead surfaces, all cut rather than wired, each an ADR-018 register entry with its reason:arg_opt_i64(upstream consumed it at the optional-arg SQL entry points whose queue functions D-04 dropped — the re-derivation resolves opts engine-side),ops::now_unix(the fold D-17 gave each module region its own clock read;resolution.rsowns the engine layer's single clock),queue_next_claim_at(upstream's external-poll-driver function; the v1 scheduler surface has no next-wake query — the engine's leader loop derives the boundary fromscheduler_tick+scheduler_soonest),Writer::try_acquire(a try-shaped begin doesn't exist on the contract —begin_txparks on the lease by design, ADR-007; a try-acquire would contradict the posture), andUpdateWatcher::spawn/SharedUpdateWatcher::new(the config-less convenience twins — this engine's single open posture always constructsWatcherConfigfromSqliteOpts, ADR-023 §4; a second config-less path would recreate the mixed-posture shape D-29 resolved). None changed kept-fidelity posture — all six aredrop-category entries against the kept set, with the affected substrate tests re-expressing their properties through the reachable surface (no assertion strength lost: the probe tests test the same coercion/lease behavior through the surviving forms). - Two substrate items kept under
#[cfg(test)]rather than cut:SharedUpdateWatcher::subscriber_countand theDEFAULT_WATCHER_POLL_INTERVALre-export — engine-side tests reach them (the leak/no-leak pins, the 1 ms default pin); they are test-observation surface, honestly gated#[cfg(test)], not suppressed.open_storewas likewise promotedpub(crate)(the store tests construct the concrete handle;openstays the consumer surface). - The exemplar row had a real-engine sequencing defect — fixed
suite-side (a suite-text change, ADR-017 §2 class 4): the
name-validation row held its
txhandle alive across the whole battery including the finalwith_txleg. The mock harness never saw this; a real engine'sbegin_txparks a concurrent begin on the writer slot (ADR-007's honest model), so the row deadlocked a real factory. The tx battery is now scoped so the handle drops before thewith_txleg. The row's assertions are unchanged — only the sequencing fix — but the incident is the wave-5 lesson the factory exists to surface: rows are mock-blind until an executes them against a real single-writer engine. - Row set (nine total — the exemplar + eight new, all in
alkstore-contract-suite/src/properties.rs, one owner, version-stamped per the convention, each a publicpub async fn(&dyn StoreFactory)): the ADR-023-stamped rows (extent-clamp including the boundary-totality legs, duration-refusal,encode_payloadround-trip), and the engine-scoped rows the task names (PayloadTooLarge-never-produced — the SQLite arm, the pg rejection arm rides wave 4's adoption of the same row text; the drop=rollback no-ghosts; in-tx read-your-own-writes; enqueue-opts resolution — ADR-020 §1–§3; receiver close/save arms — ADR-021 §5). Plain-path open (§3) and poll cadence (§4) pin engine-side, not as suite rows: both are constructor-level SQLite-native facts not expressible overStoreFactory::open()—uri_shaped_open_path_is_a_literal_filenameandpoll_interval_flows_to_the_watcher_config(stamped,open_tests.rs) are this engine's rows for them; wave 4's pg column simply doesn't carry them (they're SQLite-scoped backlog rows per core-contract.md). - The factory (
alkstore-sqlite/tests/contract_suite.rs): a fresh never-before-used temp file peropenunder a per-instance directory; teardown = directory delete, idempotent (already-deleted ⇒Ok). Its isolation/idempotence contract has its own pin in the test target (opens_are_isolated_and_teardown_is_idempotent); receiver-close rows drive the terminal-close arm by dropping the store handle (the dispose carrier every engine has), not teardown — deleting files under a live store is not a close mechanism. - Coverage spot-check (cargo-llvm-cov, engine crate): 93.59%
lines / ~89% regions, every file ≥85% lines; the misses are error
arms and Windows-only
file_idvariants (watcher.rs's HighRes/LowRes halves) — no large uncovered regions outside error arms, the gate the task pinned.
Summary
Landed: the two
#![allow]lints removed fromsubstrate/mod.rs(its module docs re-stated to the wave-3 wired posture); the removal surfaced six dead surfaces — cut, each registered D-32..D-36 inPROVENANCE.md(queue-side:arg_opt_i64,now_unix,queue_next_claim_at; writer/watcher-side:Writer::try_acquire,UpdateWatcher::spawn,SharedUpdateWatcher::new), their probe tests re-expressed through the reachable surface; two test-observation items honestly#[cfg(test)]-gated (subscriber_count, theDEFAULT_WATCHER_POLL_INTERVALre-export); no allows re-added — clippy-D warningsgreen without them.Contract-suite adoption: eight new rows in
alkstore-contract-suite/src/properties.rs(extent-clamp + boundary-totality, duration-refusal, payload round-trip,PayloadTooLarge-never-produced SQLite arm, drop=rollback no-ghosts, in-tx read-your-own-writes, enqueue-opts resolution, receiver close/save arms) — all version-stamped, all re-exported from the suite lib.store::SqliteFactoryimplemented in the engine's new integration test target (alkstore-sqlite/tests/contract_suite.rs), running all nine rows (the exemplar + the eight) against the SQLite factory — 10 tests, green; the factory's isolation/idempotence contract pinned alongside. Found and fixed suite-side: the exemplar row's hold-the-tx-across-with_txsequencing deadlocked any real single-writer factory (the mock never saw it).Engine crate lib docs: the posture statements surfaced under a
# Postureheading — single-host (ADR-016) and writer-parking (ADR-007's negative consequence) spelled as the crate's identity statements.Verified: workspace
cargo build/cargo testgreen (25 + 186 + 10 + 3 + harness), clippy--workspace --all-targets -D warningsclean,cargo fmt --checkclean; engine-crate coverage 93.59% lines (cargo-llvm-cov), misses confined to error arms and Windows-only watcher variants.