From 8331a96817518f5da893d2e6ae2c9240a76f68f4 Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Sun, 4 Oct 2026 09:26:25 +0000 Subject: [PATCH] docs: OQ-ST-03 gains the explicit SQLite option space (three postures) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator-named options, verified against the honker checkout @ f4e53c6: (1) honker-core on our own rusqlite connection (attach_honker_functions, the alknet-filesystem POC's usage); (2) honker-rs as the SQLite substrate (max reuse, least control — own connections, mutex-pinned transactions, sync-under-async-core); (3) raw SQL over sqlx-sqlite with the honker loadable extension — CI-proven in the checkout's own ORM proof suite (scripts/proof/orm/rust: transactional enqueue natively async, rollback-drops-job asserted), which dissolves most of the async tension on the SQLite side at the cost of a runtime .so dependency and watcher ownership moving in-crate. Options 1/3 are compatible with tokio-postgres on the postgres side under the OQ-ST-02 split. First-POC candidate named: options-1-vs-3 comparison on the same surface. --- docs/research/phase-0.md | 65 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/research/phase-0.md b/docs/research/phase-0.md index e3c1513..fe7ed61 100644 --- a/docs/research/phase-0.md +++ b/docs/research/phase-0.md @@ -5,9 +5,12 @@ per-feature from the paused consumers' documents; phase-0 plan step 1 done; streams upgraded to in-scope by operator-authority record; OQ-ST-02 resolved: reactive-core + engine crates, operator decision; alktty REQ-TTY-01's async-facing-trait + sync-bridge posture recorded as family -precedent bearing on OQ-ST-03's async sub-question. OQ-ST-03/04/05 -remain the open research. Interface finding and driver tension from -2026-10-03 remain trusted-but-unverified working input.) +precedent bearing on OQ-ST-03; OQ-ST-03's SQLite option space expanded +to three named postures (honker-core on our rusqlite / honker-rs as +substrate / honker extension over sqlx — the last CI-proven in the +honker checkout's own ORM proof suite). OQ-ST-03/04/05 remain open +research. Interface finding and driver tension from 2026-10-03 remain +trusted-but-unverified working input.) --- # alkstore — Phase 0 (Exploration) @@ -416,6 +419,62 @@ Genuinely open; needs research rounds (library capabilities vs the unified-trait shape) and possibly a POC. Not deferred — this is the central Phase 0 research question. +**The SQLite option space, named explicitly (2026-10-04, operator + +verified against the checkout @ f4e53c6):** three distinct postures, not +one "rusqlite vs sqlx" axis — + +1. **honker-core on our own rusqlite connection** (the + `attach_honker_functions` shape — the alknet-filesystem POC's actual + usage): we own the connection, the schema bootstrap, and the + watcher; honker supplies the SQL-function machinery. +2. **honker-rs as the crate's SQLite substrate** (`Database::open`, + typed Queue/Stream/Transaction primitives; the guide's "it *is* the + integration" posture): the trade is ownership — honker-rs opens and + holds its own connections, its `Database` wraps a connection mutex + (transactions pin the mutex; same-thread `*_tx` methods only, + deadlock-by-mutex on cross-thread reuse), and the whole engine is + sync under OUR async core (bridge at every seam). Maximum reuse, + least control; the transactional seam inherits honker-rs's + mutex-pinned transaction model rather than ours. +3. **raw SQL over sqlx-sqlite with the honker loadable extension** + (guides/orm/rust §sqlx: `SqliteConnectOptions::extension(ext)` + + `SELECT honker_bootstrap()`, then every feature is plain SQL — + `honker_enqueue`, `notify`, ... — callable through + `SqliteExecutor<'e>`, satisfied by pool, connection, AND + Transaction alike). **Verified in-harness**: the pattern is CI-proven + in the honker checkout itself (scripts/proof/orm/rust — async + business-write + `honker_enqueue` inside a `conn.begin()` tx, + commit-visibility + rollback-drops-job asserted), so the + transactional property holds *natively async* here — no sync bridge + on the call path at all. + +Option 3 is the genuinely interesting one: it dissolves most of the +async tension for the SQLite engine (native-async calls, sqlx-owned +pooling, transactional enqueue proven in the checkout's own proof +suite), keeps honker's machinery as a library-free extension artifact +we don't own code-wise, and moves ALL our custom logic (watcher +ownership, stream cursors, extra SQL) into our own crate. The cost +side: a runtime-loaded .so (build-or-download per the guide) is a +packaging/deployment dependency the other options don't have; sqlx's +load-then-disable extension discipline is worth pinning at the source +(the guide documents it — `SqliteConnectOptions::extension` loads +during connect only, then disables the C load-extension API); and the +watcher (whose machinery otherwise rides option 1/2's honker-core +library linkage) becomes OUR component watching a sqlx-managed pool — +`PRAGMA data_version` re-read design (OQ-ST-04's SQLite wake side) +lands in our lap either way, but under option 3 we can't lean on +honker-core's `SharedUpdateWatcher` thread shape as-is. Options are not +mutually exclusive across engines: option 3 (or 1) for SQLite is +compatible with tokio-postgres for the Postgres engine under the +OQ-ST-02 split. + +This expands OQ-ST-03's option list; the comparison matrix ("honker's +machinery as a linked library on our connection" vs "honker's machinery +as a loaded extension under sqlx") is now the concrete research round, +and a POC comparing options 1 and 3 directly (same queue/stream/notify +surface both ways, incl. watcher wiring) is the natural first POC for +the register. + ### OQ-ST-04: The reactive abstraction — what does the unified notify surface look like? The two engines' mechanisms are structurally different: SQLite =