docs(architecture): ADR-008 — trait size probe, fleet GC, fs-tier engines; requirements anchor

- requirements.md (new): the three use cases pinned as REQ-1..4 with
  the node/pool/fleet/engine vocabulary defined once — ends per-session
  re-derivation of consumer facts. REQ-2 (replicator fleet over one
  shared pg pool, incl. large-blob serving) is recorded as a planning
  fact predating all POCs, on the operator's authority.
- ADR-008: Backend trait gains size(key) length probe (before any
  backend ships data — ADR-002 one-way-door discipline); fleet GC
  mechanism (DB-backed pin rows committed atomically with entries,
  TTL+renewal semantics, liveness = embedder-owned table, protect
  callback is single-node-only, advisory-locked single sweeper,
  staged re-arbitrated delete window on both engines); fs tier becomes
  engine-selectable (local default; pg-lo named candidate) with the
  fleet locality contract (shared media or re-routing; mixed tiers are
  a documented deployment invariant, not a constructor-provable one).
- poc-pglo-spec.md (new): POC #7 spec — pg Large Objects as the fs
  tier's pg-lo engine; instruments, decision gate, registered in
  phase-0.md OQ-BL-06.
- ADR-003/005 status amendments point to ADR-008's extensions; specs
  ripple (backends/store-api/gc/ops/overview/README).
- open-questions.md: deferral-policy header gains the decisions-vs-
  sequenced-work distinction; pg-lo's why-not-parked audit trail
  recorded.
- research fixes: postgres POC renumbered #4->#5 to the canonical
  register (phase-0 OQ-BL-06), redb cross-refs fixed, thinking-
  artifact sentence in B1 replaced with the honest reading.

Verification: docs-only change; reference-integrity sweep across the
tree (ADR/REQ/POC refs resolve); architecture-reviewer pass on the
delta — original 3 criticals addressed, its follow-up (fleet liveness
form, pin TTL, staged-delete semantics, enforceability, shared-media
caveats) fixed in this commit.
This commit is contained in:
glm-5.3-flash committed 2026-10-03 03:41:49 +00:00
1 parent 395d58cf3f
commit 281c37876e
16 files changed
+689 -88

No files matched your search

+11 -11
View File
@@ -11,13 +11,13 @@ last_updated: 2026-10-02
> crate `/workspace/alkblobs-redb-poc` — a copy of the POC crate with the
> pg arm replaced by a `RedbKv` backend (`redb` 4.3, the engine iroh-blobs'
> fs store uses for its metadata tables). The inherited sqlite/fs arms and
> the 14-test suite are byte-identical to POC #3/#4's methodology.
> the 14-test suite are byte-identical to POC #3/#5's methodology.
> Date: 2026-10-02. Status: **passed** (14 tests, clippy `-D warnings`
> clean, fmt clean).
## What this POC set out to decide
The "opposite route" from POC #4: postgres is complicated, we only need a
The "opposite route" from POC #5: postgres is complicated, we only need a
kv — what about a high-performance *embedded* kv like redb, which the
DESIGN.md lineage (iroh-blobs' "faster than the filesystem for small
items") and downstream folklore put anywhere from **2-7× over sqlite**,
@@ -26,11 +26,11 @@ margin at equal semantics, the kv tier's engine pin (ADR-003) is again
informed rather than hypothetical — and so is the anti-recommendation if
it doesn't.
Same 2D instrument as POC #4 (the shape of the question, learned there):
Same 2D instrument as POC #5 (the shape of the question, learned there):
1.Solo sweep (inherited `bench_small` harness, redb/sqlite/fs arms at
1-256 KiB, identical working set) — where the 2-7× claim should show up.
2. **Worker scale-out probe** (`redb_conc`, plus the POC #4 `sqlite_conc`
2. **Worker scale-out probe** (`redb_conc`, plus the POC #5 `sqlite_conc`
head-to-head) — redb is a single-file single-writer engine; does it
degrade like sqlite's WAL or survive like postgres?
@@ -129,17 +129,17 @@ were never the bottleneck axis (sqlite was already the fastest get at
adding threads only adds internal transaction-lock contention plus the
None-durability freelist growth penalty (pages freed between durable
commits accumulate until an Immediate commit collects them — redb's
documented "rapid growth" behavior). Contrast POC #4: sqlite's
documented "rapid growth" behavior). Contrast POC #5: sqlite's
contentioned WAL plateaued ~1.2k, pg *scaled* to 28k+. redb's None mode
is the only arm in three POCs where throughput goes **down** as workers
go up.
### Finding C5 (the decisive one): redb write scale-out is perfectly flat — ~40-44 ops/s at 1, 2, 4, and 8 threads
`redb_conc` Immediate mode (same fresh-key discipline as POC #4's
`redb_conc` Immediate mode (same fresh-key discipline as POC #5's
`pgdiag6`/`sqlite_conc`):
| workers | redb Immediate | sqlite (same probe) | pg (from POC #4) |
| workers | redb Immediate | sqlite (same probe) | pg (from POC #5) |
|---------|---------------|---------------------|------------------|
| 1 | ~42-44 ops/s | ~700-800/s | ~2.5-3.2k/s |
| 2 | ~40 ops/s | ~1.0-1.1k/s | ~4.6-5.5k/s |
@@ -168,7 +168,7 @@ go up.
crash-consistent (unpersisted commits can leave the file failing to
open until repaired — the freelist bookkeeping itself is lost on
crash), `Immediate` pays a full fdatasync per commit. The
durability-posture comparison that POC #4 could tune continuously
durability-posture comparison that POC #5 could tune continuously
(`synchronous_commit=off` on pg) doesn't exist here.
- redb's `Database` is process-lifetime; concurrency modes
(`ExclusiveWriter` default, `SingleWriter`, `MultiWriter`) only matter
@@ -208,7 +208,7 @@ go up.
- **Anti-recommendation adopted (ADR-007, 2026-10-02): redb stays
ruled out** — recorded in the decision so the question does not
reopen implicitly. SQLite's engine pin now has four-way triangulated
evidence (POC #3 fs, POC #4/#5 pg, POC #6 redb, plus the lineage
evidence (POC #3 fs, POC #5 pg, POC #6 redb, plus the lineage
citation), and ADR-007 ships the kv tier as sqlite + postgres. If a
future consumer wanted redb-shaped durability trade-offs (ephemeral
cache tier), that's a *different* tier than the kv engine slot.
@@ -222,7 +222,7 @@ go up.
- clippy `-D warnings` clean, fmt clean.
- **Honest caveats**: mdraid single dev box whose fdatasync latency
ranged 0.24-30 ms during the session under co-resident load (pg
container churn from POC #4 ran through the first bench; stopped
container churn from POC #5 ran through the first bench; stopped
before the final redbdiag re-run — relative conclusions unaffected,
absolute redb-Immediate numbers are *device-pressure-dependent* and
the honest statement is "1 fdatasync per commit, cost = device
@@ -237,4 +237,4 @@ go up.
`redbdiag2.rs` (None + periodic-flush group-commit emulation),
`redbdiag3.rs` (commit-vs-insert split, per-put file growth),
`redbdiag4.rs` (warm distribution), `redb_conc.rs` (scale-out, both
durability modes), `sqlite_conc.rs` (copied head-to-head from #4).
durability modes), `sqlite_conc.rs` (copied head-to-head from #5).