ADR-016: deployment honesty — no runtime capability surface; compile-time identity + matrix (OQ-08 resolved)
This commit is contained in:
1 parent
8c4ec48f92
commit
8c8fec5cb8
12 files changed
+494
-72
No files matched your search
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# alkstore — Architecture
|
||||
@@ -24,11 +24,11 @@ pending architecture review and OQ resolution.
|
||||
| Doc | Status | Purpose | Key OQs |
|
||||
|---|---|---|---|
|
||||
| [overview.md](overview.md) | draft | Crate family, feature surface, non-goals, evidence base | — |
|
||||
| [core-contract.md](core-contract.md) | draft | The unified trait surface, delivery guarantees, tx seam | OQ-08, OQ-10 |
|
||||
| [core-contract.md](core-contract.md) | draft | The unified trait surface, delivery guarantees, tx seam | OQ-10 |
|
||||
| [engine-sqlite.md](engine-sqlite.md) | draft | SQLite engine: forked-substrate/rusqlite mapping | OQ-06 (resolved), OQ-12 (resolved), OQ-13 (resolved) |
|
||||
| [engine-postgres.md](engine-postgres.md) | draft | Postgres engine: tokio-postgres/LISTEN mapping | OQ-08, OQ-12 (resolved), OQ-13 (resolved) |
|
||||
| [engine-postgres.md](engine-postgres.md) | draft | Postgres engine: tokio-postgres/LISTEN mapping | OQ-08 (resolved), OQ-12 (resolved), OQ-13 (resolved) |
|
||||
| [queues.md](queues.md) | draft | Queue/scheduler/outbox semantics depth (resolved: ADR-009/ADR-010) | OQ-06 (resolved) |
|
||||
| [deployment.md](deployment.md) | draft | Host semantics, connection budgets, knobs, matrix | OQ-08 |
|
||||
| [deployment.md](deployment.md) | draft | Host semantics, connection budgets, knobs, matrix | OQ-08 (resolved) |
|
||||
| [open-questions.md](open-questions.md) | draft | OQ tracker (promoted from OQ-ST register) | — |
|
||||
|
||||
## Architecture Decision Records
|
||||
@@ -50,6 +50,7 @@ pending architecture review and OQ resolution.
|
||||
| [013](decisions/013-fold-substrate-into-sqlite.md) | Fold the forked substrate into `alkstore-sqlite` — no fourth crate | Accepted |
|
||||
| [014](decisions/014-outbox-tx-enqueue.md) | Transactional outbox enqueue — `outbox_enqueue_tx` on the `TxHandle` trait | Accepted |
|
||||
| [015](decisions/015-streams-depth.md) | Streams depth — carried-metadata keys, global-FIFO ordering row, `StreamEvent` shape, `publish_with_key_tx`, `trim_to` | Accepted |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty — no runtime capability surface; compile-time engine identity + documented matrix | Accepted |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -58,7 +59,6 @@ Phase 0 register's OQ-ST-01..08 promote one-to-one — OQ-NN mirrors
|
||||
OQ-ST-NN — with new Phase 1 questions appended after). Open, in
|
||||
suggested resolution order:
|
||||
|
||||
- **OQ-08** (medium): capability-surface shape.
|
||||
- **OQ-10** (medium): contract versioning across engine crates.
|
||||
- **OQ-11** (medium): forked-substrate follow-through (provenance
|
||||
register format, cherry-pick procedure; item (1) dissolved by
|
||||
@@ -72,7 +72,9 @@ Resolved (kept with resolutions): OQ-01 (feature scope), OQ-02
|
||||
scheduler guarantee row pinned), ~~OQ-05~~ (queue semantics depth —
|
||||
[ADR-010](decisions/010-queue-semantics-depth.md)), ~~OQ-06~~
|
||||
(honker-core quality read — fork fired,
|
||||
[ADR-011](decisions/011-sqlite-substrate-fork.md)), ~~OQ-13~~
|
||||
[ADR-011](decisions/011-sqlite-substrate-fork.md)), ~~OQ-08~~
|
||||
(capability-surface shape — none, by default ever;
|
||||
[ADR-016](decisions/016-deployment-honesty.md)), ~~OQ-13~~
|
||||
(transactional outbox enqueue shape —
|
||||
[ADR-014](decisions/014-outbox-tx-enqueue.md)), ~~OQ-12~~ (streams
|
||||
depth — [ADR-015](decisions/015-streams-depth.md)).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# Core contract
|
||||
@@ -20,7 +20,12 @@ joins the `TxHandle` trait, and by
|
||||
semantics, `StreamEvent` shape, the ordering row, `trim_to`,
|
||||
and `publish_with_key_tx`); ADR-009/ADR-010 add the first *post-v1
|
||||
contract extensions* (scheduler collapse surface, `QueueOpts` depth —
|
||||
versioning discipline for such extensions is OQ-10's); the
|
||||
versioning discipline for such extensions is OQ-10's);
|
||||
[ADR-016](decisions/016-deployment-honesty.md) decides the parked
|
||||
capability-surface question: **none, by default ever** — engine
|
||||
differences surface at compile time (engine-crate identity) and in
|
||||
the [deployment matrix](deployment.md), never as a runtime
|
||||
descriptor; the
|
||||
*obligations* are this document.
|
||||
|
||||
## Concepts
|
||||
@@ -122,8 +127,11 @@ never sees it.
|
||||
trip, verified by POC #2); no limit on SQLite. The error variant is
|
||||
contract-wide (callers match it identically on both engines), the
|
||||
*occurrence* is the documented engine asymmetry
|
||||
([ADR-008](decisions/008-contract-v1-pinning.md) §5) — see also
|
||||
OQ-08.
|
||||
([ADR-008](decisions/008-contract-v1-pinning.md) §5) — with no
|
||||
capability surface
|
||||
([ADR-016](decisions/016-deployment-honesty.md)), this variant is
|
||||
the one runtime carriage of an engine asymmetry; its occurrence
|
||||
asymmetry is pinned in the verification backlog below.
|
||||
- `listen(channel) -> Box<dyn WakeReceiver>` — starts from "now";
|
||||
delivers opaque `Wake { channel }` signals
|
||||
([ADR-006](decisions/006-wake-and-delivery-contract.md)), never
|
||||
@@ -371,10 +379,16 @@ state (`get_job`), not an error.
|
||||
|
||||
### Capability surface
|
||||
|
||||
None in contract v1. Whether the `Store` exposes engine capabilities
|
||||
at all — and if so, which (payload limits, host semantics,
|
||||
wake-cadence knobs) — is OQ-08's decision
|
||||
([deployment.md](deployment.md)).
|
||||
None — decided by
|
||||
[ADR-016](decisions/016-deployment-honesty.md) (2026-10-06): `Store`
|
||||
carries no capabilities accessor, in v1 and by default ever. The
|
||||
honest single-host/multi-host boundary lives at compile time (the
|
||||
engine-crate dependency *is* the deployment statement —
|
||||
[ADR-001](decisions/001-crate-split.md)'s single-driver binaries) and
|
||||
in [deployment.md](deployment.md)'s matrix. Runtime carriage of the
|
||||
one caller-actionable engine asymmetry is the contract-wide
|
||||
matchable `PayloadTooLarge` variant (Errors above); re-entry requires
|
||||
a consumer-inventory row naming a runtime-adapt need.
|
||||
|
||||
### Naming / reserved namespace
|
||||
|
||||
@@ -471,6 +485,14 @@ before the engine specs are called `stable`:
|
||||
keyed event row with the business write (no ghost event); commit
|
||||
makes it visible to `read_since`/`subscribe`; empty-`Some`-key
|
||||
`InvalidName` on both engines' tx paths.
|
||||
- **`PayloadTooLarge` occurrence asymmetry** ([ADR-016](decisions/016-deployment-honesty.md)
|
||||
§5) — with no capability surface, `PayloadTooLarge` is the one
|
||||
runtime carriage of an engine asymmetry, so its matchability pins
|
||||
in the suite: an oversized `notify`/`notify_tx` payload is rejected
|
||||
client-side by the Postgres engine before any round trip (the
|
||||
limit in the variant), and the SQLite engine never produces the
|
||||
variant at any size — engine-agnostic code writes the same match
|
||||
on both engines and the non-occurring arm simply never fires.
|
||||
- **`trim_to` semantics on both engines** ([ADR-015](decisions/015-streams-depth.md)
|
||||
§5) — exact-boundary trim (`<=`), surviving rows keep their offsets
|
||||
(gaps legal, never renumbered), reads resume at the trim horizon's
|
||||
@@ -493,6 +515,7 @@ before the engine specs are called `stable`:
|
||||
| [012](decisions/012-forked-substrate-design.md) | Fork design | contract-blind substrate boundary; engine-side formula arithmetic pinned equivalent by the contract suite |
|
||||
| [014](decisions/014-outbox-tx-enqueue.md) | Outbox tx enqueue (amends 008) | `outbox_enqueue_tx` on `TxHandle`; outbox-name validation; derived backing queue reached only through the outbox surface |
|
||||
| [015](decisions/015-streams-depth.md) | Streams depth (amends 006/008) | key = carried metadata, global-FIFO ordering row, `StreamEvent` shape, `publish_with_key_tx`, `trim_to` |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty (decides 008's parked question) | no runtime capability surface — compile-time engine identity + documented matrix; `PayloadTooLarge` occurrence asymmetry pinned |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -502,11 +525,12 @@ questions affecting this document:
|
||||
|
||||
- **OQ-10**: contract versioning discipline across engine crates
|
||||
([open](open-questions.md))
|
||||
- **OQ-08**: capability-surface shape ([open](open-questions.md))
|
||||
|
||||
Resolved on this document's surface: **OQ-09** (scheduler collapse —
|
||||
[ADR-009](decisions/009-scheduler-collapse.md)), **OQ-05** (queue
|
||||
semantics depth — [ADR-010](decisions/010-queue-semantics-depth.md)),
|
||||
**OQ-13** (transactional outbox enqueue shape —
|
||||
[ADR-014](decisions/014-outbox-tx-enqueue.md)), and **OQ-12** (streams
|
||||
depth — [ADR-015](decisions/015-streams-depth.md)), 2026-10-05.
|
||||
[ADR-014](decisions/014-outbox-tx-enqueue.md)), **OQ-12** (streams
|
||||
depth — [ADR-015](decisions/015-streams-depth.md)), and **OQ-08**
|
||||
(capability-surface shape — none, by default ever;
|
||||
[ADR-016](decisions/016-deployment-honesty.md)), 2026-10-05/06.
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
Accepted *(capability-flags content annotated 2026-10-06 by
|
||||
[ADR-016](016-deployment-honesty.md))*
|
||||
|
||||
## Context
|
||||
|
||||
@@ -37,6 +38,11 @@ The project ships as a **family of crates**:
|
||||
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
|
||||
|
||||
@@ -106,6 +106,9 @@ consumer-inventory-row-gated extension — not assumed now.
|
||||
queues), never on engine type (guiding principle 4; the honest
|
||||
single/multi-host line is [deployment.md]'s and OQ-08's, not this
|
||||
contract's).
|
||||
*(OQ-08 resolved 2026-10-06 by
|
||||
[ADR-016](016-deployment-honesty.md): nowhere at
|
||||
runtime — compile-time engine identity + the documented matrix.)*
|
||||
|
||||
**Negative**
|
||||
|
||||
|
||||
@@ -94,7 +94,10 @@ implement identically):
|
||||
`schedule()`) — OQ-09 decides; the scheduler surface (if any) is not
|
||||
part of contract v1.
|
||||
- **Capability flags** — OQ-08 decides whether `Store` exposes them at
|
||||
all; v1 has no capability surface.
|
||||
all; v1 has no capability surface. *(Resolved 2026-10-06 by
|
||||
[ADR-016](016-deployment-honesty.md): no capability surface — by
|
||||
default ever; the boundary is compile-time engine identity +
|
||||
deployment.md's matrix.)*
|
||||
- **`claim_waker`** — dropped from the contract surface; wake-driven
|
||||
claim is the engine's consumption posture
|
||||
([engine-postgres.md](../engine-postgres.md)'s LISTEN-driven claim),
|
||||
@@ -311,6 +314,10 @@ elsewhere, cancelled); `try_lock` returning `Option<Lock>`; lock
|
||||
constructor's own obligation — a `Store` handed out by an engine
|
||||
crate honors the full v1 surface.
|
||||
- No capability surface in v1 (OQ-08 owns whether one ever exists).
|
||||
*(Resolved 2026-10-06 by [ADR-016](016-deployment-honesty.md): by
|
||||
default never — the engine choice stays a dependency-graph fact;
|
||||
`PayloadTooLarge` is the one runtime carriage of an engine
|
||||
asymmetry.)*
|
||||
- Consumer code stays engine-agnostic by depending on core and being
|
||||
constructed by exactly one engine crate (ADR-001's single-driver
|
||||
binaries) — the engine choice is a dependency-graph fact, not a
|
||||
@@ -410,9 +417,12 @@ prefix, §4).
|
||||
reused after commit (callers re-`begin_tx`) — matches the
|
||||
caller-owned lifetime the POCs verified, but is stricter than
|
||||
honker's re-usable `&Transaction` style.
|
||||
- OQ-05/OQ-09/OQ-08 remain open: this ADR deliberately does not pin
|
||||
queue depth, the scheduler shape, or capability flags; the v1
|
||||
additions to those surfaces will be later contract extensions.
|
||||
- OQ-05/OQ-09/OQ-08 remained open here: this ADR deliberately did not
|
||||
pin queue depth, the scheduler shape, or capability flags; the v1
|
||||
additions to those surfaces were later contract decisions.
|
||||
*(OQ-05/OQ-09 resolved by [ADR-010](010-queue-semantics-depth.md)/
|
||||
[ADR-009](009-scheduler-collapse.md); OQ-08 resolved 2026-10-06 by
|
||||
[ADR-016](016-deployment-honesty.md) — none, by default ever.)*
|
||||
|
||||
## References
|
||||
|
||||
@@ -432,5 +442,7 @@ prefix, §4).
|
||||
[ADR-006](006-wake-and-delivery-contract.md) (wake contract,
|
||||
namespace existence, guarantee table),
|
||||
[ADR-007](007-transactional-seam.md) (tx seam mechanics).
|
||||
- OQ-09 (scheduler row transfer), OQ-08 (capability surface), OQ-10
|
||||
- OQ-09 (scheduler row transfer), OQ-08 (capability surface —
|
||||
resolved by [ADR-016](016-deployment-honesty.md), no runtime
|
||||
surface), OQ-10
|
||||
(versioning discipline for future contract extensions).
|
||||
@@ -0,0 +1,302 @@
|
||||
# ADR-016: Deployment honesty — no runtime capability surface; the boundary is compile-time identity + the documented matrix
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (2026-10-06, Phase 1 — OQ-08's resolution; decides the
|
||||
capability-surface question [ADR-008](008-contract-v1-pinning.md)
|
||||
§1/§6 deliberately left open; the contract surface is unchanged by
|
||||
this ADR except one verification-backlog row and the annotations this
|
||||
resolution hangs on ADR-001/ADR-008)
|
||||
|
||||
## Context
|
||||
|
||||
The two engines' host postures are facts, decided since Phase 0:
|
||||
|
||||
- **Postgres is natively multi-host** — POC #2 verified no
|
||||
single-host assumption anywhere (`poc-pg-posture-findings.md`
|
||||
"OQ-ST-08": the property tests ran all-through-network over the
|
||||
docker bridge; the listener/wake machinery is per-process,
|
||||
connection-based — [ADR-004](004-postgres-driver.md)).
|
||||
- **SQLite is single-machine by nature** — file-backed; NFS
|
||||
two-writers unsupported (honker's honesty posture —
|
||||
`/workspace/honker` @ f4e53c6, `README.md` "Honker is
|
||||
single-machine and file-backed... two servers writing the same
|
||||
`.db` over NFS is not a Honker deployment strategy"), inherited by
|
||||
the substrate at the fork
|
||||
([ADR-003](003-sqlite-driver.md),
|
||||
[ADR-011](011-sqlite-substrate-fork.md)); cross-process *on one
|
||||
host* is verified ground (`data_version` is cross-process by
|
||||
nature).
|
||||
|
||||
[deployment.md](../deployment.md) carries these facts as a matrix
|
||||
(host semantics, connection budgets, durability knobs, toolchain
|
||||
notes). OQ-08 owns the *trait-surface* half: the unified surface must
|
||||
not pretend SQLite is multi-host — where does that honesty live?
|
||||
Three options were framed there:
|
||||
|
||||
1. **Compile-time only** — the consumer picks an engine crate at
|
||||
dependency time; the engine's docs carry its deployment facts.
|
||||
Smallest contract; nothing runtime to match on.
|
||||
2. **`Store::capabilities()`** — a runtime description (payload
|
||||
limits, wake-cadence knobs, host semantics). Lets a consumer
|
||||
adapt, but adds a contract surface all engines must keep honest.
|
||||
3. **Deployment matrix only** — no API surface; the document holds
|
||||
the facts.
|
||||
|
||||
The constraint set is fixed by decisions already made:
|
||||
|
||||
- **The engine choice is a dependency-graph fact.** Single-driver
|
||||
binaries ([ADR-001](001-crate-split.md)): a consumer depends on
|
||||
core plus exactly one engine crate; constructors and their options
|
||||
live in engine crates ([ADR-008](008-contract-v1-pinning.md) §6) —
|
||||
"the engine choice is a dependency-graph fact, not a runtime
|
||||
branch."
|
||||
- **Consumer code never branches on engine type** (guiding principle
|
||||
4, phase-0 §Vision; [ADR-006](006-wake-and-delivery-contract.md)'s
|
||||
positive consequence: consumer code branches on *mechanism choice*,
|
||||
never on engine type).
|
||||
- **Contract v1's guarantees are engine-uniform.** The delivery
|
||||
table ([ADR-006](006-wake-and-delivery-contract.md) §2) and its
|
||||
extensions (locks — ADR-008 §7; scheduler —
|
||||
[ADR-009](009-scheduler-collapse.md) §4; streams ordering —
|
||||
[ADR-015](015-streams-depth.md) §4) pin identical contract text for
|
||||
both engines. The engines' genuine *behavioral* differences (wake
|
||||
coalescing vs per-notify, the pg no-replay hole and its
|
||||
reconnect-wake recovery, the SQLite writer-slot parking) are
|
||||
documented engine notes, not guarantee deltas — even the
|
||||
scheduler's leadership is engine-uniform (the leadership lock is
|
||||
the efficiency layer that runs on both engines; ADR-009 §4).
|
||||
- **No consumer row names a runtime-adapt need.** The consumer
|
||||
inventory (`docs/research/consumer-inventory.md`) names
|
||||
coordination needs — commit-atomic notify, offset replay,
|
||||
at-least-once work, TTL locks — not introspection needs. And the
|
||||
starting artifact has nothing to rename either: honker carries its
|
||||
honesty in prose, not an API (no capability surface exists anywhere
|
||||
in the honker-rs surface at the reference revision; no
|
||||
capability-surface row exists in ADR-008 §8's rename-table pattern
|
||||
to inherit or rename).
|
||||
- **No spec-side placeholder remains.** ADR-008 §1/§6 pinned "no
|
||||
capability surface in v1" and deferred the *whether-ever* question
|
||||
to this OQ; core-contract.md's capability-surface section and
|
||||
deployment.md's options frame held the question open. Both engines
|
||||
are POC-verified (so nothing here gates implementation), the
|
||||
contract's shape is fully pinned (so the trait constrains where a
|
||||
capability difference could surface), and OQ-13/OQ-12's resolutions
|
||||
completed the surface without needing one.
|
||||
|
||||
## Decision
|
||||
|
||||
### 1. No runtime capability surface — options 1 and 3 are the resolution, and they compose
|
||||
|
||||
`Store` carries **no capabilities accessor — in v1 and by default
|
||||
ever**. The honest single-host/multi-host boundary lives in the two
|
||||
places it is already true:
|
||||
|
||||
- **Compile-time identity (option 1).** The engine crate a binary
|
||||
depends on *is* the deployment statement: `alkstore-sqlite`'s
|
||||
identity says single-machine (its docs carry the NFS two-writers
|
||||
boundary and the cross-process-on-one-host ground);
|
||||
`alkstore-postgres`'s says multi-host native (its docs carry the
|
||||
listener budget line, `max_size + 1`, and the co-tenancy posture).
|
||||
A dependency edge cannot drift out of sync with the truth it
|
||||
states; a runtime struct can.
|
||||
- **The documented matrix (option 3).**
|
||||
[deployment.md](../deployment.md) is the ops-facing document of
|
||||
record for the facts a deployer needs — host semantics, connection
|
||||
budgets, durability knobs, toolchain floors — the matrix's tables
|
||||
are unchanged; this ADR only resolves its open frame.
|
||||
|
||||
The three options were framed as rivals, but options 1 and 3 are one
|
||||
posture at two altitudes (engine-crate docs serve the consumer
|
||||
choosing the dependency; the deployment matrix serves the operator
|
||||
choosing the topology) — the fork in the road was only ever *option 2
|
||||
vs both of them*. Decided: **no runtime surface.**
|
||||
|
||||
### 2. Why capability flags are rejected
|
||||
|
||||
A capabilities struct earns each field only if a caller can act
|
||||
differently on it — [ADR-008](008-contract-v1-pinning.md) §5's
|
||||
act-differently rule (pinned for error variants) generalized to
|
||||
surface. Field by field:
|
||||
|
||||
- **Host semantics** (`single_host` / `multi_host`): no in-process
|
||||
action exists. Knowing the boundary cannot make SQLite multi-host;
|
||||
the topology is decided in the same act that chooses the engine
|
||||
crate, before any `Store` exists. A flag would invite the exact
|
||||
branch principle 4 bans — `match caps.host { MultiHost => …,
|
||||
SingleHost => … }` in generic code is engine-type branching with a
|
||||
contract-sanctioned hook, and unlike the sanctioned branching
|
||||
(notify vs streams vs queues — the consumer's mechanism choice),
|
||||
it has no mechanism decision behind it to branch *for*. The
|
||||
mechanism handles are the only per-engine difference surface the
|
||||
pinned trait retains, and ADR-008 pins even those uniform.
|
||||
- **Payload limits** (`notify_payload_limit`): the one asymmetry a
|
||||
caller can genuinely act on — and its runtime surface is *already
|
||||
pinned*: `PayloadTooLarge` is a universal taxonomy variant carrying
|
||||
the limit, produced pg-side, contract-wide matchable (ADR-008 §5).
|
||||
The error **is** the honest runtime descriptor for this capability;
|
||||
a `capabilities()` field would duplicate it as a second normative
|
||||
home — the one-owner discipline
|
||||
([ADR-012](012-forked-substrate-design.md) §2's formula rule)
|
||||
applies to it identically.
|
||||
- **Wake cadence knobs**: engine options at open
|
||||
([ADR-008](008-contract-v1-pinning.md) §6) — engine-crate
|
||||
configuration, not contract description; restating them in a
|
||||
returned struct would add a second normative home to the config
|
||||
split §6 pinned.
|
||||
- **Connection budgets / durability knobs / toolchain floors**:
|
||||
deployer-time and build-time facts (deployment.md's tables) — they
|
||||
describe things decided *before the process runs*; nothing a
|
||||
running caller branches on.
|
||||
|
||||
Under all of it: **no consumer row names the need.** Every
|
||||
inventory row's need is already served by engine-uniform contract
|
||||
text; real runtime machinery — a descriptor all engines must keep
|
||||
honest forever and every future engine addition must grow — for an
|
||||
unnamed need is exactly the scope discipline
|
||||
[ADR-002](002-feature-scope.md) exists to enforce. The cost
|
||||
asymmetry seals it: a capabilities surface is a *promise* (every
|
||||
field honest on every engine, forever, plus a versioning surface for
|
||||
OQ-10 to govern) against a need named by no row; the compile-time +
|
||||
docs posture has zero incremental surface and zero drift risk.
|
||||
|
||||
### 3. What "must not pretend" then means, concretely
|
||||
|
||||
The honesty obligation OQ-08 posed resolves into three standing
|
||||
statements rather than one API:
|
||||
|
||||
1. **Contract text**: no guarantee row distinguishes hosts; where the
|
||||
engines genuinely differ in a caller-observable way, the error
|
||||
taxonomy carries it (`PayloadTooLarge` — universal variant,
|
||||
pg-occurrence documented) rather than a flags descriptor. This is
|
||||
the contract suite's business too — the backlog gains one row
|
||||
pinning the occurrence asymmetry (§5 below).
|
||||
2. **Engine-crate docs**: the engine's identity prose carries its
|
||||
posture (SQLite: single-machine, NFS two-writers unsupported,
|
||||
one-host cross-process supported; Postgres: multi-host native,
|
||||
the listener budget, co-tenancy expected). `Store::open`'s
|
||||
documented signature *is* the interface a deployer meets before
|
||||
any `Store` exists ([ADR-008](008-contract-v1-pinning.md) §6).
|
||||
3. **The deployment matrix**: the ops-facing document of record,
|
||||
unchanged — this ADR only resolves its open frame.
|
||||
|
||||
The *misconfiguration* case is handled by the family's established
|
||||
posture, not by detection: a SQLite database file operated as a
|
||||
multi-writer network share is a **deployment violation the crate
|
||||
cannot honestly observe** — the same shape as alkblobs'
|
||||
deployment-verified invariants ("the constructor cannot prove
|
||||
cross-node truth, the deployment asserts it, and the detection
|
||||
symptom is documented" — `/workspace/@alkdev/alkblobs` @ 7b9d904,
|
||||
`docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md`
|
||||
§3, fleet mode as a constructor declaration). The crate's duty is honesty where the deployer reads:
|
||||
document the boundary in the engine-crate docs and the matrix, and
|
||||
never fabricate runtime machinery that *pretends* to detect it. What
|
||||
the constraint rules out is the *contract claiming* a posture —
|
||||
that claim would have been the pretense. A documented boundary,
|
||||
backed by a compile-time engine choice that cannot silently disagree
|
||||
with the deployment, is the honesty.
|
||||
|
||||
### 4. Explicit rejections and the re-entry gate
|
||||
|
||||
- **No `Store::capabilities()`** — §2.
|
||||
- **No `engine_name()` / debug accessor** — the dependency name is
|
||||
the compile-time fact; a runtime string restating it adds surface
|
||||
with no consumer row behind it, and engine-agnostic code — the
|
||||
only code the contract governs — is defined *not* to care.
|
||||
- **No `#[cfg]`-style capability features** — the engine-crate split
|
||||
([ADR-001](001-crate-split.md)) *is* the compile-time mechanism,
|
||||
already working; a feature gate parallel to it would be a second
|
||||
engine-selection axis to keep honest.
|
||||
- **Re-entry gate**: a consumer-inventory row naming a runtime-adapt
|
||||
need — a generic, engine-agnostic consumer that must *act*
|
||||
differently per engine at runtime, with the action named. Until
|
||||
then, capability introspection is out of the contract's future as
|
||||
well as its v1: OQ-10's versioning discipline has one less surface
|
||||
class to govern, and a future engine stays purely additive without
|
||||
a descriptor to grow.
|
||||
|
||||
### 5. Verification backlog addition
|
||||
|
||||
- **`PayloadTooLarge` occurrence asymmetry pinned in the contract
|
||||
suite** — with no capabilities API, the error variant is the *only*
|
||||
runtime carriage of an engine asymmetry, so the suite pins it: pg
|
||||
rejects an oversized `notify`/`notify_tx` payload client-side
|
||||
before any round trip (POC #2's payload boundary); SQLite never
|
||||
produces the variant at any size. The property is the variant's
|
||||
*matchability*: engine-agnostic code writes the same match on both
|
||||
engines and the non-occurring arm simply never fires.
|
||||
|
||||
No other new rows — the boundary decision adds nothing surface to
|
||||
test (there is none); the engines' cross-engine uniformity is the
|
||||
existing backlog's business, unchanged.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive**
|
||||
|
||||
- The trait surface stays exactly as pinned — zero methods, zero
|
||||
types added; ADR-008 §1/§6's "no capability surface" line
|
||||
graduates from deferred question to pinned answer with no code
|
||||
weight either way.
|
||||
- Principle 4 keeps its only sanctioned branching: mechanism choice.
|
||||
Engine-agnostic consumer code has no hook inviting an engine
|
||||
branch, and a future engine stays purely additive — one more
|
||||
crate implementing the traits, no descriptor to grow (the
|
||||
ADR-001/ADR-008 positive consequence, unweakened).
|
||||
- OQ-10's versioning discipline has no capability struct to track;
|
||||
the contract's governable surface is the smaller for this.
|
||||
- One normative home per class of engine-difference fact: the
|
||||
compile-time identity (deployment statement), engine-crate docs
|
||||
(the engine's posture), deployment.md's matrix (ops facts) — each
|
||||
at one altitude, none duplicated in a runtime struct.
|
||||
|
||||
**Negative**
|
||||
|
||||
- A consumer who wants runtime introspection (a generic store-level
|
||||
broker adapting to payload limits *without* reading the typed
|
||||
error) has no in-contract means — they rely on `PayloadTooLarge`
|
||||
matchability or learn the engine at build time. No named consumer
|
||||
carries this cost today; the re-entry gate is the relief valve.
|
||||
- The misconfiguration case (SQLite treated as shared network
|
||||
storage) relies on documentation, not detection — the honest
|
||||
posture, but a deployer who ignores the docs gets the failure
|
||||
symptom the matrix documents, not an API error.
|
||||
|
||||
## References
|
||||
|
||||
- OQ-08 (`docs/architecture/open-questions.md`) — this ADR's
|
||||
resolution; the option set framed in deployment.md.
|
||||
- [deployment.md](../deployment.md) — the facts (host semantics,
|
||||
budgets, knobs) and the options list this decision resolves.
|
||||
- [ADR-001](001-crate-split.md) — single-driver binaries; the
|
||||
dependency-graph fact the boundary's compile-time half rides
|
||||
(item 1 annotated: capability flags dropped from the core crate's
|
||||
contents list).
|
||||
- [ADR-008](008-contract-v1-pinning.md) — §1/§6 (the partition that
|
||||
parked the question; the config split; "the engine choice is a
|
||||
dependency-graph fact, not a runtime branch"), §5 (the
|
||||
act-differently rule generalized in §2; `PayloadTooLarge`, the one
|
||||
runtime-visible asymmetry).
|
||||
- [ADR-006](006-wake-and-delivery-contract.md) — engine-uniform
|
||||
guarantee rows; the never-branch-on-engine-type statement and the
|
||||
note that the trait's shape constrains where capability
|
||||
differences can surface (resolved: nowhere).
|
||||
- [ADR-009](009-scheduler-collapse.md) §4,
|
||||
[ADR-015](015-streams-depth.md) §4 — the later guarantee-row
|
||||
extensions checked for engine-uniformity (scheduler leadership is
|
||||
uniform; the ordering row is uniform).
|
||||
- [ADR-012](012-forked-substrate-design.md) — §2's
|
||||
one-normative-owner rule (§2's field reasoning); the honesty
|
||||
posture the substrate inherits.
|
||||
- POC findings: `docs/research/poc-pg-posture-findings.md`
|
||||
("OQ-ST-08: the pg engine is natively multi-host");
|
||||
`docs/research/poc-sqlite-posture-findings.md` (single-machine
|
||||
ground).
|
||||
- Honker's prose honesty (`/workspace/honker` @ f4e53c6,
|
||||
`README.md:112`) — the reference posture; no capability API exists
|
||||
in the starting artifact to inherit or rename.
|
||||
- alkblobs' deployment-asserts-truth precedent
|
||||
(`/workspace/@alkdev/alkblobs/docs/architecture/decisions/012-pre-decomposition-consistency-rulings.md`
|
||||
§fleet) — the documented-invariant-not-detected posture §3 adopts.
|
||||
- OQ-04 (the pinning that parked this question), OQ-10 (the
|
||||
versioning duty this resolution narrows), OQ-11.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# Deployment
|
||||
@@ -8,8 +8,11 @@ last_updated: 2026-10-05
|
||||
What a deployer must know to size, run, and reason about alkstore
|
||||
engines: host semantics, connection budgets, durability knobs, and
|
||||
where engine differences may honestly surface in the contract. The
|
||||
capability-surface *decision* (how much of this the trait exposes) is
|
||||
OQ-08's; this document holds the facts and the decision's frame.
|
||||
capability-surface *decision* is resolved
|
||||
([ADR-016](decisions/016-deployment-honesty.md), 2026-10-06): no
|
||||
runtime capability surface — this document's matrix is (with the
|
||||
engine crates' own docs) where the honest boundary lives; this
|
||||
document holds the facts.
|
||||
|
||||
## Host semantics
|
||||
|
||||
@@ -18,24 +21,41 @@ OQ-08's; this document holds the facts and the decision's frame.
|
||||
| SQLite | **single-machine**, file-backed | NFS two-writers unsupported (honker's honesty posture, inherited, [ADR-003](decisions/003-sqlite-driver.md)). Cross-process *on one host* is verified POC ground (`data_version` is cross-process by nature). |
|
||||
| Postgres | **multi-host native** | Nothing assumes a shared host; POC #2 ran all-through-network (docker bridge) with the same properties ([ADR-004](decisions/004-postgres-driver.md)). |
|
||||
|
||||
The unified trait must not pretend SQLite is multi-host — but whether
|
||||
that honesty lives as runtime capability flags, compile-time engine
|
||||
knowledge, or a documented matrix only is OQ-08
|
||||
([ADR-006](decisions/006-wake-and-delivery-contract.md) note: the
|
||||
trait's shape constrains where capability differences can surface).
|
||||
The unified trait must not pretend SQLite is multi-host — and it does
|
||||
not: [ADR-016](decisions/016-deployment-honesty.md) resolves that
|
||||
honesty to compile-time engine identity (the engine crate a binary
|
||||
depends on *is* the deployment statement) plus this documented matrix.
|
||||
There is no `Store::capabilities()` — the trait's shape constrains
|
||||
where capability differences can surface
|
||||
([ADR-006](decisions/006-wake-and-delivery-contract.md)), and the
|
||||
resolution is: nowhere at runtime.
|
||||
|
||||
Options for OQ-08, with their shape:
|
||||
Options for OQ-08, with their outcome
|
||||
([ADR-016](decisions/016-deployment-honesty.md)):
|
||||
|
||||
1. **Compile-time only** — a consumer chooses an engine crate at
|
||||
dependency time; the engine's docs carry its deployment facts.
|
||||
Smallest contract; nothing runtime to match on.
|
||||
Smallest contract; nothing runtime to match on. **Adopted** —
|
||||
together with (3); the two compose (engine docs serve the consumer
|
||||
choosing the dependency, the matrix serves the operator choosing
|
||||
the topology).
|
||||
2. **`Store::capabilities()`** — a runtime description
|
||||
(payload limits, wake cadence knobs, host semantics). Lets a
|
||||
consumer adapt (e.g., chunk large notify payloads) but adds a
|
||||
contract surface all engines must keep honest.
|
||||
contract surface all engines must keep honest. **Rejected** —
|
||||
field-by-field under ADR-008 §5's act-differently rule, and no
|
||||
consumer-inventory row names a runtime-adapt need
|
||||
([ADR-016](decisions/016-deployment-honesty.md) §2).
|
||||
3. **Deployment matrix only** (this document) — no API surface. The
|
||||
honest-middle choice; matches the ecosystem's doc-first posture
|
||||
but provides no programmatic guard.
|
||||
but provides no programmatic guard. **Adopted** (with (1)) — the
|
||||
"programmatic guard" gap is closed where it can honestly be:
|
||||
the engine-crate dependency edge cannot drift out of sync with
|
||||
the truth it states; the misconfiguration case (SQLite as shared
|
||||
network storage) follows the family's
|
||||
deployment-asserts-truth posture — documented detection symptom,
|
||||
no fabricated runtime machinery
|
||||
([ADR-016](decisions/016-deployment-honesty.md) §3).
|
||||
|
||||
## Connection budgets
|
||||
|
||||
@@ -107,7 +127,8 @@ From both POCs (single-box, relative shapes are the deliverable —
|
||||
| [003](decisions/003-sqlite-driver.md) | SQLite driver | bundling, toolchain floor |
|
||||
| [004](decisions/004-postgres-driver.md) | Postgres driver | listener budget line, forwarder posture |
|
||||
| [006](decisions/006-wake-and-delivery-contract.md) | Wake contract | where capability differences may surface |
|
||||
| [008](decisions/008-contract-v1-pinning.md) | Contract v1 | constructor/options in engine crates; no capability surface in v1 (OQ-08) |
|
||||
| [008](decisions/008-contract-v1-pinning.md) | Contract v1 | constructor/options in engine crates; no capability surface in v1 (OQ-08; resolved by [ADR-016](decisions/016-deployment-honesty.md)) |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty | no runtime capability surface — compile-time identity + this matrix; `PayloadTooLarge` is the one runtime asymmetry carriage |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -115,5 +136,8 @@ Open questions are tracked in
|
||||
[open-questions.md](open-questions.md). Key
|
||||
questions affecting this document:
|
||||
|
||||
- **OQ-08**: capability-surface shape — compile-time vs runtime flags
|
||||
vs matrix-only (open)
|
||||
- **OQ-08**: capability-surface shape — **resolved**
|
||||
(2026-10-06, [ADR-016](decisions/016-deployment-honesty.md)):
|
||||
no runtime capability surface; compile-time engine identity +
|
||||
this matrix; re-entry via a consumer-inventory row naming a
|
||||
runtime-adapt need.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# Postgres engine
|
||||
@@ -111,6 +111,7 @@ the record in [ADR-003](decisions/003-sqlite-driver.md).
|
||||
| [012](decisions/012-forked-substrate-design.md) | Fork design | contract-blind substrate (SQLite side); pg engine owns its own curve/stamps arithmetic, equivalence pinned by the contract suite |
|
||||
| [014](decisions/014-outbox-tx-enqueue.md) | Outbox tx enqueue | `outbox_enqueue_tx` on `TxHandle`; derivation engine-side inside the caller's tx |
|
||||
| [015](decisions/015-streams-depth.md) | Streams depth | nullable key column (carried metadata); bigserial offsets, global-FIFO reads; keyed tx publish; `trim_to` as a pool-connection delete |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty | no runtime capability surface — this engine's multi-host posture is stated by its crate identity and docs; `PayloadTooLarge` occurrence pinned contract-suite (this engine produces it, client-side pre-round-trip) |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -118,8 +119,12 @@ Open questions are tracked in
|
||||
[open-questions.md](open-questions.md). Key
|
||||
questions affecting this document:
|
||||
|
||||
- **OQ-08**: capability surface (shared with
|
||||
[deployment.md](deployment.md)) (open)
|
||||
- **OQ-08**: capability surface — **resolved**
|
||||
(2026-10-06, [ADR-016](decisions/016-deployment-honesty.md)):
|
||||
no runtime capability surface; this engine's multi-host posture
|
||||
lives in its crate identity + docs and the deployment matrix;
|
||||
the engine's one runtime-visible asymmetry (`PayloadTooLarge`)
|
||||
was already contract-pinned.
|
||||
- **OQ-12**: streams depth — **resolved**
|
||||
(2026-10-05, [ADR-015](decisions/015-streams-depth.md)): key =
|
||||
carried metadata; global-FIFO-by-offset ordering row
|
||||
@@ -130,6 +135,8 @@ questions affecting this document:
|
||||
|
||||
Resolved: **OQ-09** (scheduler collapse —
|
||||
[ADR-009](decisions/009-scheduler-collapse.md)), **OQ-05** (queue
|
||||
semantics depth — [ADR-010](decisions/010-queue-semantics-depth.md)), and
|
||||
semantics depth — [ADR-010](decisions/010-queue-semantics-depth.md)),
|
||||
**OQ-12** (streams depth — [ADR-015](decisions/015-streams-depth.md)),
|
||||
2026-10-05.
|
||||
and **OQ-08** (capability surface — none;
|
||||
[ADR-016](decisions/016-deployment-honesty.md)),
|
||||
2026-10-05/06.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# SQLite engine
|
||||
@@ -33,7 +33,10 @@ per-contract obligations live in the core spec and are not restated here.
|
||||
Every engine call runs in `spawn_blocking`.
|
||||
- Single-host by nature: file-backed, one machine, NFS-two-writers
|
||||
unsupported (honker's honesty posture, inherited). See
|
||||
[deployment.md](deployment.md).
|
||||
[deployment.md](deployment.md); the boundary's surface location is
|
||||
decided ([ADR-016](decisions/016-deployment-honesty.md)) — this
|
||||
crate's identity and docs state the posture; no runtime descriptor
|
||||
exists.
|
||||
|
||||
## Connection architecture
|
||||
|
||||
@@ -127,6 +130,7 @@ family is `__alkstore_*` (ADR-010 §8's naming authorization).
|
||||
| [013](decisions/013-fold-substrate-into-sqlite.md) | Substrate packaging | folded into `alkstore-sqlite` (`src/substrate/`); no fourth crate |
|
||||
| [014](decisions/014-outbox-tx-enqueue.md) | Outbox tx enqueue | `outbox_enqueue_tx` on `TxHandle`; derivation engine-side through the writer-slot lease |
|
||||
| [015](decisions/015-streams-depth.md) | Streams depth | key = carried metadata (the inherited nullable column); global-FIFO ordering; `trim_to` as a writer-lease delete; event shape already the substrate's |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty | no runtime capability surface; single-host posture stated by crate identity + docs; this engine never produces `PayloadTooLarge` (pinned in the contract suite) |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -153,6 +157,8 @@ questions affecting this document:
|
||||
|
||||
Resolved: **OQ-09** (scheduler collapse —
|
||||
[ADR-009](decisions/009-scheduler-collapse.md)), **OQ-05** (queue
|
||||
semantics depth — [ADR-010](decisions/010-queue-semantics-depth.md)), and
|
||||
semantics depth — [ADR-010](decisions/010-queue-semantics-depth.md)),
|
||||
**OQ-12** (streams depth — [ADR-015](decisions/015-streams-depth.md)),
|
||||
2026-10-05.
|
||||
and **OQ-08** (capability surface — none, by default ever;
|
||||
[ADR-016](decisions/016-deployment-honesty.md)),
|
||||
2026-10-05/06.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# alkstore — Open Questions
|
||||
@@ -27,13 +27,17 @@ is OQ-11); **the fork packaging folded** (2026-10-05,
|
||||
**OQ-12 resolved** (2026-10-05,
|
||||
[ADR-015](decisions/015-streams-depth.md) — streams depth pinned:
|
||||
carried-metadata keys, global-FIFO ordering row, `StreamEvent` shape,
|
||||
`publish_with_key_tx`, `trim_to`).
|
||||
Next: **OQ-08** (rides the now-pinned trait
|
||||
shape and the ADR-011 substrate fork), OQ-10 (versioning discipline
|
||||
`publish_with_key_tx`, `trim_to`); **OQ-08 resolved** (2026-10-06,
|
||||
[ADR-016](decisions/016-deployment-honesty.md) — no runtime
|
||||
capability surface; the honest boundary lives in compile-time engine
|
||||
identity + the documented deployment matrix).
|
||||
Next: **OQ-10** (versioning discipline
|
||||
for contract extensions; note ADR-011 changes its substrate-side facts
|
||||
for SQLite — the forked machinery lives in-tree inside the engine
|
||||
crate per [ADR-013](decisions/013-fold-substrate-into-sqlite.md), so
|
||||
the engine/core contract pairing is what the discipline must track),
|
||||
the engine/core contract pairing is what the discipline must track;
|
||||
OQ-08's resolution also narrowed its surface — no capability struct
|
||||
to govern),
|
||||
OQ-11 (fork follow-through items — substrate-side, non-consumer-facing).
|
||||
|
||||
Resolved questions stay listed with their resolution; they are not
|
||||
@@ -288,23 +292,52 @@ narrowed to the pinning work its own record already scoped.)*
|
||||
|
||||
## Theme: Deployment and capabilities
|
||||
|
||||
### OQ-08: Where does the honest single-host/multi-host boundary live in the trait surface? *(== OQ-ST-08)*
|
||||
### OQ-08: Where does the honest single-host/multi-host boundary live in the trait surface? *(== OQ-ST-08)* — **RESOLVED**
|
||||
|
||||
- **Origin**: [deployment.md](deployment.md)
|
||||
- **Status**: open
|
||||
- **Status**: resolved (2026-10-06, Phase 1 —
|
||||
[ADR-016](decisions/016-deployment-honesty.md))
|
||||
- **Priority**: medium
|
||||
- **Resolution**: open. The pg engine is natively multi-host (POC #2
|
||||
verified — no single-host assumption to remove); SQLite is
|
||||
single-machine by nature (file-backed, NFS-two-writers unsupported —
|
||||
honker's honesty posture, inherited by the forked substrate). The
|
||||
unified surface must not pretend SQLite is multi-host. Options:
|
||||
per-engine capability flags (`Store::capabilities()`), a documented
|
||||
deployment matrix only ([deployment.md](deployment.md) carries the
|
||||
facts), or compile-time knowledge only (a consumer choosing the
|
||||
SQLite engine knows). Rides the now-pinned contract shape
|
||||
([ADR-008](decisions/008-contract-v1-pinning.md)): the trait
|
||||
constrains where capability differences can surface.
|
||||
- **Cross-references**: OQ-04, [ADR-006](decisions/006-wake-and-delivery-contract.md), [ADR-012](decisions/012-forked-substrate-design.md) (the substrate inherits the honesty posture).
|
||||
- **Resolution**: Pinned by
|
||||
[ADR-016](decisions/016-deployment-honesty.md): **no runtime
|
||||
capability surface — in v1 and by default ever**. The honest
|
||||
single-host/multi-host boundary lives in the two places it is
|
||||
already true, which compose rather than rival: (1)
|
||||
**compile-time engine identity** — the engine crate a binary
|
||||
depends on *is* the deployment statement (single-driver binaries,
|
||||
[ADR-001](decisions/001-crate-split.md); constructors in engine
|
||||
crates, [ADR-008](decisions/008-contract-v1-pinning.md) §6 —
|
||||
"the engine choice is a dependency-graph fact, not a runtime
|
||||
branch"); (2) **deployment.md's documented matrix** — the
|
||||
ops-facing facts of record, unchanged. Option 2
|
||||
(`Store::capabilities()`) rejected field-by-field under ADR-008
|
||||
§5's act-differently rule generalized to surface: host semantics
|
||||
admit no in-process action (a flag would invite the engine-type
|
||||
branch principle 4 bans); payload limits already have their runtime
|
||||
carriage — the universal, contract-wide matchable
|
||||
`PayloadTooLarge` variant (a `capabilities()` field would be a
|
||||
second normative home); wake cadence and knobs are engine-crate
|
||||
config (§6's split); and no consumer-inventory row names any
|
||||
runtime-adapt need. No `engine_name()`, no `#[cfg]` capability
|
||||
axes. The "must not pretend SQLite is multi-host" obligation
|
||||
resolves into three standing statements (contract text carries
|
||||
asymmetries via the taxonomy, engine-crate docs carry posture,
|
||||
deployment.md carries ops facts); the misconfiguration case
|
||||
(SQLite as shared network storage) follows the family's
|
||||
deployment-asserts-truth posture (alkblobs precedent) — documented
|
||||
boundary, no fabricated detection. Contract-suite row added:
|
||||
`PayloadTooLarge` occurrence asymmetry (pg client-side pre-round-
|
||||
trip, SQLite never) — with no capabilities API, the variant is the
|
||||
one runtime carriage of an engine asymmetry, so its matchability
|
||||
is pinned. Re-entry gate: a consumer-inventory row naming a
|
||||
runtime-adapt need.
|
||||
- **Cross-references**: OQ-04 (the pinning that parked this),
|
||||
OQ-10 (narrowed by this — no capability struct to govern), OQ-11,
|
||||
[ADR-001](decisions/001-crate-split.md),
|
||||
[ADR-006](decisions/006-wake-and-delivery-contract.md),
|
||||
[ADR-008](decisions/008-contract-v1-pinning.md) §1/§5/§6,
|
||||
[ADR-012](decisions/012-forked-substrate-design.md),
|
||||
[deployment.md](deployment.md).
|
||||
|
||||
|
||||
|
||||
@@ -416,6 +449,6 @@ narrowed to the pinning work its own record already scoped.)*
|
||||
## Deferred / Blocked
|
||||
|
||||
None currently. Every open OQ above is actionable Phase 1 work
|
||||
(capability-surface shape, versioning discipline, fork-scaffold
|
||||
(versioning discipline, fork-scaffold
|
||||
follow-through) with its evidence base complete — no
|
||||
external arrivals are being waited on.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-05
|
||||
last_updated: 2026-10-06
|
||||
---
|
||||
|
||||
# alkstore — Overview
|
||||
@@ -28,7 +28,7 @@ Per [ADR-001](decisions/001-crate-split.md):
|
||||
|
||||
| Crate | Contents | Driver dependencies |
|
||||
|---|---|---|
|
||||
| `alkstore` (core) | trait surface, types, error model | none (capability flags, if ever, are OQ-08's to add) |
|
||||
| `alkstore` (core) | trait surface, types, error model | none (no capability surface — [ADR-016](decisions/016-deployment-honesty.md): engine differences are compile-time identity + the deployment matrix, never a runtime descriptor) |
|
||||
| `alkstore-sqlite` | SQLite engine ([ADR-003](decisions/003-sqlite-driver.md)) | rusqlite; the forked honker-core lineage rides in-tree as the engine crate's substrate module subtree ([ADR-011](decisions/011-sqlite-substrate-fork.md), designed in [ADR-012](decisions/012-forked-substrate-design.md), folded per [ADR-013](decisions/013-fold-substrate-into-sqlite.md)) |
|
||||
| `alkstore-postgres` | Postgres engine ([ADR-004](decisions/004-postgres-driver.md)) | tokio-postgres, deadpool-postgres |
|
||||
| (mem engine, optional) | test convenience, decided at implementation ([ADR-001](decisions/001-crate-split.md)) | none |
|
||||
@@ -56,7 +56,7 @@ Per [ADR-002](decisions/002-feature-scope.md):
|
||||
| [engine-sqlite.md](engine-sqlite.md) | SQLite engine: mapping the contract onto the forked substrate module/rusqlite |
|
||||
| [engine-postgres.md](engine-postgres.md) | Postgres engine: mapping the contract onto tokio-postgres/LISTEN |
|
||||
| [queues.md](queues.md) | Queue/scheduler/outbox semantics depth (ADR-009/ADR-010 resolved) |
|
||||
| [deployment.md](deployment.md) | Host capabilities, connection budgets, deployment matrix (OQ-08) |
|
||||
| [deployment.md](deployment.md) | Host capabilities, connection budgets, deployment matrix (OQ-08 resolved) |
|
||||
| [open-questions.md](open-questions.md) | OQ-01..NN tracker |
|
||||
| [decisions/](decisions/) | ADRs |
|
||||
|
||||
@@ -79,6 +79,7 @@ Per [ADR-002](decisions/002-feature-scope.md):
|
||||
| [013](decisions/013-fold-substrate-into-sqlite.md) | Fold the forked substrate into `alkstore-sqlite` (no fourth crate) | Accepted |
|
||||
| [014](decisions/014-outbox-tx-enqueue.md) | Transactional outbox enqueue (`outbox_enqueue_tx` on `TxHandle`) | Accepted |
|
||||
| [015](decisions/015-streams-depth.md) | Streams depth (carried-metadata keys, global-FIFO ordering, `StreamEvent`, `trim_to`) | Accepted |
|
||||
| [016](decisions/016-deployment-honesty.md) | Deployment honesty (no runtime capability surface; compile-time identity + matrix) | Accepted |
|
||||
|
||||
## Non-goals
|
||||
|
||||
@@ -90,7 +91,8 @@ Per [ADR-002](decisions/002-feature-scope.md):
|
||||
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](deployment.md)).
|
||||
([deployment.md](deployment.md); the boundary's location in the
|
||||
surface is decided — [ADR-016](decisions/016-deployment-honesty.md)).
|
||||
|
||||
## Evidence base
|
||||
|
||||
|
||||
@@ -701,7 +701,8 @@ unless a consumer appears; nothing remains to extract or decide here.
|
||||
|
||||
### OQ-ST-08: Multi-host / deployment posture
|
||||
|
||||
**Status: open.**
|
||||
**Status: resolved (2026-10-06, Phase 1 — promoted as OQ-08;
|
||||
[ADR-016](../architecture/decisions/016-deployment-honesty.md).)**
|
||||
|
||||
Honker is explicitly single-machine (file-backed SQLite). Postgres is
|
||||
natively multi-host — POC #2 verified the pg engine side has no
|
||||
|
||||
Reference in new issue
Block a user