Files
alkstore/docs/architecture/overview.md
T
glm-5.3-flash 060f262e62 ADR-024 — the mem engine adopted as the family's third engine (wave 6; release readiness renumbered to wave 7)
Row-first gate: consumer-inventory.md gains an engine-tier section — the mem-engine need recorded operator-authority, dated 2026-10-10 (wasm32 sandboxing across the alk protocol family + downstream ffi/napi/python-adapter economics; rusqlite/tokio-postgres structurally out on wasm, so mem is the only triad member the sandbox can carry).

ADR-024 (decisions/024-mem-engine.md) pins the decision set: (1) separate `alkstore-mem` crate — discharges and amends ADR-001 §4 (superseded in part: full contract-v1 engine, not an "implementation convenience"; annotation on ADR-001 §4 + Status, class-1 window still open); (2) honest-ephemeral posture — no durability, single-process, ephemeral by design, never fleet-valid (ADR-010 §3's shared-pool predicate fails structurally), riding ADR-016's carriers unchanged (identity + docs + matrix); (3) full contract v1 tier with the asymmetry classification — `PayloadTooLarge` never produced (SQLite arm), no reconnection concept (reconnect-wake/watcher rows absent from mem's per-engine column), receiver close at engine drop, wake coalescing N/A; (4) `MemStore::new()` engine-native constructor — the one documented exception to the open-prose, core-contract.md Store concept amended; shared-instance (two opens → one engine) rejected with the ADR-016 §4-style re-entry gate (consumer-inventory row), register stays closed; (5) wasm32 — compile-clean for wasm32-unknown-unknown plus the suite's mem column green on host under a current-thread runtime flavor are wave-6 acceptance items; on-target suite execution scoped out with a named collapse condition (wasm-bindgen-test adapter crate) — a scope decision, not a pending-client hedge; (6) mem is not a core dev-dependency — core's doc examples stay mock-based, ADR-001 §4's doctest posture declines.

engine-mem.md (draft): the in-process mapping — guarded per-mechanism state (no pool, no schema bootstrap, no forwarder, no spawn_blocking seam), the tx overlay (staged *_tx effects merged atomically at commit; read-your-own-writes easy, drop-=-rollback trivial; wake-at-commit structural — the seam pg needed pg-fix-tx-wake for, mem pins from birth via the existing tx-commit-atomicity rows), ADR-012 §2 third owner of the curve/opts/@every arithmetic (three-way equivalence, ADR-022's StoreFactory reused verbatim — born pinned).

deployment.md: host-semantics row (single-process, ephemeral, never fleet-valid, wasm32-clean), mem connection-budget subsection (none — nothing to budget), durability-knobs row (the honest row is the absence), toolchain row (wasm32 subset + current-thread-clean, acceptance-cited). README/overview: engine-mem.md row, ADR-024 row, family table entry (alkstore-mem, no driver deps), current-state updated to the implementation phase with engine specs' stable statuses reflected.

implementation.md: wave table gains wave 6 (mem engine, depends waves 1 + 5) and renumbers release readiness to wave 7 (fuzzing decision — the one remaining decided-at-implementation deferral — rides wave 7); wave-6 section records the born-pinned posture, acceptance items, the one suite-harness pre-task (past_stamp_sleep blocking sleep → async sleep, review 003's properties.rs:1683 note), and the window riders (review 003 Finding 1: the pg transient-fault seam, MEDIUM, rides wave 6; Findings 2–3 follow their park into wave 7's pre-release); wave-6 review gate defined; Decided points updated (mem discharged, fuzzing renumbered); stale wave-6 references swept across review docs and the landed tasks' notes (release-readiness items renumbered or annotated).

Docs-only change; verified by cross-reference audit (all ADR/OQ/anchor references resolve, residual wave-6 mentions are correct under the new numbering or carry dated annotations).
2026-10-10 09:42:40 +00:00

7.7 KiB


status: draft last_updated: 2026-10-10 (ADR-024 — the mem engine joins the crate family as alkstore-mem; family/ADR tables updated)

alkstore — Overview

One reactive store interface over SQLite, Postgres, and the in-process mem engine: durable notify/subscribe signals, streams with per-consumer offsets, durable queues with the transactional enqueue property, named locks, a scheduler, and an outbox helper — with each engine using its own native machinery underneath (SQLite: honker's watcher design; Postgres: pg_notify/LISTEN and the pg-boss schema family; mem: guarded in-process state, ephemeral by design — ADR-024).

Why this crate exists

The alk* ecosystem's current shape is a repository pattern with a default in-memory adapter, cache-invalidation wiring in hot paths, and per-project approximations where a durable reactive substrate was needed. alkblobs paused partly on that fuzziness. alkstore is the substrate, made once: the answer to "how does a change in the database become visible to other processes/connections?" that downstream stores don't re-derive.

Crate family

Per ADR-001:

Crate Contents Driver dependencies
alkstore (core) trait surface, types, error model none (no capability surface — ADR-016: engine differences are compile-time identity + the deployment matrix, never a runtime descriptor)
alkstore-sqlite SQLite engine (ADR-003) rusqlite; the forked honker-core lineage rides in-tree as the engine crate's substrate module subtree (ADR-011, designed in ADR-012, folded per ADR-013)
alkstore-postgres Postgres engine (ADR-004) tokio-postgres, deadpool-postgres
alkstore-mem mem engine — full contract v1, honest-ephemeral (no durability, single-process, never fleet-valid; ADR-024) none (tokio sync + time only; the wasm32-clean member of the family)

Downstream consumers depend on core + exactly one engine. Family standards apply throughout: tokio async runtime, thiserror errors, no panics in library code, no unwrap()/expect() outside tests, lean base crate.

Feature surface

Per ADR-002:

  • First-class: notify/listen; streams.
  • In scope: named locks; queues + outbox helper; scheduler.
  • Cut-flag: rate limits; result storage.
  • Out: loadable-extension surface; DAGs/task chains/chords/multi-writer replication/cross-machine locking.

Document map

Doc Purpose
core-contract.md The unified trait surface: mechanisms, delivery guarantees, tx seam, naming
engine-sqlite.md SQLite engine: mapping the contract onto the forked substrate module/rusqlite
engine-postgres.md Postgres engine: mapping the contract onto tokio-postgres/LISTEN
engine-mem.md Mem engine: mapping the contract onto guarded in-process state (ADR-024)
queues.md Queue/scheduler/outbox semantics depth (ADR-009/ADR-010 resolved)
deployment.md Host capabilities, connection budgets, deployment matrix (OQ-08 resolved)
open-questions.md OQ-01..NN tracker
decisions/ ADRs

What is decided (ADR index)

ADR Decision Status
001 Reactive-core + per-engine crates Accepted
002 Feature scope (inventory-confirmed) Accepted
003 SQLite: rusqlite + honker-core lineage, bridged seam (ownership: ADR-011) Accepted
004 Postgres: tokio-postgres + deadpool, hand-rolled LISTEN Accepted
005 Published libraries by default, named fork triggers Accepted
006 Opaque wake + re-read; notify-vs-streams guarantee split Accepted
007 Caller-held TxHandle with *_tx methods Accepted
008 Contract v1 surface pinning (partition, TxHandle shape, wake type, reserved strings, error taxonomy) Accepted
009 Scheduler collapse (queues + schedule(), @every-only) Accepted
010 Queue semantics depth (visibility, backoff, dead-letter, sweep, layout) Accepted
011 SQLite substrate — fork honker-core into owned code Accepted
012 Forked substrate design (contract-blind boundary, fidelity, port deltas) Accepted
013 Fold the forked substrate into alkstore-sqlite (no fourth crate) Accepted
014 Transactional outbox enqueue (outbox_enqueue_tx on TxHandle) Accepted
015 Streams depth (carried-metadata keys, global-FIFO ordering, StreamEvent, trim_to) Accepted
016 Deployment honesty (no runtime capability surface; compile-time identity + matrix) Accepted
017 Contract versioning (core crate's semver is the contract version; change classes, pairing carriers, lockstep duties) Accepted
018 Substrate provenance register and cherry-pick procedure (PROVENANCE.md in-tree, per-delta entries) Accepted
019 Mechanism-handle surfaces (handle traits, Job/Schedule shapes, worker_id, StopToken) Accepted
020 Enqueue-option semantics (delay/run_at, expires, scheduler stamp source, payload encoding) Accepted
021 Third review round (tx-read methods on TxHandle, Job.claimed_at, schedule() queue-argument validation, drop = rollback, receiver close/error arms) Accepted
022 Contract-suite layout (shared internal suite crate, store-factory parameterization) Accepted
024 The mem engine (alkstore-mem — full contract v1, honest-ephemeral, wasm32 compile-clean acceptance) Accepted

Non-goals

  • Not a database abstraction/ORM: the store covers the reactive coordination surface, not general row storage (consumers keep their own engines/schema for business data, sharing the connection when appropriate — the outbox pattern).
  • Not a network service: no transport; any networked ops surface rides alkcall and is a separate future decision (store layer stays substrate-free, the alkblobs store-layer precedent).
  • Not multi-machine on SQLite: single-host honesty is inherited (deployment.md; the boundary's location in the surface is decided — ADR-016).

Evidence base

Phase 0 (docs/research/phase-0.md) is complete: two POCs (poc-sqlite-posture-findings.md, poc-pg-posture-findings.md) passed all gate conditions; the consumer inventory (consumer-inventory.md) graded every feature row. The Phase 1 architecture work runs over that complete evidence base; open Phase 1 work is tracked in open-questions.md.