102 lines
4.5 KiB
Markdown
102 lines
4.5 KiB
Markdown
# ADR-001: Reactive-core crate + per-engine crates
|
|
|
|
## Status
|
|
|
|
Accepted *(capability-flags content annotated 2026-10-06 by
|
|
[ADR-016](016-deployment-honesty.md))*
|
|
|
|
## Context
|
|
|
|
The store must present one reactive interface (notify, streams, queues,
|
|
locks, scheduler, outbox) over two backing engines, SQLite and Postgres.
|
|
The engines differ sharply in how much of that surface is natively
|
|
theirs:
|
|
|
|
- The **SQLite** engine rides honker's existing, battle-tested machinery
|
|
(published `honker-core` — a port-and-adapt of a sync library to the
|
|
family's async-facing-trait posture). *(Ownership since resolved:
|
|
the substrate is forked into owned code — [ADR-011](011-sqlite-substrate-fork.md).)*
|
|
- The **Postgres** engine is the build-heavy side: LISTEN/NOTIFY wiring
|
|
and the pg-boss-family queue schema are built by this crate.
|
|
|
|
A single crate with feature-gated engines would force both engines'
|
|
dependency graphs into every downstream binary that enables both
|
|
features. That is not hypothetical: rusqlite 0.40's `libsqlite3-sys`
|
|
link collision with sqlx's sqlite driver is a real constraint
|
|
(see [ADR-003](003-sqlite-driver.md)); single-driver binaries are the
|
|
only clean escape.
|
|
|
|
Scope evidence lives in `docs/research/consumer-inventory.md`; the
|
|
operator decision was recorded 2026-10-04 against
|
|
OQ-ST-02 (`docs/research/phase-0.md`).
|
|
|
|
## Decision
|
|
|
|
The project ships as a **family of crates**:
|
|
|
|
1. **`alkstore` (core)** — the crate carrying the unified trait
|
|
surface, types, error model, capability flags, and the contract
|
|
documentation. No driver dependencies. Compile-lean by construction:
|
|
the base crate has no engine machinery to keep out.
|
|
*(Annotated 2026-10-06: capability flags are not part of this
|
|
contents list as decided — [ADR-016](016-deployment-honesty.md)
|
|
resolves there is no runtime capability surface, by default ever;
|
|
the engine boundary lives at compile time and in the deployment
|
|
matrix.)*
|
|
2. **`alkstore-sqlite`** — the SQLite engine implementing the core
|
|
surface. Single driver: rusqlite + the forked honker-core
|
|
lineage, carried in-tree as the engine crate's substrate module
|
|
subtree ([ADR-003]; ownership per
|
|
[ADR-011](011-sqlite-substrate-fork.md); folded into the engine
|
|
crate per [ADR-013](013-fold-substrate-into-sqlite.md)).
|
|
3. **`alkstore-postgres`** — the Postgres engine implementing the core
|
|
surface. Single driver: tokio-postgres + deadpool-postgres
|
|
([ADR-004]).
|
|
4. **A mem-shaped engine** (in-tree or separate test crate) may exist as
|
|
a third implementation for tests and doctests, if the test story
|
|
turns out to want it. Treated as an implementation convenience, not
|
|
a contract artifact — decided at implementation time, not now.
|
|
|
|
Downstream consumers depend on `alkstore` plus exactly one engine
|
|
crate. A consumer binary links at most one driver.
|
|
|
|
## Consequences
|
|
|
|
**Positive**
|
|
|
|
- The engines' asymmetry of work is structural: the SQLite engine has a
|
|
small, mostly-wiring job; the Postgres engine carries the build-heavy
|
|
LISTEN/queue work. Neither is burdened by the other's dependencies.
|
|
- Any future engine (alkfs's in-tree needs, an ops-surface engine) is
|
|
additive — a new crate implementing the core traits — rather than a
|
|
feature-graph edit to one crate.
|
|
- Core-lean is structural, not a feature-discipline to be enforced by
|
|
review.
|
|
- The libsqlite3-sys link-collision class of problems is eliminated by
|
|
construction (single-driver binaries).
|
|
- Per-engine compilation/test gates are independent.
|
|
|
|
**Negative**
|
|
|
|
- A version-coordination duty: the core's trait surface is a contract
|
|
the engine crates must track. Version bumps in core must be adopted
|
|
by engines in lockstep when the contract changes (minor/major
|
|
discipline; no trait-default drift).
|
|
- Slightly more crate plumbing; naming/publishing overhead.
|
|
- Consumers who want *both* engines in one binary (rare, unsupported-by
|
|
design) cannot get a both-features build today.
|
|
|
|
## References
|
|
|
|
- OQ-ST-02 (`docs/research/phase-0.md`) — the decision record with
|
|
options considered.
|
|
- `docs/research/consumer-inventory.md` — the inventory whose lean
|
|
(single crate) was superseded, with the correction recorded there.
|
|
- [ADR-003](003-sqlite-driver.md) — the SQLite driver choice whose
|
|
link-collision constraint motivates this split.
|
|
- [ADR-004](004-postgres-driver.md) — the Postgres driver choice.
|
|
- OQ-10 (`docs/architecture/open-questions.md`) — trait-versioning
|
|
duties created here.
|
|
[ADR-003]: 003-sqlite-driver.md
|
|
[ADR-004]: 004-postgres-driver.md
|