ADR-037
Bottom-up diamond progression (no feature-milestone defer)
accepted · 2026-04-17 · L0 L0.5 L1 L2 L3 L4 L5 · cites 6
0ADR-037: Bottom-up diamond progression #
⚠️ AMENDED 2026-06-20 (D-2026-06-20-N1) · the VERSION-policy layer of this ADR is superseded. The core decision is INTACT · bottom-up layer progression · no feature-milestone defer · every feature built as its layer is reached. What changes · the "forever-v0.x · no v1.0 target ever" framing (ADR-002) is RETIRED → real semver toward a 1.0 launch. Thev0.8X.Ylayer-tag scheme below is a historical record · the engine is now 0.90.0 (RC-grade) →1.0.0-rc.N→ 1.0.0 launch → 1.x minors add the remaining crates additively toward the 42-crate target → 2.0 = the Connectome era. The bottom-up ordering still governs which crate admits next; only the public version number now CLIMBS to signal maturity instead of sitting at 0.x forever. Original body preserved per cross-source-validation §2.7 (zero silent rewrite).
Status #
Accepted 2026-04-17 night post-brainstorm (Q-plan 1a/2a/3b/4b/5-both/6a). Amends ADR-028. Cascade: ROADMAP restructure, FCI-007 re-eval, crate count target revised 40-42 → 50-90 (cap 100 unchanged).
Context #
Nika Diamond shipped 6 admitted L0/L0.5 crates + 1 WIP (nika-schema) by 2026-04-17. Throughout the first 6 admissions, the ROADMAP carried arbitrary version gates:
v0.81— Foundationv0.90— Ship (pck + providers)v0.95— Cortex (9 memory satellites)v0.100— Plugins (WASM host + sandbox)
These gates encoded a feature-milestone scheduling model: ship core, then Cortex later, then plugins later. In practice this produced:
- Stubs that pretend to implement reserved traits (
MemoryStoreinnika-kernelwith no satellite impl in sight until v0.95). - Version-labelled drift — docs + specs referenced "target design — arriving at v0.95" as if it were a commitment.
- Shadow zones — the gap between "reserved" and "implemented" accumulated residue (invariants drift, type changes needed later).
- Fake ambition — any mention of "we'll ship X at vN.M" is a promise we cannot keep with forever-v0.x.
User said 2026-04-17 night:
"c'est une mauvaise chose de le faire en différé. on a pas la bonne logique v0.95 v0.100. je veux vraiment qu'on fasse toutes les features au fur et à mesure en partant du bas du diamant et on remonte."
Translation: defer = bad logic. Build every feature as its layer is reached, from the bottom of the diamond upward.
Decision #
Abandon feature-milestone scheduling. Adopt bottom-up layer progression:
L0 (~9 crates) foundation types, pure, sync ↓L0.5 (~2 crates) kernel traits (sealed, ISP, async OK in defs) ↓L1 (~20+ crates) effect impls — fs, http, process, git, memory-*, provider-* ↓L2 (~10+ crates) verbs + domain services + memory orchestrator + pck ↓L3 (~5 crates) runtime + shield + wasm-host + sandbox ↓L4 (~7 crates) interfaces — cli, lsp, daemon, mcp, sdk, serve ↓L5 (1 crate) the `nika` binaryEvery crate admits atomically with 12 gates. Every admission = 1 commit = 1 v0.80.N tag increment.
What changes #
- ROADMAP.md restructure — replace
v0.81/v0.90/v0.95/v0.100section headers with layer-progression sections. No calendar targets. No "this ships at vN.M" language. - ADR-028 re-scope — distinguish:- **API type reservation** (non_exhaustive ratchet, reserved fields in InferRequest/InferResponse, kernel trait surface) — KEEP. Legitimate forward-compat work. - **Feature scheduling** (we'll ship Cortex at v0.95) — REMOVE. Bad diamond.
- FCI-007 `unstable-cortex` re-evaluate — if Cortex ships layer-by-layer without defer, we don't need a feature flag gating it. Either drop or repurpose as per-crate experimental opt-in.
- Version tagging — Q-plan 3b LOCKED:
v0.8X.Ywhere X climbs per layer-phase completion, Y increments per admission within a phase.- `v0.80.N` → current baseline (L0 partial, L0.5 complete) - `v0.81` → L0 complete (9 crates admitted) - `v0.82` → L1a primitives complete (fs, process, http-client, keys-env) - `v0.83` → L1b deps-étage-1 (git, keys-keychain, catalog-sync) - `v0.84` → L1c providers (rig + openai-compat + mock) - `v0.85` → L1d pck backend (registry + store) - `v0.86` → L1e memory foundation (embed, store-fjall, autodesc, hnsw, bm25, rrf) - `v0.87` → L1f memory advanced (temporal, fsrs, rdfs-reasoner, graph-algos) - `v0.88` → L1g reserved satellites (as demand emerges: causal, episodic, working, meta, procedural, spatial) - `v0.89` → L2 complete (verbs, orchestrators, builtins) - `v0.90` → L3 complete (runtime, shield, wasm-host, sandbox). **NOT a "ship" tag** per Q-plan 6a. - `v0.91` → L4 complete (cli, daemon, serve, mcp, lsp, sdk) - `v0.92` → L5 binary first full-stack integration - `v0.93+` → polish, optimization, quality iterations - ~~Forever-v0.x — no v1.0 target ever.~~ (amended D-2026-06-20-N1 · real semver toward a 1.0 launch · this layer-tag scheme is now a historical record · see top banner) - Total crate count target — Q-plan 1a LOCKED: 40-42 → 50-90 crates (cap 100 unchanged). Growth driven by 14-crate memory subsystem, 4 storage backends, ~30 provider crates, own
nika-embed, WASM host + 3 sandbox crates. - Dedicated deep-dive sessions reserved — Q-plan 5 LOCKED both:- **Session nika-memory** — most-ambitious B1-B5 validated 2026-04-17 night. Design 14 crates (8 core + 6 reserved). Runs FIRST (stabilizes kernel memory traits before L1 memory admission). - **Session nika-registry** — backend + publishing policy. Runs after memory.
- "v0.90 ship target" DROPPED — Q-plan 6a. Versions 0.9X are just layer tags, no marketing ceremony. (Amended D-2026-06-20-N1 · the 1.0.0 launch is now the marketing moment · 0.9X stays RC-grade pre-launch · per top banner.)
What stays the same #
- 12-gate admission model (unchanged).
- 28+ invariants (all still binding).
- 7 shadow zones (still pre-launch quality gates).
publish = falseon foundation crates (ADR-022 unchanged).- The release model (ADR-002) — amended D-2026-06-20-N1 to real semver toward a 1.0 launch (was "forever-v0.x · no v1.0 target").
Ordering within a layer #
Dependencies-first topological order. If two crates have no dep relation, tiebreaker:
- User-value-first (which unlocks a demo or blocks downstream first).
- LOC-smallest-first (easier wins early build momentum).
- Effect-axis-smallest-first (fewer capability axes = lower review burden).
Example L1 candidates in topological order:
nika-fs(L1, reads-fs rw-fs, no deps on other L1)nika-process(L1, exec-shell, no deps)nika-http-client(L1, net-egress, no deps)nika-git(L1, depends onnika-fs+nika-process)nika-memory-*(L1, each independent, 8 core + reserved)nika-<provider>-*(L1, depend onnika-http-client)
Consequences #
- ✅ Bottom-up integrity — no fake feature-milestones, no version-labelled residue (the anti-defer discipline survives the D-2026-06-20-N1 real-semver amendment; only the version labels changed, not the build order).
- ✅ Every admitted crate is REAL code, not stub. No "v0.95 target design" banners in docs.
- ✅ Linear ROADMAP — users see "what's admitted, what's coming up in this layer, what's above".
- ✅ Tagging discipline —
v0.80.Nmonotonic, no backtracking, no retroactive milestone rewrites. - ❌ Harder to communicate "when does Cortex ship" — answer is "when we reach L1/L2 memory satellites, and never before then".
- ❌ Existing docs (ROADMAP sections, spec drafts, adr-036 MSRV body) that reference
v0.90/v0.95/v0.100need cascade edits. - ⚠️ Some speculative scheduling (nika-sdk crates.io publishing, MSRV cadence) currently pinned to v0.90 — adr-036 must be reworded to say "at whichever tag crosses L4 interface completion" rather than "v0.90".
Alternatives considered #
- Keep version-milestone gates but clarify they're goals not deadlines — fails because docs still communicate false scheduling.
- Hybrid: layer-progression as primary, version labels as secondary guidance — fails because version labels re-encode the deferred-scheduling mindset.
- Skip ADR-028 revision, just restructure ROADMAP — fails because ADR-028 still uses "reservation for v0.95 Cortex" language that contradicts this ADR.
Cascade plan (post-acceptance) #
- Restructure ROADMAP.md (1 commit).
- Re-scope ADR-028 (1 commit, Under Revision → Amended).
- Re-evaluate FCI-007 (1 commit in
forward-compat-invariants.md). - Update CLAUDE.md narrative (1 commit).
- Reserve dedicated sessions for nika-memory + nika-registry (memory files, no commits).
- Rework adr-036 MSRV body to remove v0.90 references (1 commit).
- Constellation reconciliation report: Note Option A/B/C oxigraph rename deferred to nika-memory session (1 commit).
See also #
- ADR-001 — Diamond orphan branch.
- ADR-002 — release model (amended D-2026-06-20-N1 · real semver toward 1.0 · was "forever-v0.x").
- ADR-003 — 12-gate admission.
- ADR-004 — Context-window-sized crates.
- ADR-028 — Forward-compat reservation policy (amended by this ADR).
philosophy_bottom_up_diamond_2026_04_17.mdin memory — full brainstorm record.
🦋
read at v0.107.0 · the decision record ships with the engine