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.
11 KiB
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 §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:
- 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 alongsidealkstore,alkstore-sqlite, andalkstore-postgres, it now falsely signals a general foundation layer that a Postgres-consuming reader might think they need. - 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/honkerstays 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. - 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.
- 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-sqlitefrom 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-sqlitefeature 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.
- Compiler-enforced contract-blindness (ADR-012 §2's strongest
structural argument) becomes review-enforced under a fold: nothing
stops substrate code inside
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_infore-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/LICENSEshape: 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@f4e53c6remains 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 — 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 — the fork decision and its scope register; packaging re-read under this ADR.
- ADR-001 — the three-crate shape restored.
- ADR-003 — driver, seam, and watcher architecture; the origin of "substrate" as relationship vocabulary.
- ADR-008 §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.mdand013-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 — the engine spec this ADR's packaging realizes.