AGPL-3.0-or-later · forever.
Nika · Intent as Code.

Make agent work repeatable.

Nika turns useful agent work into checked workflows your team can run, inspect and own.

Agents explore. Nika makes it repeatable.

  1. Planmeeting-actions.nika.yaml
  2. Checkbefore it runs
  3. Run3 tasks · 4m12s
  4. Proofexit 0
Problem

A good answer once is not a system.

Chat, scripts and automation tools all produce a result. None of them keep the procedure, the limits and the record in one place you own.

A good answer, once.

A chat gives you the result and loses the procedure. The next time, the same work starts from a blank window: no kept plan, no declared limits, no record of what actually ran.

The same work, every time, on record.

Nika keeps the procedure as a file. The plan is checked before anything runs, the run stays inside the limits the file declares, and what happened remains inspectable afterwards.

See the boundary
Capture

The second time starts from a file.

Keep the useful procedure as readable source. The next run starts from this plan, not another blank conversation.

The kept plan
  1. 01
    Read the meeting transcript

    transcript · invoke · nika:read

  2. 02
    Extract every action item, with its owner

    extract · infer · ollama/qwen3.5:4b

  3. 03
    Write the result to a file

    save · invoke · nika:write

May read
./transcript.txt
May write
./action-items.json
meeting-actions.nika.yamlthe typed extract is the kept decision
nika: meeting-actions# local model · the recording stays yoursmodel: ollama/qwen3.5:4b # the file IS the blast radiuspermits:  fs: { read: [ ./transcript.txt ], write: [ ./action-items.json ] }  tools: [ "nika:read", "nika:write" ] tasks:  transcript:    invoke: { tool: "nika:read", args: { path: ./transcript.txt } }   extract:    timeout: "900s"    with:      transcript: ${{ tasks.transcript.output }}    infer:      prompt: "Extract every action item with its owner: ${{ with.transcript }}"      schema:        type: object        required: [ actions ]        properties:          actions:            type: array            items:              type: object              required: [ owner, task ]              properties:                owner: { type: string }                task: { type: string }      max_tokens: 6144   save:    with:      extract: ${{ tasks.extract.output }}    invoke:      tool: "nika:write"      args: { path: ./action-items.json, content: "${{ with.extract }}" } outputs:  actions: "${{ tasks.extract.output }}"
Check

Nothing runs until the boundary is clean.

The checker is the same for every file. Below is a pull-request review that was refused, then repaired and admitted, before anything ran.

nika checkpr-review.broken.nika.yaml
Recorded findings
  1. NIKA-DAG-002 · CONFORM

    unknown dependency: task `judge` depends on `dif`, which does not exist — did you mean `diff`? · → nika explain NIKA-DAG-002

  2. NIKA-SEC-004 · PERMITS

    invoke tool `nika:wrte` is outside permits.tools (task `save`)

  3. NIKA-BUILTIN-001 · TOOLS

    `nika:wrte` names no canonical builtin (task `save`) — did you mean `nika:write`?

Nothing ran

3 findings · refused before execution

refused before executionnika 0.114.0
Run

One file. A known plan.

The same meeting file, executed. Task identities and durations come from a recorded run, not a mock.

Recorded Nika runmeeting-actions.nika.yaml trace · completed
ollama/qwen3.5:4bdefault-deny2 permit families
sourcechecked
nika: meeting-actions
# local model · the recording stays yours
model: ollama/qwen3.5:4b

# the file IS the blast radius
permits:
  fs: { read: [ ./transcript.txt ], write: [ ./action-items.json ] }
  tools: [ "nika:read", "nika:write" ]
execution3 / 3
01invoketranscript1ms
02inferextract4m12s
03invokesave3ms
before · policy declaredduring · 3 tasks observedafter · trace recorded
3 tasks · 3 completed · 0 skipped4m12s observed
A recorded Nika fixture: byte-identical source, observed engine events and measured task durations.
Proof

Inspect what actually happened.

Source, tasks, artifact and duration stay on one recorded trace. You can open this run later and see the same evidence.

Source
meeting-actions.nika.yaml
Tasks
3 complete · 0 skipped
Artifact
wrote action-items.json
Trace
  1. 01transcript1ms
  2. 02extract4m12s
  3. 03save3ms
Apply

Start with work your team already repeats.

The file, the tools and the artifact change. Plan, check, run and proof stay readable the same way.

See real workflows
pr-risk-review.nika.yaml4 tasks · 3 waves

dashed = conditional (when:)

Model
ollama/llama3.2:3b
Boundary
3 permit families
Artifact
wrote review.md
Own

Your stack. Your models. Your record.

Nika runs where you put it, against the models you choose, and leaves evidence you keep.

Your infrastructureone local binarylocal-first · no Nika cloud required
Your models17 providers5 local · 11 cloud · your keys, your seats
Your proofappend-only tracehash-chained record · AGPL engine · Apache-2.0 spec
Use

Same file. Same limits.

Run the same checked workflow from your terminal, your editor, or the agent already working with your team.

Terminalnika run meeting-actions.nika.yamlone local binary
Editormeeting-actions.nika.yamlchecked as you edit
Agentnika wireread-only oracle
Questions

Questions, answered straight.

The real objections, and honest answers. No overclaiming, no dunking on the tools you already use.

I already see the agent’s steps in Cursor or a README. Why Nika?

Seeing the steps is not the same as enforcing the procedure. A README is documentation; a Nika file is an executable contract: versionable, replayable, permission-bound, auditable, and portable off any platform. You do not just read what it intends to do; the runtime holds it to exactly that.

Isn’t this just YAML, or another workflow engine?

The syntax is plain YAML, but the point is not the syntax. The point is the reviewable, enforced plan. The 4 verbs (infer · exec · invoke · agent) are native execution models, each one explicit and typed, with a permits: block the runtime enforces before anything runs. The file is the control surface, not the formatting.

Why not LangGraph, n8n, or MCP (agent tools)?

They live at a different layer. Frameworks help you orchestrate and assistants help an agent act; MCP exposes tools to call. Nika is the contract-and-control layer underneath: it makes the plan reviewable and enforceable, and it runs their tools through invoke, allow-listed and traced. It complements them rather than replacing them.

Does my data leave my machine?

Local-first, any model: fully local, or any API. Run a local model and nothing leaves at all. Every plan declares its network egress in its permits: block, and it is default-deny: omit the hosts and the workflow physically cannot reach the network. The file states exactly what can leave, and the runtime enforces it. 5 of the 17 providers are local.

Is it production-ready? What’s the license?

Honest answer: Nika is early. Real semver toward a 1.0 launch, currently at v0.116.2, shipping in the open. It is one Rust binary you can install and run today. The engine is AGPL-3.0-or-later; the spec is Apache-2.0. We would rather you trust the spec and the binary than a maturity claim we have not earned yet.