OQ-06 resolved: honker-core quality read fires the fork trigger (ADR-011)
Quality read of honker-core's watcher/transactional core cross-checked against the published crates.io artifact: the core itself is clean (Writer/Readers, polling-watcher failure handling, WatcherDeathGuard all verified), but published 0.5.0 predates upstream's unreleased fix train carrying the issue-#133 savepoint hardening (silent job loss in the dead-letter paths) and five .ok() error swallows — and ADR-010's queue depth requires engine-owned queue SQL in any posture. Resolution: fork honker-core at the reference revision, inherit the clean machinery and test suites, re-derive queue ops on contract v1, rename tables to __alkstore_*. - docs/research/quality-read-honker-core.md — full evidence - docs/architecture/decisions/011-sqlite-substrate-fork.md — decision - OQ-06 resolved in open-questions.md; ADR-003/005/008, engine-sqlite, queues, README annotated for consistency
This commit is contained in:
1 parent
79a135c934
commit
befbe2e714
10 files changed
+586
-74
No files matched your search
@@ -83,7 +83,9 @@ comparable reuse.
|
||||
|
||||
- honker-core pins rusqlite ^0.40.1; version movement in honker-core
|
||||
moves our rusqlite. A honker-core quality read is the recorded fork
|
||||
trigger ([ADR-005], OQ-06).
|
||||
trigger ([ADR-005], OQ-06) — *(resolved 2026-10-05: the trigger
|
||||
fired, [ADR-011](011-sqlite-substrate-fork.md) forks the substrate;
|
||||
its rusqlite pin is then ours to move deliberately.)*
|
||||
- rustc ≥ 1.99 required by rusqlite 0.40.x — binaries linking this
|
||||
engine carry that toolchain floor (deployment-matrix row,
|
||||
[deployment.md](../deployment.md)).
|
||||
|
||||
@@ -27,7 +27,7 @@ when a named trigger fires. Per subsystem:
|
||||
|
||||
| Subsystem | Posture | Notes |
|
||||
|---|---|---|
|
||||
| honker-core (SQLite engine machinery) | published library, `honker-core = 0.5` | Fork trigger: the Phase 1 quality read of the watcher/transactional core finds a defect, OR a needed change upstream won't take. OQ-06 tracks the read. |
|
||||
| honker-core (SQLite engine machinery) | published library, `honker-core = 0.5` — **trigger fired 2026-10-05**: forked per [ADR-011] | Fork trigger: the Phase 1 quality read of the watcher/transactional core finds a defect, OR a needed change upstream won't take. OQ-06 tracked the read; the read fired the trigger (published 0.5.0 carries the unreleased-fix-train defect class + ADR-010's queue depth requires engine-owned queue SQL in any posture). |
|
||||
| rusqlite | published, riding honker-core's pin | Pin movement is honker-core's; we ride it ([ADR-003]). |
|
||||
| tokio-postgres + deadpool-postgres | published library, as-is | Clean, zero conflicts, actively maintained (POC #2). |
|
||||
| postgres-notify | **not adopted** (derive-not-adopt) | Lazy reconnect, connect_script skipped at initial connect, unquoted-identifier LISTENs, single maintainer. Hand-rolled forwarder instead ([ADR-004]). Fallback if upstream improves materially. |
|
||||
@@ -43,7 +43,9 @@ to this posture.
|
||||
**Positive**
|
||||
|
||||
- Zero vendored code in the tree by default; upgrades are
|
||||
`cargo update` work, not patch-management work.
|
||||
`cargo update` work, not patch-management work. *(Exception now
|
||||
live: the [ADR-011] fork is a vendored family crate — the named
|
||||
trigger, not a posture change.)*
|
||||
- The fork triggers are concrete and named *before* the quality read,
|
||||
so the read produces a decision, not a debate.
|
||||
- Per-subsystem votes are recorded with evidence, so no future
|
||||
@@ -53,6 +55,10 @@ to this posture.
|
||||
|
||||
- honker-core 0.5 remains alpha-quality software per its own README in
|
||||
the link graph; the quality read (OQ-06) is the mitigation gate.
|
||||
*(Resolved 2026-10-05: the read fired the trigger — [ADR-011].
|
||||
This row's negative consequence is retired with it; the
|
||||
"zero vendored code" positive consequence now carries ADR-011's
|
||||
named exception.)*
|
||||
- The pg queue machinery is written by us — the pg-boss family's
|
||||
battle-tested edge cases must be re-earned by design + tests
|
||||
([queues.md]).
|
||||
|
||||
@@ -208,8 +208,9 @@ struct Wake { channel: String }
|
||||
- SQLite: honker's machinery owns two categories of internal names,
|
||||
and the contract treats them differently. Its `_honker_*` *table*
|
||||
family (`_honker_dead`, `_honker_locks`, …) is storage-internal —
|
||||
not part of any consumer namespace; its fate rides the quality
|
||||
read (OQ-06, [ADR-005](005-dependency-ownership.md)). Its
|
||||
not part of any consumer namespace; its fate resolved with the
|
||||
quality read (OQ-06, [ADR-011](011-sqlite-substrate-fork.md) — the
|
||||
fork re-owns the names as `__alkstore_*`). Its
|
||||
**consumer-namespace derived names** are a real collision surface:
|
||||
honker-rs materializes an outbox's backing queue as
|
||||
`_outbox:{name}` inside the queue-name namespace — a consumer
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
# ADR-011: SQLite substrate — fork honker-core into owned code
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (2026-10-05, Phase 1 — OQ-06's resolution; the fork trigger
|
||||
ADR-005 named, fired)
|
||||
|
||||
## Context
|
||||
|
||||
ADR-005 fixed the dependency posture: published honker-core 0.5 by
|
||||
default, with the fork trigger being the Phase 1 quality read finding a
|
||||
defect the POCs wouldn't surface. ADR-010 handed the read two concrete
|
||||
fork candidates (the expired-processing-row zombie hole; dead-row
|
||||
`get_job` visibility) and made the SQLite realization of contract v1's
|
||||
queue depth contingent on it. OQ-06 is the tracked assessment; the
|
||||
evidence is `docs/research/quality-read-honker-core.md` (full read of
|
||||
all five honker-core sources at the reference revision, cross-checked
|
||||
against the published crates.io artifact).
|
||||
|
||||
Three facts drive this decision:
|
||||
|
||||
1. **The published artifact carries confirmed silent-job-loss defects.**
|
||||
crates.io's newest honker-core is 0.5.0 (2026-08-23). The upstream
|
||||
fix train for its own documented defect class — issue #133's
|
||||
savepoint hardening of the DELETE→INSERT dead-letter paths (a job
|
||||
stranded in neither table on mid-flight error = silent job loss) and
|
||||
the five `.ok()` error-swallows that map every SQLite error to "no
|
||||
row"/"not our claim"/"lock held" — sits in the repository
|
||||
*unreleased*, alongside `claimed_at` and six weeks of hardening. The
|
||||
ride posture's core value ("defects inherited for free" cuts both
|
||||
ways: fixes do too) currently inherits the defects, not the fixes.
|
||||
2. **Contract v1 requires re-deriving the queue-op surface in any
|
||||
posture.** Per-job option stamps (ADR-010 §3a — visibility/backoff/
|
||||
retention stamped at enqueue, honored per-row in the claim
|
||||
statement), the no-stranded-rows sweep (§5), and dead-visible
|
||||
`get_job` with stamps (§1) all mean the engine owns enqueue / claim
|
||||
/ retry / fail / sweep / get_job SQL whether riding or forking. The
|
||||
post-fork ride would cover only ack/heartbeat/cancel, locks,
|
||||
streams, notify transport, scheduler storage, and the watcher/
|
||||
connection plumbing — the minority of what the engine touches, dual-
|
||||
owning the `_honker_*` schema with our migrations in the complement
|
||||
posture.
|
||||
3. **The read's original target — the watcher/transactional core — is
|
||||
clean.** Writer, Readers, and the polling watcher's three-layer
|
||||
failure handling (transient-BUSY-vs-fatal classification, conservative
|
||||
wakes, re-baseline discipline, the stat-identity dead-man's switch)
|
||||
and `WatcherDeathGuard`'s death-closes-subscribers property all
|
||||
verified in source, present in 0.5.0. This fact steers the fork's
|
||||
*scope* (inherit that machinery almost verbatim), not the posture.
|
||||
|
||||
## Decision
|
||||
|
||||
**The fork trigger fires.** The SQLite engine's substrate becomes owned
|
||||
code: fork honker-core at the reference revision
|
||||
(`/workspace/honker` @ `f4e53c6`, MIT OR Apache-2.0, provenance
|
||||
recorded per AGENTS.md §3) into the alkstore family, ported to the
|
||||
family standard (tokio-facing consumers, no comments discipline, panics
|
||||
out of library code), re-derived on contract v1 where ADR-010 pinned
|
||||
semantics honker's functions don't provide.
|
||||
|
||||
Per-scope (the full register with keeps/re-derivations/drops is
|
||||
`docs/research/quality-read-honker-core.md` §6):
|
||||
|
||||
- **Inherited near-verbatim:** the PRAGMA/WAL open posture,
|
||||
`Writer`, `Readers`, the polling watcher + `SharedUpdateWatcher` +
|
||||
`WatcherDeathGuard` + dead-man's switch (with two port fixes the read
|
||||
named: reconnect backoff, fallible watcher spawn), the
|
||||
`in_savepoint` mutation-discipline machinery, arg-coercion helpers,
|
||||
the notify scalar + notifications table (renamed, with engine-
|
||||
internal hygiene per ADR-010 §6), streams, locks.
|
||||
- **Re-derived on contract v1:** enqueue + opt stamping; single-
|
||||
statement claim with per-row visibility from the job's stamps;
|
||||
savepoint-guarded retry/fail/dead-letter; the both-states
|
||||
no-stranded-rows `sweep_expired` with retention deletion; dead-
|
||||
visible `get_job`; scheduler tick with `@every` boundary math.
|
||||
- **Dropped:** cron parsing (ADR-009 rejects cron strings), the
|
||||
experimental watcher backends and their optional deps, the rate-limit
|
||||
and result tables (cut-flags), the superseded queue functions.
|
||||
- **Table naming:** `_honker_*` → `__alkstore_*` — storage-internal
|
||||
(ADR-008 §4); ADR-010 §8 pre-authorized the fork re-owning names.
|
||||
- **Tests:** honker-core's suites inherited as the floor (watcher
|
||||
lifecycle/failure, savepoint, multiprocess pressure) + the contract-
|
||||
property tests (no-stranded-rows, dead-visible `get_job`, stamps).
|
||||
|
||||
Packaging follows ADR-001's split: the forked substrate is the
|
||||
SQLite engine crate's dependency — vendored as a workspace-family
|
||||
crate (provenance + license recorded), not re-published.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive**
|
||||
|
||||
- The confirmed defect class (D-1..D-5) is owned, fixed, and testable
|
||||
in-tree; no release cadence gates correctness we already know how to
|
||||
fix.
|
||||
- Contract v1's queue depth realizes directly in owned SQL — no
|
||||
two-statement re-stamp bridge, no engine migrations over a
|
||||
dual-owned `_honker_*` table family.
|
||||
- The fork inherits ~4,000 lines of upstream hardening tests plus the
|
||||
watcher machinery the POCs measured as the quality win of the ride
|
||||
posture — most of the fork cost is pre-paid.
|
||||
|
||||
**Negative**
|
||||
|
||||
- We own the SQLite machinery's future: upstream fixes (rare and
|
||||
incremental, but real — the #80/#133 train proves the stream is
|
||||
alive) must be deliberately cherry-picked rather than inherited by
|
||||
`cargo update`.
|
||||
- A vendored workspace-family crate breaks "zero vendored code in the
|
||||
tree by default" (ADR-005's positive consequence) — this is the
|
||||
exception the posture always named, not a renegotiation.
|
||||
|
||||
## References
|
||||
|
||||
- OQ-06 (`docs/architecture/open-questions.md`) — the resolved
|
||||
assessment; `docs/research/quality-read-honker-core.md` — the
|
||||
evidence (published-artifact fact, watcher-core verdict, defect
|
||||
register, fork calculus and scope).
|
||||
- [ADR-005](005-dependency-ownership.md) — the posture and trigger this
|
||||
ADR fires; fork-is-normal-work applies.
|
||||
- [ADR-003](003-sqlite-driver.md) — driver, seam, and watcher
|
||||
architecture (unchanged in ownership; the fork inherits the measured
|
||||
machinery).
|
||||
- [ADR-010](010-queue-semantics-depth.md) — §3a/§5/§1's realization
|
||||
is now owned-code work; §8's naming authorization applies.
|
||||
- [ADR-001](001-crate-split.md) — packaging (engine crate's
|
||||
single-driver substrate).
|
||||
- [engine-sqlite.md](../engine-sqlite.md) — the living spec, updated
|
||||
to the forked substrate.
|
||||
Reference in new issue
Block a user