Files
alkstore/docs/architecture/decisions/001-crate-split.md
T

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