docs(architecture): ADR-013 — family composition, reactive boundary, sweep lease; OQ-11 resolved
- No sibling (alkstore) dependency in-core; reactivity is deployment-layer composition above the facade — cadence stays embedder-owned (ADR-005), with alkstore the named substrate for it; in-crate notify/scheduler/queues/invalidation hooks are non-goals. - Fleet sweeper lock pinned as 'named exclusive sweep lease' semantics; shipped provider unchanged (pg advisory clause); provider swaps are ADR-007-shaped substitution doors. - Composition contract for downstream ADRs: co-tenancy of CAS/GC state + reactive machinery + consumer/liveness tables on one fleet host; no-cross-store-atomicity ruled; compensation rests on idempotent re-puts, windowed deletes, sweeps-as-report-data. - OQ-11 resolved (the register's one live circular hedge): engine features pull their own driver clusters — sqlite becomes feature 'sqlite' (default-on, carries rusqlite); 'kv'/'large' tier features retired; 'local' ungated; pg-pure builds are supported, non-default. Deciding fact already in-tree (REQ-2/ADR-009). - requirements.md: UC-4/REQ-5 records the composition facts (operator record 2026-10-11, corroborated by alkstore's consumer-inventory). - Publish guard stated pre-code: facade ships before publish; semver-is-contract from first publish (alkstore ADR-017 discipline). - Amended accepted ADRs' feature wording (ADR-010 §1, ADR-011 §3/§4, ADR-003) with supersession notes; README/overview/open-questions/ backends/store-api/gc aligned; parked index now empty. Verification: docs-only round (no Rust surface touched); full-tree single-value check on the feature graph and sweep-lease wording.
This commit is contained in:
1 parent
7b9d904b8a
commit
bee86b0dbd
11 files changed
+433
-64
No files matched your search
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-03 (ADR-012 — OQ-11 parking reference; ADR-012 row added)
|
||||
last_updated: 2026-10-11 (ADR-013 — family composition & reactive boundary; OQ-11 resolved, feature graph re-pinned to engine features)
|
||||
---
|
||||
|
||||
# Overview
|
||||
@@ -72,8 +72,9 @@ or three times.
|
||||
┌──────────────────────┐ ┌─────────────────────────────────┐
|
||||
│ kv tier (ADR-003/ │ │ large tier (ADR-003/008/011; │
|
||||
│ 007/011) │ │ formerly "fs") │
|
||||
│ sqlite (default) │ │ local (default) │
|
||||
│ postgres ("postgres") │ pg-lo ("pg-lo"; ADR-009) │
|
||||
│ sqlite ("sqlite"; │ │ local (ungated; ADR-013 §4) │
|
||||
│ default engine) │ │ pg-lo ("pg-lo"; ADR-009) │
|
||||
│ postgres ("postgres") │ │
|
||||
│ mem ("mem"; tests + │ │
|
||||
│ contract reference) │ │
|
||||
└──────────────────────┘ └─────────────────────────────────┘
|
||||
@@ -90,24 +91,31 @@ or three times.
|
||||
|
||||
| Layer | Dependencies | Notes |
|
||||
|---|---|---|
|
||||
| base crate (store core + tier engines) | `tokio`, `thiserror`, `parking_lot`, plus `rusqlite` behind the `kv` feature and nothing behind `large`/`mem` | no alkcall, no serialization frameworks |
|
||||
| `postgres` engine feature (ADR-007) | adds `tokio-postgres` + `deadpool-postgres` behind the kv tier's second engine, default-off | depends on `kv`'s contract surface (the `Backend` trait definition is base-crate code); the engine's *impl* is additive. Same `Backend` contract, own sweep-safety CI gate under `--all-features` |
|
||||
| `pg-lo` engine feature (ADR-009) | Large Objects as the large tier's second engine, default-off | pulls the same `tokio-postgres`/`deadpool-postgres` cluster as the `postgres` kv engine (SQL `lo_*` functions, no additional dependency); **does not imply the `postgres` feature** — engine features pull the driver cluster independently (ADR-010 §1), so a `large`=pg-lo + kv=sqlite node is coherent and supported; same admission/test-gate shape |
|
||||
| `mem` engine feature (ADR-011) | the kv tier's ephemeral engine, default-off | `BTreeMap`-shaped; the contract-reference engine; no dependencies |
|
||||
| base crate (store core + tier dispatch + GC) | `tokio`, `thiserror`, `parking_lot` | no alkcall, no reactive substrate, no serialization frameworks |
|
||||
| engine features (ADR-010 §1, extended to every engine by ADR-013 §4) | each engine pulls only its own driver cluster | `sqlite` (default-on, `rusqlite`), `postgres` (default-off, `tokio-postgres`+`deadpool-postgres`), `mem` (default-off, nothing), `pg-lo` (default-off, the shared pg cluster); `local` is ungated (dependency-free). Every engine-feature combination is a coherent node shape (e.g. `large`=pg-lo + kv=sqlite, ADR-010 §1); the feature-gated engines' conformance/sweep-safety gates run under `--all-features` (ADR-007/009) |
|
||||
| `ops` feature | adds `alkcall` (feature-gated, default-off) | JSON op specs + binary channels + `AccessControl`; ADR-001 |
|
||||
| consumer crates | depend on alkblobs (and on alkcall directly when they speak ops) | alkgit, alkfs |
|
||||
| consumer crates | depend on alkblobs (and on alkcall directly when they speak ops) | alkgit, alkfs — which also deploy the sibling reactive substrate beside it (below) |
|
||||
|
||||
Tiers are feature-gated; both default-on (batteries-included, the
|
||||
alkgit feature-model pattern — default-on features, opt-out rather
|
||||
than opt-in); the engine features `postgres` and `pg-lo`, and `mem`,
|
||||
are default-off, as are `ops`. A pg-only kv node (postgres engine
|
||||
without rusqlite) is **not** a supported configuration this crate
|
||||
optimizes for — feature-graph work for it is deferred until a named
|
||||
requirement exists (the base `kv` feature pulling rusqlite is the
|
||||
accepted v1 shape; convention 8's lean-base principle applies to
|
||||
*default* builds, which stay lean since `kv` is what the feature model
|
||||
controls, not what default-on means downstream; tracked as OQ-11 in
|
||||
open-questions.md's parked index). Wasm: the tier
|
||||
**The sibling reactive substrate (ADR-013 §1/§3):** **alkstore**
|
||||
(v0.1.0 — notify/locks/queues/streams/outbox/scheduler behind its own
|
||||
engine crates) ships beside this crate, not under it. The core keeps
|
||||
no alkstore dependency and no reactive machinery: cadence and
|
||||
invalidation wiring are deployment-layer composition above the facade
|
||||
(ADR-005's "embedder owns cadence" stands, with the sibling the
|
||||
named substrate; sweep outcomes are report data — ADR-012 §1 — whose
|
||||
pinned consumer is that wiring). Cross-store atomicity is unachievable
|
||||
by construction; the composition properties are idempotent re-puts,
|
||||
windowed deletes, and reports-as-data (ADR-013 §3, the citable
|
||||
downstream contract).
|
||||
|
||||
Tiers are **constructor composition**, not features (ADR-013 §4);
|
||||
engine features as in the table above. The default build is
|
||||
batteries-included (sqlite default-on — opt-out rather than opt-in,
|
||||
the alkgit feature-model pattern), and a pg-pure build (sqlite off;
|
||||
kv=postgres, `large`=pg-lo if wanted) is a supported configuration
|
||||
this crate does not default to — REQ-2's consolidation posture
|
||||
(ADR-009), now carried by the feature graph instead of parked on it.
|
||||
Wasm: the tier
|
||||
engines are not a wasm story; a wasm client is a consumer of the `ops`
|
||||
surface (which rides alkcall, itself wasm-clean), never an in-process
|
||||
embedder (ADR-001 §Consequences).
|
||||
@@ -124,6 +132,10 @@ embedder (ADR-001 §Consequences).
|
||||
Backend to model paths (ADR-004).
|
||||
- No chunk-tree/CDC storage encoding; whole-file CAS is the store's only
|
||||
granularity (ADR-006).
|
||||
- No reactive coordination machinery in-core — no notify, no scheduler,
|
||||
no queues, no invalidation hooks: reactivity is the sibling
|
||||
substrate's (alkstore), composed at the deployment layer above the
|
||||
facade (ADR-013 §1).
|
||||
- No per-repo or per-namespace walled stores — one pooled CAS
|
||||
(ADR-005).
|
||||
|
||||
@@ -143,6 +155,7 @@ embedder (ADR-001 §Consequences).
|
||||
| [010](decisions/010-backend-io-seams-and-fleet-state-home.md) | I/O seams + GC-state home | read cursor / staged put; store-core-owned GC state via the engine-state seam; kv fleet-validity rule; pin-token renewal |
|
||||
| [012](decisions/012-pre-decomposition-consistency-rulings.md) | Sweep-abort shape + composition rulings | sweeps never error (`GcAborted` retired, `GcRefuse` for direct-delete); token wire shape; fleet mode = constructor declaration; GC state hosts on the kv engine; sqlite seam reduction |
|
||||
| [011](decisions/011-vocabulary-tiers-engines-and-fleet-state.md) | Vocabulary + rename | tier/engine/instance/node/fleet pinned; mem joins the kv tier; large tier renamed `large`; constructor modes |
|
||||
| [013](decisions/013-family-composition-reactive-boundary-and-feature-graph.md) | Family composition & reactive boundary | no sibling dependency in-core; sweep lease semantics (provider: raw advisory clause); co-tenancy + no-cross-store-atomicity; OQ-11 resolved (engine features pull own drivers) |
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -157,8 +170,9 @@ crate level:
|
||||
open-read requirement)
|
||||
- **OQ-10**: second kv engine — resolved by ADR-007 (sqlite + postgres
|
||||
shipped behind one trait; per-node constructor choice)
|
||||
- **OQ-11**: pg-only kv node feature graph — deferred(scope), parked
|
||||
(see [open-questions.md](open-questions.md))
|
||||
- **OQ-11**: pg-only kv node feature graph — resolved by ADR-013 §4
|
||||
(engine features pull their own driver clusters; `sqlite` default-on;
|
||||
pg-pure builds supported, non-default)
|
||||
- **POC #7** (`docs/research/poc-pglo-findings.md`): pg Large Objects
|
||||
as the large tier's `pg-lo` engine — **passed** 2026-10-03; admitted as
|
||||
a shipped engine by ADR-009 (REQ-2's consolidation option)
|
||||
|
||||
Reference in new issue
Block a user