ADR-013: fold the forked substrate into alkstore-sqlite — no fourth crate
Operator review of ADR-012's fork design re-litigated §1's crate identity. alkstore-substrate misdescribed what the code is (unpublished, path-dep-only, one consumer, SQLite-only — not a family-wide substrate); the mechanical-diff hope was gone at fork time regardless (port deltas, renames, re-derived half); and the alksocks F-1 lesson applies — a vendored region under a second, weaker instruction set is a defect seam. The fork folds into alkstore-sqlite as a bounded module subtree (src/substrate/); ADR-012 §3–§6 retained verbatim, §2 retained with its enforcement re-sited from the crate graph to diff fence + review + contract-suite equivalence pins. OQ-11 item (1) dissolved.
This commit is contained in:
1 parent
2949612e2c
commit
8e68b44194
10 files changed
+309
-55
No files matched your search
@@ -0,0 +1,207 @@
|
||||
# ADR-013: Fold the forked substrate into `alkstore-sqlite`
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (2026-10-05, Phase 1 — operator review of the fork design;
|
||||
amends [ADR-012](012-forked-substrate-design.md) §1, superseding the
|
||||
`alkstore-substrate` crate identity; §3–§6 of ADR-012 are retained
|
||||
verbatim, §2 is retained with its enforcement re-sited per §2 below)
|
||||
|
||||
## Context
|
||||
|
||||
ADR-011 fired the fork trigger; ADR-012 designed the fork and named the
|
||||
crate `alkstore-substrate` — a fourth, vendored, unpublished,
|
||||
path-dependency-only workspace crate below `alkstore-sqlite`. The design
|
||||
pillars (ADR-012 §2–§6) survived operator review intact. §1 did not:
|
||||
the operator flagged the naming and packaging for re-litigation, on two
|
||||
grounds — `alkstore-substrate` reads as a family-wide foundation crate
|
||||
in the family listing, which misdescribes what the code is, and since
|
||||
edits were coming regardless, the "keep the mechanical diff cheap"
|
||||
consideration that favored a separate fence was never going to pay out
|
||||
anyway.
|
||||
|
||||
Re-litigation from the decided material:
|
||||
|
||||
1. **The substrate was never a foundation.** It is unpublished, has a
|
||||
path-dependency-only, exactly-one-consumer relationship
|
||||
(`alkstore-sqlite`), is SQLite-only machinery, and its storage
|
||||
surface was re-owned as `__alkstore_*` at fork time — it is not
|
||||
shared, not reusable by the Postgres engine, and not a layer
|
||||
anything else sits on. "Substrate" named the *ride relationship*
|
||||
correctly in ADR-003's original posture (`honker-rs as the SQLite
|
||||
substrate`); promoted to a crate name in the family listing
|
||||
alongside `alkstore`, `alkstore-sqlite`, and `alkstore-postgres`,
|
||||
it now falsely signals a general foundation layer that a
|
||||
Postgres-consuming reader might think they need.
|
||||
2. **The mechanical-diff hope was already gone on day one.** The fork
|
||||
is born with port deltas (ADR-012 §4), table renames (ADR-011),
|
||||
dropped regions, family-standard porting, and — in any packaging —
|
||||
the re-derived half (new code, contract-derived names). No future
|
||||
point exists where a line-based diff against `/workspace/honker`
|
||||
stays mechanical. What survives is *cherry-pick* economics, and
|
||||
that is carried by ADR-012 §3's fidelity posture (keep the kept
|
||||
half's names), which is packaging-independent.
|
||||
3. **The alksocks precedent is directly on point — twice.** (a) The
|
||||
alksocks review's F-1 defect escaped through exactly the seam this
|
||||
packaging creates: a vendored region governed by a *second, weaker*
|
||||
instruction set ("verbatim where kept" + an adjustments list)
|
||||
sitting next to the project's own conventions. The standalone
|
||||
vendored crate carries the same structural risk — "vendored lineage"
|
||||
is baked into its identity, and ADR-012 already had to negotiate
|
||||
exceptions to the family standard inside it. One codebase, one
|
||||
instruction set closes the seam. (b) alksocks' own resolution
|
||||
(ADR-013 there) retired the vendor framing and folded the forked
|
||||
core into the owning crate as a named module tree, keeping the
|
||||
reference checkout for behavioral differential testing — and that
|
||||
shape shipped on crates.io without provenance problems.
|
||||
4. **The separate crate's advantages are weaker than they look, and
|
||||
the fold has a concrete bonus.**
|
||||
- *Compiler-enforced contract-blindness* (ADR-012 §2's strongest
|
||||
structural argument) becomes review-enforced under a fold: nothing
|
||||
stops substrate code inside `alkstore-sqlite` from importing
|
||||
alkstore core types that sit in a sibling dependency. This is the
|
||||
fold's one genuine loss, stated plainly and accepted — weighed
|
||||
against the misleading crate name, the dead wiring question, and
|
||||
the second-instruction-set seam, with the diff fence and the
|
||||
contract suite as the working guards.
|
||||
- *Dependency-graph hygiene*: ADR-012 §2's concern — "a vendored
|
||||
lineage crate must not acquire a dependency on our contract crate;
|
||||
the mirror inverts ADR-001" — becomes structurally impossible
|
||||
under a fold. There is no crate to carry the edge, and nothing
|
||||
depends on the folded code.
|
||||
- *License/provenance hygiene* ships fine in-tree: bundled license
|
||||
notice + module docs + the git-history fork line, the alksocks
|
||||
shape, proven.
|
||||
- *Bonus*: OQ-11 item (1) — the `bundled-sqlite` feature interplay
|
||||
of a substrate crate's rusqlite dependency with the engine crate's
|
||||
own — dissolves entirely. One crate, one rusqlite dependency.
|
||||
- *Restored shape*: ADR-001's split is three crates; ADR-011's
|
||||
"packaging follows ADR-001's split" line had been quietly
|
||||
stretched to four. The fold restores the decided shape.
|
||||
|
||||
## Decision
|
||||
|
||||
### 1. The fork lives inside `alkstore-sqlite`
|
||||
|
||||
The forked honker-core machinery is **a bounded module subtree of
|
||||
`alkstore-sqlite`** — `alkstore-sqlite/src/substrate/` — mirroring
|
||||
upstream's module structure per ADR-012 §3's fidelity posture. There is
|
||||
no fourth crate; ADR-001's three-crate shape (`alkstore`,
|
||||
`alkstore-sqlite`, `alkstore-postgres`) stands unamended. The engine
|
||||
crate's public API surface carries nothing of the substrate (ADR-012 §2
|
||||
and ADR-008 §6 unchanged — the contract is the returned trait; no
|
||||
substrate type or name reaches a consumer signature).
|
||||
|
||||
The word "substrate" survives where it reads correctly — as
|
||||
engine-internal vocabulary for "the SQLite storage machinery this
|
||||
engine rides" (its origin, ADR-003's sense) — and stops being a crate
|
||||
name. Specs referencing "the substrate" after this ADR mean the module
|
||||
subtree, not a dependency.
|
||||
|
||||
### 2. ADR-012 §2–§6 are retained (§3–§6 verbatim; §2 re-sited)
|
||||
|
||||
- **§2, contract-blind boundary**: retained in substance — the
|
||||
substrate module takes and returns primitives; the engine layer
|
||||
resolves contract semantics into primitive arguments exactly as
|
||||
ADR-012 §2 specifies — but its *enforcement site* moves from the
|
||||
crate graph to code discipline: the diff fence (lineage-relative
|
||||
diffs stay confined to the subtree), review, and the contract
|
||||
suite's equivalence pins, not Cargo.
|
||||
- **§3, fidelity posture**: retained verbatim — module structure and
|
||||
internal names of the kept half are upstream's; names are
|
||||
engine-internal either way, and cherry-pick economics (the posture's
|
||||
purpose) are packaging-independent.
|
||||
- **§4, port deltas**: retained verbatim (W-1 backoff, W-2 fallible
|
||||
spawn, panic-free watcher-fatal death, W-4 keep-RW, W-3 recorded).
|
||||
- **§5, bootstrap and schema machinery**: retained verbatim (append-
|
||||
column migrations; the `pragma_table_info` re-key of the duplicate-
|
||||
column race swallow; stamp columns via the re-derivation; no online
|
||||
rename migration; inert `_honker_*` orphans).
|
||||
- **§6, upstream tracking**: retained verbatim — deliberate
|
||||
cherry-picks recorded in the delta register, evaluated by
|
||||
port-cost logic; re-adoption keeps quality-read §7's bar.
|
||||
|
||||
### 3. Provenance and license, in-tree
|
||||
|
||||
At fork-scaffold time `alkstore-sqlite` carries:
|
||||
|
||||
- A **provenance register** recording upstream identity —
|
||||
`/workspace/honker` @ `f4e53c6`, MIT OR Apache-2.0 — and the delta
|
||||
list. Timing and initial contents are ADR-012 §1's (retained);
|
||||
location and format are this fold's to place — in-tree, beside the
|
||||
substrate subtree — and the exact format/granularity is OQ-11 item
|
||||
(2)'s.
|
||||
- The **dual license notice, bundled** in the substrate subtree (the
|
||||
alksocks `src/rfc1928/LICENSE` shape: upstream MIT + Apache text and
|
||||
copyright, preservation obligation perpetual, plus a fork-point
|
||||
statement and a modification note). Sublicensing is permitted by
|
||||
both licenses; the engine crate's license statement covers the
|
||||
whole crate.
|
||||
- **Git history is the fork-point record** — the scaffold commits are
|
||||
the provenance line, exactly as alksocks' extraction-commits window
|
||||
is.
|
||||
- `/workspace/honker` @ `f4e53c6` remains the **reference checkout**
|
||||
for cherry-pick candidates and differential testing; no dependency,
|
||||
no wiring.
|
||||
|
||||
### 4. OQ-11 reshaped
|
||||
|
||||
OQ-11's item (1) — the Cargo-workspace layout and the
|
||||
`bundled-sqlite`/rusqlite interplay of a separate substrate crate — is
|
||||
**dissolved** by this fold; the provenance register is carried
|
||||
in-tree beside the substrate subtree (its location settles with the
|
||||
fold; its format/granularity remains OQ-11 item (2)). Items (2)
|
||||
(register format and delta-list granularity) and (3) (cherry-pick
|
||||
procedure in practice) remain, now scoped to the in-tree register.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive**
|
||||
|
||||
- The family listing is honest: three crates, and nothing in the crate
|
||||
table suggests a foundation layer shared across engines.
|
||||
- One codebase, one instruction set — the alksocks F-1 seam class
|
||||
(conventions-vs-fidelity gaps in a vendored region) is closed
|
||||
structurally rather than by vigilance.
|
||||
- The `bundled-sqlite`/rusqlite wiring question dissolves; the engine
|
||||
crate has exactly one rusqlite dependency.
|
||||
- ADR-001's decided shape stands unamended; the fork-scaffold task
|
||||
shrinks (no fourth crate to wire, version-coordinate, or gate).
|
||||
- Cherry-pick economics are unaffected: ADR-012 §3's fidelity posture
|
||||
is packaging-independent.
|
||||
|
||||
**Negative (accepted)**
|
||||
|
||||
- Contract-blindness is review-enforced, not compiler-enforced:
|
||||
substrate-module code could import alkstore core types that the
|
||||
sibling dependency makes available. The guards are the diff fence
|
||||
(lineage-relative diffs stay confined to the subtree), review, and
|
||||
the contract suite's equivalence pins. Assessed low-risk — the
|
||||
module's API takes primitives by design, and the code has no reason
|
||||
to reach upward.
|
||||
- Internal-name ambiguity ("substrate" the module vs. the retired
|
||||
crate name) — mitigated by this ADR being the naming record and by
|
||||
the specs' references resolving to the module subtree.
|
||||
|
||||
## References
|
||||
|
||||
- [ADR-012](012-forked-substrate-design.md) — the fork design this ADR
|
||||
amends (§1 superseded; §3–§6 retained verbatim, §2 re-sited; this
|
||||
ADR does not reopen any retained question).
|
||||
- [ADR-011](011-sqlite-substrate-fork.md) — the fork decision and its
|
||||
scope register; packaging re-read under this ADR.
|
||||
- [ADR-001](001-crate-split.md) — the three-crate shape restored.
|
||||
- [ADR-003](003-sqlite-driver.md) — driver, seam, and watcher
|
||||
architecture; the origin of "substrate" as relationship vocabulary.
|
||||
- [ADR-008](008-contract-v1-pinning.md) §6 — the contract-is-the-
|
||||
returned-trait rule the fold preserves.
|
||||
- OQ-11 (`docs/architecture/open-questions.md`) — residue reshaped by
|
||||
§4 here.
|
||||
- alksocks `docs/architecture/decisions/011-inline-vendor.md` and
|
||||
`013-targeted-fork.md` (@ `/workspace/@alkdev/alksocks`) — the
|
||||
second-instruction-set finding (F-1) and the fold-into-owning-crate
|
||||
precedent this decision follows.
|
||||
- `docs/research/quality-read-honker-core.md` — the fork calculus and
|
||||
scope register.
|
||||
- [engine-sqlite.md](../engine-sqlite.md) — the engine spec this ADR's
|
||||
packaging realizes.
|
||||
Reference in new issue
Block a user