docs(architecture): ADR-010/011 — I/O seams, GC-state home, vocabulary; pre-decomposition consistency round

ADR-010 (new): the Backend trait's I/O seams pinned before any code —
'get' returns a crate-internal read cursor (kv engines materialize;
'local' pread loop; pg-lo lo_get windows), 'put' has two named forms
(whole-value kv / staged-put large); GC state is store-core-owned via
a crate-internal contract-tested engine-state seam on the SQL-backed
engines (backends never learn liveness — ADR-005 verbatim); the store
core holds the joint entry+pin transaction (corrects ADR-009 §2's
ownership statement); kv-tier fleet-validity rule added (mirror of
ADR-008 §3); ops pin-token TTL race resolved (the token IS the pin;
renewal rides have/re-put; pause-past-TTL falls to delete-then-recover);
feature graph pinned (pg-lo does not imply postgres).

ADR-011 (new): vocabulary pinned — tier (contract, exactly two) vs
engine (concrete impl, exactly five); store instance / node / fleet
split (fleet = pool-sharing, not node count — fixes requirements.md's
self-contradiction with REQ-2); mem demoted from 'backend'/'testing
tier' to the kv tier's third engine (contract-reference engine);
fs tier renamed 'large' including the feature name (last free moment
before code exists); constructor modes pinned (dual-tier default,
kv-only, mem-only) plus the composite fleet-validity predicate.

Consistency round across all specs and ADR-003/004/007/008/009: stale
pg-lo passages resolved per ADR-009's supersession; ADR-008 owner
'node id' → store-instance id; threshold wording corrected (conservative
edge, not midpoint, of the 128-256 KiB crossover zone); SweepReport
shape specced; mem classification unified; 008/009 ADR files renamed to
match the tier rename; README deferral-policy recap aligned (third
category = decided-but-sequenced work, not a parking kind); POC crate
list completed.

Verification: two independent architecture review rounds (the first
found 4 criticals — unpinned trait I/O shapes, missing fleet-state
seam, node/fleet self-contradiction, pin-token/TTL conflict — all
resolved; final round: zero criticals); all markdown links resolve;
ADR tables complete (11 ADRs).
This commit is contained in:
glm-5.3-flash committed 2026-10-03 05:55:20 +00:00
1 parent 9bbe6f3ad9
commit abf8c5ae9c
18 files changed
+1137 -336

No files matched your search

@@ -5,10 +5,15 @@
Accepted (engine pin amended by ADR-007 — the kv tier ships two
engines, sqlite and postgres, behind this contract; the dispatch layer
and trait are unchanged. The trait was extended by ADR-008 with a
`size` length probe — before any backend ships data — and the fs
tier became engine-selectable (`local` default; pg-lo candidate), so
this ADR's "engines"/"backends" counts are read through ADR-004's
tier≠engine scope note)
`size` length probe — before any backend ships data — and the second
tier became engine-selectable (`local` default; pg-lo admitted by
ADR-009), so this ADR's "engines"/"backends" counts are read through
ADR-004's tier≠engine scope note. The I/O shapes behind `get`/`put`
are pinned by ADR-010 (read cursor / staged put). The tier's name
changed: `fs` → `large` (ADR-011 — its routing criterion is length,
not medium); this ADR's per-engine counts also gained the `mem` kv
engine as ADR-011's vocabulary resolves — mem is a kv engine, not a
tier)
## Context
@@ -54,28 +59,34 @@ Evidence in hand (no further POC or consumer-waiting needed):
- **Virgin-store reads are no-ops** (missing table = absent/empty).
- **Namespace-blind** (ADR-005): backends see hashes only.
### Shipped backends (two, default-on; plus a testing tier)
### Shipped tiers (two, default-on; the kv tier also carries the mem engine)
- **`kv` (default-on): sqlite** for small blobs — measured ~9-10×
faster than fs at 1-16 KiB (POC #3 A4, first-party benchmark),
the regime holding most git objects, workspace files, and manifests.
WAL + `synchronous=NORMAL` as shipped durability; prepared
statements; no-tables-yet tolerance. (The tier's engine set was
widened to include postgres by ADR-007.)
- **`fs` (default-on)** for large blobs — flat
`{hex-prefix}/{hex-prefix}/{hash}` sharding (iroh's surviving
widened to include postgres by ADR-007, and mem — the ephemeral
reference engine — by ADR-011's vocabulary resolution.)
- **`fs` (default-on; renamed `large` by ADR-011)** for large blobs —
flat `{hex-prefix}/{hex-prefix}/{hash}` sharding (iroh's surviving
conclusion); stage-then-commit-rename; pread range reads (sound
locally per ADR-006).
- **`mem` (default-off):** ephemeral `BTreeMap` tier for tests and
in-process ephemerality. Never a production story.
locally per ADR-006). (The tier's engine set was widened by ADR-008/
009.)
- **`mem` (default-off):** ephemeral `BTreeMap` kv engine for tests
and in-process ephemerality — **an engine of the kv tier, not a
third tier** (ADR-011 §2; the pre-ADR-011 "testing tier" phrasing
is superseded). Never a production story; the contract-reference
engine.
Both production backends are default-on (batteries-included, the
Both production tiers are default-on (batteries-included, the
alkgit feature-model precedent); `mem` is not.
### Dispatch policy
- **Size-threshold routing; default 128 KiB, constructor-tunable**
(midpoint of the measured ~128-256 KiB crossover zone; POC #3 A4).
(chosen at the bottom of the measured ~128-256 KiB crossover zone —
the conservative edge of the flat zone; POC #3 A4).
- **Unknown-length puts buffer in memory up to the threshold; the
buffer's fate has three pinned semantics** (finding A6's option (d)):
1. **Threshold exceeded mid-stream** (non-restartable sources are
@@ -141,9 +152,10 @@ alkgit feature-model precedent); `mem` is not.
**Neutral**
- A network-backed backend (S3-like) remains possible via the same
- A network-backed engine (S3-like) remains possible via the same
trait but ships nothing here; its list/GC obligations are the
acceptance gate.
acceptance gate; per-tier, via a new ADR (ADR-011's vocabulary: an
engine addition, not a tier addition).
## References