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.
- Planmeeting-actions.nika.yaml
- Checkbefore it runs
- Run3 tasks · 4m12s
- Proofexit 0
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 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.
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 boundaryThe second time starts from a file.
Keep the useful procedure as readable source. The next run starts from this plan, not another blank conversation.
- 01Read the meeting transcript
transcript · invoke · nika:read
- 02Extract every action item, with its owner
extract · infer · ollama/qwen3.5:4b
- 03Write the result to a file
save · invoke · nika:write
- May read
- ./transcript.txt
- May write
- ./action-items.json
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 }}"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-DAG-002 · CONFORM
unknown dependency: task `judge` depends on `dif`, which does not exist — did you mean `diff`? · → nika explain NIKA-DAG-002
- NIKA-SEC-004 · PERMITS
invoke tool `nika:wrte` is outside permits.tools (task `save`)
- NIKA-BUILTIN-001 · TOOLS
`nika:wrte` names no canonical builtin (task `save`) — did you mean `nika:write`?
3 findings · refused before execution
One file. A known plan.
The same meeting file, executed. Task identities and durations come from a recorded run, not a mock.
checkednika: 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" ]3 / 3invoketranscript1msinferextract4m12sinvokesave3msInspect 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
- 01transcript
1ms - 02extract
4m12s - 03save
3ms
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 workflowsdashed = conditional (when:)
- Model
- ollama/llama3.2:3b
- Boundary
- 3 permit families
- Artifact
- wrote review.md
Your stack. Your models. Your record.
Nika runs where you put it, against the models you choose, and leaves evidence you keep.
one local binarylocal-first · no Nika cloud required17 providers5 local · 11 cloud · your keys, your seatsappend-only tracehash-chained record · AGPL engine · Apache-2.0 specSame file. Same limits.
Run the same checked workflow from your terminal, your editor, or the agent already working with your team.
nika run meeting-actions.nika.yamlone local binarymeeting-actions.nika.yamlchecked as you editnika wireread-only oracleQuestions, 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.