Skip to main content
This is a historical archive, preserved as written. Statements such as “current”, “ships” and “these docs teach” refer to the date of each entry. Some entries describe tags whose release builds failed. They are not installation instructions. Use the published release index, current status and installation guide for what you can use today.
The timeline guide explains the eras and evidence classes. The accounts below predate the automated release inventory and are retained without rewriting their original claims.
releaselanguage
2026-08-19 · the first published nine-key binary · Linux builders jail before the gates run
The second refusal, one layer down. v0.109.1 fixed the fossil envelope in the release gates and died on both Linux builders one leg later: [consent-run] exit=3 want=4 — since 0.109.0 a workflow that declares permits: refuses to start on a host with no sandbox backend (NIKA-1710), and a GitHub Linux runner has no bubblewrap. The macOS builders, where seatbelt exists, passed both gates confined. No asset shipped under v0.109.1 either; the binaries were fine both times. This patch is the same tree plus the second fix and is the version consumers install.
  • The Linux release builders install bubblewrap before the gates run. The Diamond CI tests-leg recipe (apt bubblewrap · detach ubuntu-24.04’s AppArmor bwrap profile · keep unprivileged userns open) now runs on the two Linux builders, so the funnel e2e and the trust battery run confined there exactly as they do on macOS — never a waiver. A gate that spends an exec under permits: proves the jail as a side effect; a host that cannot jail says so (NIKA-1710) instead of being waved through.
These docs teach 0.109.2 (measured 2026-08-19). A file written for 0.108 meets a refusal that names its replacement; nika check --fix moves the mechanical parts.
releaselanguagebreaking
2026-08-19 · the first published nine-key binary · the release gates speak the live envelope
The release the release gate refused. v0.109.0 was tagged from f58a17396 and its own pre-upload gates killed all four builders: the funnel e2e and the trust battery still authored their fixtures in the fourteen-key envelope (nika: v1 + workflow:) the nine-key engine refuses at parse. No asset was published under that tag; the binaries were fine and the gate was the fossil, exactly as v0.106.0 died on 2026-07-27 when the battery spent an exec without a permits: block. v0.109.0 stays a tag with no release; this patch ships the same tree plus the gate fix and is the version consumers install. The language change itself is the v0.109.0 entry below.
  • The release gates speak the live envelope (funnel e2e · trust battery). Four fixtures move from nika: v1 + workflow: to nika: <id>. Nothing else in the gates changes: the consent-dirty leg still expects NIKA-SEC-014 at guard and check, the consent-pause leg still expects exit 4 with the resume line, the trust battery still runs its exec under permits.exec.
  • Hygiene vector 50 · check-release-gate-envelope. The two gates run only at tag time, so a language change on main could leave them teaching the previous envelope for weeks with nothing red on any push. The vector greps both scripts for the dead envelope forms on every push and is RED on any hit — proven by mutation (one restored fixture → red).
These docs teach 0.109 (measured 2026-08-19). A file written for 0.108 meets a refusal that names its replacement; nika check --fix moves the mechanical parts, the table below names the hand moves.
releaselanguagebreaking
2026-08-18 · the nine-key release — tagged, no binary shipped (install 0.109.1)
The nine-key release. The envelope shrinks from fourteen keys to nine and a workflow written for 0.108.0 will not check on 0.109 · this is the flag-day the 0.106.0 front page announced as possible, and it lands whole. The identity moves onto nika: itself (nika: <id> · a kebab-case name · the workflow: block, its id: and its description: are gone), the value authorities are exactly three (inputs · const · secrets · config: died with the block), types: · policy: · assert: leave the envelope, and the task body loses its second grammars: cleanup is a real task on an unwind edge (on_finally: is dead · graph_format: 3 carries the finally node), output: is spelled extract:, declassify: and inert: merge into one door (lift:), fail_workflow is gone (on_error is recover or skip), the two fan-out knobs live INSIDE for_each:, and group: arrives (fan-in · NIKA-DAG-008). Two P0 close at the surface users install: an expression sees only its INPUT (the ambient env leaves the jaq function set at the three seams, with a pinned inventory of natives that reddens if a future jaq adds one), and a third-party receipt can no longer write the operator’s clipboard (every field rides escape_tty). The refusal a 0.108.0 file meets first now TEACHES where each retired key’s role went, instead of unknown field.Tagged 2026-08-18 · no binary shipped under this number. The tag’s own release gate refused the upload (its fixtures still spoke the fourteen-key envelope), so nothing was published as 0.109.0. The first published nine-key binary is 0.109.1, the same tree plus the gate fix — that is the version to install.① The envelope · fourteen keys become nine (ADR-113). The live envelope is nika · model · inputs · const · secrets · permits · run · tasks · outputs. Every other top-level key refuses, and the refusal names the destination:② The task body · one grammar per thing.③ What nika check --fix migrates · and what it does not. The rungs are idempotent and equivalence-or-stop · r1-identity (new · nika: v1 + workflow: {id, description} · the block, the pre-W1 scalar workflow: <id>, the one-line flow form, a bare top-level description: · become nika: <id> with the prose demoted to a # comment ABOVE it, never dropped · it STOPS, never guesses, when nika: already names something else, when the block carries a foreign key, when the id is not kebab-case, or when there is no id at all) · w1-map (a tasks: sequence becomes the map · atomic or nothing) · w2-flow (depends_on + body tasks.* reads become with: bindings and after: predicates) · d1-split (the pre-0.103 string command:) · esplit (vars:inputs: / const: · classify-not-rename) · predicates (succeededsuccess). One --fix runs them all in one loop, so a 0.108.0 file whose only sins are the identity and the tasks list heals to green in one command. Every round is a transaction: a repair whose text no longer parses is rolled back and reported, and the file is written once, from committed text only.Still hand migrations in this release · the on_finally: restructuring (cleanup becomes its own task on an unwind edge), output:extract:, declassify:/inert:lift:, config:inputs: (a classification), and the for_each re-nesting · the refusal teaches each destination at the point of refusal and --fix leaves the file untouched rather than write a document its own checker would reject. Measured on the pack that ships inside this binary: 0.108.0 passes 0/40 of these examples · 0.109 passes 40/40 · every existing file outside this repo sits on the 0.108.0 side of that line until it is migrated.④ Two P0, closed where users install. An expression sees only its input (#959): a nika:jq expression could read the ambient environment (env.PATH) under an ABSENT permits block while check printed « the body is pure compute so nothing escapes »; the retained natives leave the jaq function set at the three seams from ONE list, and a pinned inventory of jaq natives reddens if a future jaq adds one. A third-party receipt wrote the operator’s clipboard (#958): three fields of a proof receipt reached the terminal without escape_tty while the helper existed in the same file · a foreign evidence pack could emit OSC52; every receipt field rides the escape, proven by mutation before publication.⑤ The two trains. stable is the newest tag · what brew · the Registry · nika-action and the starters install. next is main, at <next>.0-dev between tags · a real semver prerelease · nika --version and every trace say which one they are. Stable consumers move only when a tag they can install exists.
releaseaccesssecurity
2026-08-05 · the access layer arrives · the check stops trusting what it cannot read
The access layer arrives; the check stops trusting what it cannot read. Three steps of the access ratification land: access picks the path, model: picks the intelligence — a deterministic resolver with a strict sovereign order (local < mock < harness < oauth < api), an --access <path> pin on run and try judged at the launch gates (unsatisfied refuses with NIKA-1800/1801/1802, never substitutes), and the ACP harness class (nika-acp · ACP 2.0.0 = wire v1) with its mock agent in a quarantined workspace and the kernel’s AgentBackend seam. The zero-authority scan now refuses every exec spelling, the shell form included. Fixed alongside: the doubled catalog-miss advisory, the taught surfaces that misdirected, two more sandbox tightenings, a resumed run that keeps its seat, and every pack skeleton passing its own golden lane. Proven red-first, like everything on this train.
releasetrustclibreaking
2026-08-01 · the trust release — three doors, one honest machine
An outside audit measured the experience instead of the feature list — five waves, seventy-two receipts, twenty-two P0s — and the arc closed every one. Consent means consent: a non-affirmative answer fires zero effects (NIKA-SEC-014, minted spec-first with its conformance fixtures). The hooks’ judge moved into the binary (nika guard, fail-visible). Autonomy is graded before it is colored — the risk rung never renders green past Supervised. The data journey names sources, destinations and secrets before the run, and redaction works by provenance: a one-byte secret dies the same death as a long one.The teaching grammar collapses to three doors. nika try [slug] is the showroom — offline by default (the mock rehearsal · zero keys · zero flags), nothing written, nothing owned; bare nika try lists what there is to see. nika new takes ONE positional gesture: plain words route across the whole catalog, an example slug lands verbatim WITH its ingredients, a skeleton name instantiates (nika new '?' lists the set). nika init founds. The old doors die loudly:A human gate can no longer kill a first run. A nika:prompt with no default: used to die in milliseconds on every text-mode run. The rider is now armed on every lane: unattended runs pause durably (exit 4, the pause journaled, never a failure frame), and at a terminal the gate asks you directly — confirm [y/N], choice, or input — leaving a paste-able resume line that carries the run’s own --var/--model.Around the core, the doors multiplied honestly: nika wire previews and never rewrites unasked, six clients join the targets (grok · antigravity · kimi · kiro · copilot · amp — wire all covers twenty-one), and nika init writes the two project MCP doors (.mcp.json + .agents/mcp_config.json), handing the read-only oracle to agent surfaces with zero machine wiring. nika doctor gives every probed host a capability receipt and names kit↔binary train drift with the exact align command. Cost honesty grows an energy rung (NEP-0018 — watt-hours beside dollars), and a priced backend that omits token usage now fails closed.These docs teach 0.107 and only 0.107. The 0.106 value/permits grammar is unchanged — what moved is the CLI’s teaching surface. Pin the tag you run.
releaselanguagesecuritybreaking
2026-07-27 · the values get names, the boundary gets teeth
Two flag-days land in one window, and both are the same idea: a thing the file left implicit becomes a thing the file declares.① The E-split — vars: and env: die into four named authorities. One block for everything a workflow knew was a block that told you nothing: whether a value came from the caller, from the deployment, or from the file itself was invisible, and so was whether it could be trusted. The family is now closed at four, one role each — inputs: (the caller supplies it at launch) · config: (the deployment supplies it, and it may appear in logs) · const: (the file owns it, immutable) · secrets: (a governed store, masked). inputs.* and config.* are untrusted (they come from outside the file); literals, const.* and secrets.* are trusted — which is why a destination a permits: entry pins belongs in const:, where no caller can move it out from under the boundary.The old spellings refuse loudly, and they refuse with a classification, not a rename: there is no mechanical vars:inputs: (that is how you end up with a caller-overridable output path). Each use is classified into the authority its role commands; nika check --fix migrates the provable cases and stops on the rest rather than guessing.② An absent permits: block declares ZERO authority. It used to mean “engine floor only” — a hint, and a green check. It now means what its absence always should have: no filesystem, no network, no shell, no tools. Every effect the body requires is refused at check with NIKA-AUTH-006 before a single token is spent, and any effect that reaches run time fails the task with NIKA-SEC-004. A pure-compute workflow still passes; permits: {} is the authored spelling of “I touch nothing”; and under composition the absence is a wall — a parent’s grants never flow down implicitly (NIKA-COMP-002). The repair is one command: nika check --infer-permits walks the DAG and prints the tightest boundary the body actually needs, ready to paste.Also in the window: an envelope run: block declares the run’s entropy and clock ({ entropy, clock }, closed) — randomness and time stop being ambient, and entropy: { seeded: N } + clock: virtual make two runs of the same file byte-identical. The dimensions couple, so a declared contradiction refuses at parse (NIKA-PARSE-026 / NIKA-PARSE-027).These docs teach 0.106 and only 0.106 — no dual grammar, no “if you are on 0.105” branch. Pin the tag you run.
releaselanguagesecuritybreaking
2026-07-20 · the map comes home
The refonte reaches users — the file becomes a map. workflow: is an object (id: + description:), tasks: is a map keyed by id, and precedence reads the way you think: the binding IS the edge (with: x: ${{ tasks.a.output }} declares the data edge) · control-only ordering is after: {producer: succeeded} against a closed predicate set (succeeded · failed · skipped · terminal). The old forms die loudly — a scalar workflow: is NIKA-PARSE-020, depends_on: is NIKA-PARSE-024 — and nika check --fix machine-migrates the provable cases. The proof layer opens: semantic hash + nika.lock + receipt_format: 1, workflow composition (invoke: workflow:), and nika:decide, the deterministic decision kernel. One security seat ships in this tag: the lethal-trifecta judge (NIKA-SEC-009) refuses private-read + untrusted-ingress + external-egress with no blocking human gate on the path. The LSP learns the map end-to-end (server-side rename · per-block keysets · semantic_document_format: 1). Every surface you copy from re-baked the same day — the site, these docs, the templates and the kit speak the released grammar (the serve-time door law: what you copy runs on YOUR installed binary). Thinking-model note, same honesty as the K3 seat: reasoning spends max_tokens — budget generously or declare thinking:; an empty answer says why.
releaseproviders
2026-07-17 · the seventeenth seat
Moonshot (Kimi) joins the canonical catalog — 17 providers (11 cloud · 5 local · 1 test). model: moonshot/kimi-k3 runs Kimi K3 first-class: 1M context, MOONSHOT_API_KEY, and the pricing snapshot makes --max-cost-usd a hard ceiling on kimi spend (the promotion run metered 0.002787againsta0.002787 against a 0.0077 printed worst-case). K3 is a thinking model — reasoning spends output tokens, so budget max_tokens generously (512+; at 64 the answer comes back empty and the engine says why). Weights are announced open on July 27; until then the hosted API routes through Moonshot’s servers with training-by-default — read the permits section of your workflow as the data-residency contract it is: no declared egress, no call. Also in this wave: the lsp/graph/mcp test fixtures that shipped red at the v0.103.0 tag now speak the argv form (a CI-coverage gap banked as a finding), and the tag’s rustfmt drift is cleared. Release branch cut from v0.103.0 — main is mid-refonte and users never ship a transitional grammar. Spec side: ADR-105 + stdlib 16→17 + the escape-hatch doc now names the real variable (NIKA_OPENAI_BASE_URL, complete endpoint, verbatim).
releaselanguagebreaking
2026-07-13 · the language tightens
The pre-1.0 window pays for itself — three breaking cuts in one wave, spec and engine merged in the same window. command: is argv-only (["cargo", "test"] — execve, no shell: an interpolated value can never break out of its argument) and the string form moves to shell:, the explicit door — semantics ride the field, never the YAML type. A bare ${{ tasks.X }} is now an error (NIKA-VAR-020): name the projection — .output / .status / .error / .duration_ms. And the gate algebra (upstream terminal × gate form → downstream status) becomes a normative spec table — the when-status pattern is a propagation choice, not redundancy. ~530 corpus sites migrated; docs, site, editor, kit and registry re-taught in lockstep.Engine release
releaselspeditor
2026-07-13 · the editor speaks the language
The LSP arc lands server-side: the pause after a colon answers itself (space joins the triggers), args: keys complete from the tool’s own schema, mode: enums scope to the enclosing tool, ${{ vars./secrets./env. }} complete from the FILE’s declarations, hover cards read the graph (wave k/N · transitive reach · model fallback tiers), and references resolve closure-aware. Plus: wave-sweep.sh (the one-command release sweep) and three new coherence-bot probes born from drifts caught by hand.Engine release
releasesovereignmodels
2026-07-13 · the sovereign lane ships whole
Every release binary now carries local-infernika model pullnika model serve → workflow infer against your own machine: no cloud, no external daemon, no build-from-source wall (#518, the release ruling, executed). CPU on every target on purpose (darwin included) until candle’s quantized rms-norm Metal kernel is fixed. The release funnel now pins the teaching both ways: a shipped binary must never utter « built without local inference ».Engine release
releaseclisovereignagents
2026-07-12 · the terminal sings · the models come home · the kit rides three surfaces
The terminal learns to sing: a verb band colors every task by its verb, the spinner is a real live probe, and nika run paints the DAG as living wire-art in-frame — states, in-node spinners, edge pulses — while nika inspect --format json|mermaid|dot becomes the ONE graph projector (now projecting declared policy too: retry · timeout · on_error · outputs). nika init becomes a founding wizard (recipes, themes, wiring — everything asked before the first write) and equips a repo for 15 agent surfaces project-side, Cursor subagents + seatbelt hooks included. The models come home: nika model pull/list/rm (one models dir by construction, resumable verified downloads) and nika model serve (the sovereign sidecar, OpenAI-compatible on loopback) close the local loop — pull → serve → workflow infer, trace-chained. nika check --fix is an in-binary repair loop that converges; the machine dry-run ships one versioned plan object; a paused run teaches its exact resume command; registry refs run verified (nika run @org/flow). The agents kit becomes a suite — 4 skills · 3 subagents · 5 commands · 3 seatbelt hooks in ONE dialect across Claude Code, Cursor and Codex (probe-proven) — and the LSP ships code actions: every check --fix rename lands as a quickfix in any editor. Wire waves add claude-desktop, cline, continue and qwen (12+ targets).
releaseauditstdlib
2026-07-10 · the MODELS rung · two media builtins graduate · the boundary earns its valve
The check ladder earns its MODELS rung: every model: must resolve in THIS binary — a bare id (gpt-5-turbo) or a provider the resolver cannot drive is a finding with the fix taught in-line, pricing refuses to price what cannot resolve (unpriced beats conjured), and the MCP nika_check lane obeys the same law. Two media builtins graduate: nika:image_fx (15 deterministic op families — dither · duotone · halftone · glitch · ascii — over a hand-rolled zero-dep PNG codec, the recipe riding the tEXt chunk) and nika:chart (five chart types compiled to byte-identical SVG, parity proven across architectures); both artifacts sha256-chain into the trace. Egress to outputs closes the one documented information-flow gap: a sink-only, secret-specific declassification of the workflow boundary itself — every embedded template now passes its own audit, zero exceptions. nika explain --forecast computes duration/cost/risk priors from YOUR local traces (p50/p90 earned at n ≥ 5 — deterministic stats, never a model call). nika wire covers opencode and hermes (8 targets), the missing-input trap teaches at check time, and the release tarball is funnel-gated — a stranger’s broken first run never uploads.
releasestructured-outputonboarding
2026-07-08 · native answers · the checker closes run-fail gaps · one lexer
Structured output goes native per provider — Anthropic’s output_config.format, Gemini’s responseJsonSchema (the lossy converter dies), OpenAI strict-mode honesty (not/allOf stripped at the wire instead of 400ing) — with a coercion ladder that repairs case-folded enums, string numbers and singleton arrays before any PAID retry. The checker closes gaps that used to fail at run: the compact block-sequence bomb that aborted every check/run is caught as NIKA-PARSE-001, max_turns bounds and for_each over a typed non-array are check-time findings, and env: binds at run exactly as checked. The ${{ }} scanner becomes its own crate (nika-tmpl), shared by checker AND runtime — parity by construction. And the first 30 seconds learn to speak: nika welcome mirrors your machine, nika explain <file> narrates a workflow (cost honesty included), nika init briefs six agent surfaces, --max-cost-usd refuses to start when the static floor already exceeds the budget.
releasetrust
2026-07-07 · the run becomes evidence
Every journal line carries a hash chainnika trace verify walks it and names the first broken link; export and replay check the chain before trusting the data. nika trace reproduce compares a recorded run against a fresh one and classifies every task (reproduced · nondeterministic · authored · environment). The journal attests its engine (engine_version + platform on workflow_started). Models are priced before the first run — 602 rules refreshed from models.dev, per-model rates in check --json (the VS Code preflight shows $in/$out per 1M on this tag). check IS the dry-run — the plan names what dispatches in which wave. doctor --json speaks machine; bare nika init/new converse on a terminal; and the dap drift warn tells a re-encode from an edit (workflow_sha256_lf).
releasedebugging
2026-07-06 · the run becomes a place
nika dap brings time-travel replay debugging over the run journal — breakpoints in your .nika.yaml, step forward AND backward, recorded outputs in the Variables pane; the VS Code extension’s F5 integration lights up on this tag. nika trace export projects any journal to OTLP/JSON lines (Jaeger · Grafana · Langfuse — cost rides gen_ai.usage.cost). nika check --json gains the requirements section (models · keys · secrets · env) so editors and CI state blockers before any token. A typo’d field now teaches: « unknown field infr — did you mean infer? ». Runs record their source (workflow_sha256) and skips say why (when · blocked_by). Plus: doctor —ping v2, strict boolean args, the opt-in CSV formula-injection guard.
releaseproviderslocal-first
2026-07-06 · the catalog practices local-first
The 5 local servers (Ollama · LM Studio · llama.cpp · LocalAI · vLLM) join nika catalog with descriptions, tags and seed models — keyless by construction, and sovereign models stay unpriced, never « free ». 38 providers in the engine’s catalog inventory (the canonical spec set stays 16). A bare nika now suggests the next command instead of a wall of help text. Fixes: nika:write honors create_dirs: false loudly, nika:date resolves named timezones from the bundled db, nika:log neutralizes terminal control sequences, and the MCP stdio transport bounds its line reads.
releasemediaproviders
2026-07-06 · the media suite · every run leaves a journal
Two media builtins take the stdlib to 25: nika:image_generate (generation and editing, local-first providers, provenance manifests, content credentials preserved) and nika:tts_generate (one sovereign /v1/audio/speech wire · a real deterministic WAV under mock). Every run now writes .nika/traces/ by default and --task scopes execution to one upstream cone. The catalog rides the wire (catalog/tools --json plus their MCP twins — the read-only tool set on protocol 2026-07-28), cost_usd rides task_completed without ever faking a zero, Hugging Face and NVIDIA join the 16-provider canonical catalog, and nika doctor --ping actually probes the local ports.
releaselocal-first
2026-07-05 · the embedded pack teaches 2026 models
The pack vendored into the binary carries the qwen3.5 teach-cascade: the first nika examples run 01-hello of a fresh install works against the local models people actually pull in July 2026. Plus the README daily-commands block — the full 0.93 user loop in one place.
releaselocal-firstdebugging
2026-07-05 · resume · test harness · local thinking models unbricked
Provider-plane HTTP timeout rises to 180s: 2026 open-weight thinking models (qwen3.5 · gemma4) no longer die at the cloud-calibrated 30s ceiling. nika run --resume lands durable-lite resume — the trace IS the checkpoint, completed tasks replay as visible cache hits (ADR-099). nika test golden harness + ADR-098 schema wire selection + the CLI verdict card. nika-cap admitted (all 12 gates) — 40 of 42 crates.
releaseagentssecurity
2026-07-03 · MCP learning tools · codex wire · exec hardening
The MCP oracle grows the learning tools (nika_schema · nika_examples · nika_template · nika_canon). nika wire codex patches ~/.codex/config.toml; the Claude Code marketplace ships one plugin dir for two ecosystems. Exec hardening: provider API keys scrubbed from exec children · env keys restricted to POSIX names · browser navigation guarded against private/loopback SSRF.
releasepackaging
2026-06-25 · onboarding wiring · headless builds
Explicit onboarding wiring in the CLI · nika examples run takes a --model override with an offline mock hint · headless build fixes (xcap backend default-off · atspi 0.29) · doctor recognizes the workspace Cursor MCP config · release pipeline separates the dev version from brew assets.
releasemilestonepackaging
2026-06-21 · the first public release
Diamond’s first tagged public release. CLI binaries for four platforms (macOS arm64/x64 · Linux arm64/x64) via Homebrew and the install script, cut by the release pipeline on the tag. nika-cli and nika-extract admitted the same morning — the operator surface and the 9 fetch extract modes. Real semver toward a 1.0.0 public launch — quality over speed. Everything before this tag is rewrite history.
foundationmilestone
2026-06-10 → 2026-06-21 · 23 crates in twelve days
The sprint that turned a foundation into a runnable engine. June 10: the kernel splits into four siblings (core · ai · runtime · plugin) and the effect crates land — nika-fs, nika-http, nika-blob, nika-exec-runner, nika-input. June 11: nika-pack, nika-providers, nika-browser, and all four verb crates admitted the same dayinfer · exec · invoke · agent. June 12: nika-runtime (the DAG scheduler). June 15-18: nika-lsp, nika-mcp, nika-builtin, nika-schema. June 21: nika-cli + nika-extract — and the v0.90.0 tag ships that evening.
foundationlanguage
May 2026 · the spec goes public · 7 crates climb
The month the language reached its final shape, in the open nika-spec repo (Apache-2.0): the nika: v1 envelope (one field, forever), the four verbs locked (infer · exec · invoke · agent — everything else is a tool under invoke), CEL + jq as the only two expression layers, agent tools default-deny, and the stdlib curated down to 22 builtins with zero capability loss. Meanwhile the climb continued: nika-catalog-codegen (May 10), nika-bm25 (May 12), nika-event + nika-clock (May 24), nika-screen + nika-ocr + nika-a11y (May 25).
foundation
2026-04-17 · hygiene vectors · forward-compat seams · telemetry seeds

Added

  • 4 new hygiene vectors (30-33): check-cancel-safety.sh, check-owned-strings.sh, check-unsafe-count.sh, check-layer-deps.sh — the suite reaches 33 active vectors.
  • Forward-compat reservations: 5 seams pre-planted for the memory subsystem + WASM eras: EmbeddingSpec, MemoryFrameRef.trust, RecallQuery.tenant, WasmPluginError::OutOfFuel + PluginCallContext, MemoryLifecycle trait.
  • Telemetry seeds: SpanGuard.parent_span_id + W3C Trace Context linkage; Timestamp(i64 unix_ns) + WallDuration in nika-types::timestamp with RFC 3339 Display.
  • Test depth: 14 new proptest properties (TrustLevel lattice invariants, ID serde roundtrip); Loom interleaving tests for CancelCtx; a mutation baseline for nika-error.
  • 5 new ADRs: ADR-029 → ADR-032 + ADR-035 (telemetry seams).

Changed

  • ObservabilitySink dropped → 5 sibling channels (Event · Metrics · Trace · Audit · Billing).
  • Engine hygiene enforces RED as fail / YELLOW as suggestion for routine pushes.
foundation
2026-04-14 · nika-catalog-verify admitted
Crate admitted: nika-catalog-verify (L4, 600 LOC, 9 tests, all 12 gates green). The first L4 interface crate: validates all catalog TOMLs at build time via cargo run -p nika-catalog-verify.
foundation
2026-04-13 · nika-kernel + nika-kernel-mock admitted
Crates admitted: nika-kernel (L0.5) + nika-kernel-mock (L0.5). 40 ISP traits with sealed supertrait discipline. trait_variant::make for async dynamic dispatch. Pure-memory mocks for hermetic test environments. Preludes re-export nika-types + nika-error types for ergonomic downstream imports.
foundation
2026-04-13 · nika-catalog admitted
Crate admitted: nika-catalog (L0). TOML-driven provider + model + capability catalog with build-time codegen, perfect-hash lookup, Cow- heavy zero-copy types. At admission: 105 MCP servers, 32 LLM providers, 13 embedding models in the inventory. Schema FK-check enforced in build.rs.
foundation
2026-04-13 · nika-error admitted
Crate admitted: nika-error (L0). Typed NIKA-XXX error hierarchy, miette integration for L4 diagnostics, per-crate error range allocation, proptest-backed roundtrip invariants.
foundationmilestone
2026-04-13 · the orphan branch · v0.80.0-alpha.0
The rewrite starts. An orphan branch created from scratch (as nika-diamond, renamed main in May 2026) — zero shared history with the brouillon. The constraint that defines everything after: every crate must fit in an AI context window. ≤15k LOC per crate, ≤1,500 per file, ≤100 lines per function, zero .unwrap() in src/, and 12 admission gates before a crate joins the workspace. First admitted crate: nika-types (L0 foundation). The versioning policy said « forever v0.x » at the time; it was later amended to real semver toward 1.0.
originsmilestone
2026-04-09 · 322k LOC · 31 crates · the context lesson
The final sprint says everything about the pace: v0.73 → v0.79 in three days (April 6-8), v0.79.3 on April 9. Fourteen weeks after the first commit, the brouillon engine is a working 322k-LOC, 31-crate system — and it has surfaced the lesson Diamond is built on: at that scale the biggest correctness risk stops being algorithmic and becomes context. No human or AI assistant could hold the system in working memory, so refactors happened by pattern-match, and pattern-match hallucinates. Four days later the rewrite began. The era is preserved read-only on the branch that named it — brouillon, a private archive; nothing ships from it. Diamond reads it, then rewrites from scratch.
origins
2026-02 → 2026-03 · v0.3 → v0.21 in fifteen days
February 18 is the day the language grows teeth: invoke: and agent: land in the AST and the runtime, the MCP client appears, and the provider layer learns tool calling — all in one day. Then the storm: v0.3 (February 19) → v0.10 (February 25) → v0.17 (March 2) → v0.21 with a first language server (March 5). March alone counts 2,900+ commits — the month the brouillon engine became an ecosystem: LSP, security releases, CI/CD, release automation. The era even has a public spine: seven crates.io releases, 0.20.0 (March 4) → 0.47.1 (March 26) — later yanked, listed forever.
originsmilestone
2026-01-01 · the first commit
The first commit lands on New Year’s Day 2026: initial nika v0.1 with strict templating system — followed the same week by DAG validation, event sourcing for the workflow audit trail, and fine-grained executor events. The shape of everything that followed — declarative workflows, a DAG, an audit trail — is visible in week one. ~4,600 commits follow in fourteen weeks. The era carries the name its git branch carries: brouillon — the draft.
origins
summer 2025 → end 2025 · prototypes before the repo
Nika started as a frustration in 2025: useful AI work kept disappearing into chat histories. A great run — a research brief, a review procedure, a data pipeline — lived and died inside one conversation, unrepeatable and unownable. The bet: durable agent work should be source code — one file you can run, diff, review, and keep; local-first; any model; sovereign by default. The idea was tested in code from the start — private prototypes through the summer and fall of 2025, pre-git and testimony-grade, and the timeline labels them exactly that. The first repo commit followed on January 1, 2026.

Full history

CHANGELOG.md

Every crate admission, every hygiene vector deploy, every ADR promotion. Source of truth on the main branch.

Commit history

Every commit on the main branch: atomic, bisectable, Co-Authored-By Nika 🦋.

GitHub Releases

Binaries for every tag: macOS arm64/x64 · Linux arm64/x64 · checksums + per-release notes.

Live state

Current test counts, clippy, hygiene, admitted crate inventory.

Roadmap

What’s next: the 0.9x hardening train, the contract system and the whole Connectome landing before 1.0, the 1.0.0 culmination, 1.x minors completing the layered foundation, then the ecosystem tier.