Skip to main content
Agents are the primary authors of Nika. The language is built so that the path carries the quality, not the model: a small closed grammar ( verbs · namespaces · one expression surface), one canonical way per intention, and a validator whose errors prescribe their own fix.

The protocol

1

Route — one intent, one template

The templates are six complete, valid skeletons (conformance-gated on every push). Match the outer shape of the job:
Intent sounds like…Template
take data → produce words → savechain
watch X, act when Ygate-and-act
do this for every itemfanout
only what changed · survive bad inputetl-state
research / review / open-endedagent-loop
anything irreversiblehuman-gated-ship
2

Instantiate — structure is copied, never invented

Copy the template, rename the workflow, fill every # SLOT: line. Creativity belongs only in prompts, jq expressions and paths. If the job needs a construct the template lacks, the coverage matrix names the canonical example that exercises it — read it, don’t guess.
3

Check — never ship unchecked

nika check workflow.nika.yaml (engine) or python conformance/runner.py validate <file> (spec oracle). Editors get the same truth live via the JSON Schema.
4

Repair — the error names its fix

Fix exactly what the code says, nothing else, then re-check:
ErrorThe fix
NIKA-DAG-003you referenced ${{ tasks.X }} — add depends_on: [X]
NIKA-DAG-001cycle — remove the back-edge
NIKA-VAR-001undeclared name — declare it in vars:/secrets: or fix the typo
NIKA-PROVIDERmodel: must be <provider>/<name> with a canonical prefix
NIKA-PARSE (duplicate id)two tasks share an id — rename one

The eight hard rules

These catch ~90% of LLM-written errors. The validator enforces all of them; knowing them just saves round-trips:
  1. One verb per task · infer, exec, invoke or agent.
  2. snake_case task ids (CEL-safe) · kebab-case workflow:.
  3. Every ${{ tasks.X }} reference requires depends_on: [X] · the DAG has no invisible edges.
  4. when: is a ${{ }} CEL boolean or the literal true/false · ${{ vars.count }} is not a condition; ${{ vars.count > 0 }} is; a bare string without ${{ }} is rejected; when: true is the always-pattern (run even when an upstream failed).
  5. size() is the only CEL function · arithmetic and string functions live in jq, not in ${{ }}.
  6. nika:write needs content: · a write without it writes nothing.
  7. nika:done only inside agent.tools · it is the loop sentinel, meaningless elsewhere.
  8. Fan-outs get the leash · max_parallel + fail_fast: false + per-iteration retry/timeout.

After valid: the judgment layer

Validity is the floor. The twelve patterns are the ceiling: deterministic core, typed boundaries, the right gate (when = skip · assert = fail · prompt = human), sovereignty for sensitive data, budgets on agents, on_finally evidence. Every pattern links the canonical example that embodies it.

The templates

Six skeletons, every decision point a slot, conformance-gated.

The twelve patterns

The judgment layer: why each locked choice is locked.