AGPL-3.0-or-later · forever.

ADR-037

Bottom-up diamond progression (no feature-milestone defer)

accepted · 2026-04-17 · L0 L0.5 L1 L2 L3 L4 L5 · cites 6

0

ADR-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. The v0.8X.Y layer-tag scheme below is a historical record · the engine is now 0.90.0 (RC-grade) → 1.0.0-rc.N1.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 — Foundation
  • v0.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:

  1. Stubs that pretend to implement reserved traits (MemoryStore in nika-kernel with no satellite impl in sight until v0.95).
  2. Version-labelled drift — docs + specs referenced "target design — arriving at v0.95" as if it were a commitment.
  3. Shadow zones — the gap between "reserved" and "implemented" accumulated residue (invariants drift, type changes needed later).
  4. 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:

text
L0    (~9 crates)     foundation types, pure, syncL0.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 + pckL3    (~5 crates)     runtime + shield + wasm-host + sandboxL4    (~7 crates)     interfaces — cli, lsp, daemon, mcp, sdk, serveL5    (1 crate)       the `nika` binary

Every crate admits atomically with 12 gates. Every admission = 1 commit = 1 v0.80.N tag increment.

What changes #

  1. ROADMAP.md restructure — replace v0.81/v0.90/v0.95/v0.100 section headers with layer-progression sections. No calendar targets. No "this ships at vN.M" language.
  2. 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.
  3. 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.
  4. Version tagging — Q-plan 3b LOCKED: v0.8X.Y where 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)
  5. 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.
  6. 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.
  7. "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 = false on 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:

  1. User-value-first (which unlocks a demo or blocks downstream first).
  2. LOC-smallest-first (easier wins early build momentum).
  3. 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 on nika-fs + nika-process)
  • nika-memory-* (L1, each independent, 8 core + reserved)
  • nika-<provider>-* (L1, depend on nika-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.N monotonic, 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.100 need 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 #

  1. Keep version-milestone gates but clarify they're goals not deadlines — fails because docs still communicate false scheduling.
  2. Hybrid: layer-progression as primary, version labels as secondary guidance — fails because version labels re-encode the deferred-scheduling mindset.
  3. 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) #

  1. Restructure ROADMAP.md (1 commit).
  2. Re-scope ADR-028 (1 commit, Under Revision → Amended).
  3. Re-evaluate FCI-007 (1 commit in forward-compat-invariants.md).
  4. Update CLAUDE.md narrative (1 commit).
  5. Reserve dedicated sessions for nika-memory + nika-registry (memory files, no commits).
  6. Rework adr-036 MSRV body to remove v0.90 references (1 commit).
  7. 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.md in memory — full brainstorm record.

🦋

read at v0.107.0 · the decision record ships with the engine