- ✧ Exploration (summer 2025 → end 2025) — private prototypes before the repo existed: the idea, tested in code that was never meant to survive.
- ✎ Brouillon (January 1 → April 13, 2026) — the named draft: v0.1 →
v0.79.3, a 14-week private sprint that grew to a 322k-LOC engine and
taught the lesson Diamond is built on. The era is called what its git
branch is called:
brouillon. - ◆ Diamond (April 13, 2026 →) — a ground-up rewrite, one crate at a time, 12 gates each; tagged binaries and real semver since v0.90.0 (June 21, 2026).
Canonical source:
CHANGELOG.md
on the main branch. This page curates the milestones; the full history
lives in the repo. Current HEAD {STATUS.head}. Filter entries with the
tags, or subscribe via RSS.
The era model itself is machine-verified: nika.sh/timeline
renders the spec’s timeline/timeline.yaml,
and every provable claim in it is re-proven in CI against crates.io and GitHub.Cadence
Since v0.90.0 (June 21, 2026 · the first public release), every release
is a real-semver tag with binaries: Homebrew, the install script, a
GitHub Release, and a curated
CHANGELOG.md section. Public
accountability, no hidden work.main as:
- Crate admission commits (e.g.,
feat(nika-X): admit to workspace — all 12 gates passed). - Hygiene vector deployments ( active vectors guard the workspace on every push).
- ADR promotions ( total: Accepted, Proposed).
History
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.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.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.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.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).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 releaseThe 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 releaseEvery release binary now carries
local-infer — nika model pull →
nika 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 releasereleaseclisovereignagents
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.Every journal line carries a hash chain —
nika 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).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.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.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.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.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.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.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.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.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 day — infer · 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.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).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,MemoryLifecycletrait. - Telemetry seeds:
SpanGuard.parent_span_id+ W3C Trace Context linkage;Timestamp(i64 unix_ns)+WallDurationinnika-types::timestampwith RFC 3339 Display. - Test depth: 14 new proptest properties (TrustLevel lattice
invariants, ID serde roundtrip); Loom interleaving tests for
CancelCtx; a mutation baseline fornika-error. - 5 new ADRs: ADR-029 → ADR-032 + ADR-035 (telemetry seams).
Changed
ObservabilitySinkdropped → 5 sibling channels (Event · Metrics · Trace · Audit · Billing).- Engine hygiene enforces RED as fail / YELLOW as suggestion for routine pushes.
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.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.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.Crate admitted:
nika-error (L0). Typed NIKA-XXX error hierarchy,
miette integration for L4 diagnostics, per-crate error range
allocation, proptest-backed roundtrip invariants.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.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.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.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.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.