AGPL-3.0-or-later · forever.

the language

Every word.

Every key a .nika.yaml can carry, projected from the one contract the engine serves: workflow.schema.json, the same file your editor validates against. Descriptions are the schema's own. Every word opens its own room; the contract, the word in a real file, the block it lives in; the four verbs keep theirs. The deeper grammar lives in the spec.

  • 59wordsthe whole surface
  • 73declarations10 surfaces
  • 4verbsrooms of their own
  • schemathe sourcenever prose
  • envelopethe file itself
  • workflowinside workflow:
  • taskone step of the plan
  • inferinside infer:
  • execinside exec:
  • invokeinside invoke:
  • agentinside agent:
  • retryinside retry:
  • on_errorinside on_error:
  • on_finallyinside an on_finally step
  1. aftertask
    task
    objectThe CONTROL boundary · {producer-task: predicate}. Each entry is one control edge (spec/03-dag.md §after). State, never data — observe outcomes through with:.
  2. task
    the fourth verb: a budgeted tool-calling loop; its room: /verbs/agent
    on_finally
    the fourth verb: a budgeted tool-calling loop; its room: /verbs/agent
  3. argsinvoke
    invoke
    objectthe tool call’s arguments, validated against the builtin’s declared contract before anything runs
  4. retry
    integerceiling on the computed backoff delay
  5. retry
    integerbase delay between attempts
  6. retry
    stringhow the delay grows between attempts fixedlinearexponential
  7. exec
    stringwhich stream becomes the task output stdoutstderrcombinedstructured
  8. exec
    arrayargv — the program and its arguments, execve, NO shell. Each element substituted independently (the injection-safe form). Shell features (pipes · redirects · globs) live in `shell:`.
  9. configenvelope
    envelope
    objectTyped non-sensitive runtime config · `${{ config.X }}` · supplied by the deployment or environment, may appear in logs (R3a · LAW-SURFACE-0201 · succeeds the dead `env:` block). Each entry is a typed declaration; a `default:` MUST conform to `type:` (LAW-TYPE-0211 · NIKA-DEFAULT-001).
  10. constenvelope
    envelope
    objectNamed constants · `${{ const.X }}` · a fixed value baked into the workflow (R3a · LAW-SURFACE-0201 · the literal half of the dead `vars:` block · everything that is not required:true lands here per the E-split total rule). Either a bare literal, or a `{ type, value }` typed constant whose `value:` MUST conform to `type:`.
  11. cwdexec
    exec
    stringworking directory for the command
  12. decodeexec
    exec
    stringHow the captured string becomes a value (spec 09 §decode) — illegal with capture: structured (NIKA-PARSE-025) textjsonjsonlbytes
  13. descriptionworkflow
    workflow
    stringone honest sentence about the workflow; it shows in listings and traces
  14. envexec
    exec
    objectenvironment variables for the exec command, a name to value map
  15. task
    the second verb: run a command, captured and typed; its room: /verbs/exec
    on_finally
    the second verb: run a command, captured and typed; its room: /verbs/exec
  16. task
    booleanfor_each abort-on-error · default true.
  17. on_error
    booleanescalate: a caught error still fails the run after recovery
  18. task
    string | arrayMap this task over a collection · `${{ ... }}` reference OR a literal array.
  19. idworkflowrequired in workflow
    workflow*
    stringWorkflow id · kebab-case · the document-type discriminator (W1: the envelope became an object).
  20. task
    the first verb: call a model; its room: /verbs/infer
    on_finally
    the first verb: call a model; its room: /verbs/infer
  21. inputsenvelope
    envelope
    objectTyped workflow inputs · `${{ inputs.X }}` · the parameters an author declares and a caller supplies (R3a · LAW-SURFACE-0201 · the typed half of the dead `vars:` block · a required:true value lands here per the E-split total rule). Each entry is a typed declaration whose `type:` speaks the full TypeExpr of 09-types (R3b · LAW-GRAMMAR-0211 · the flat 6-enum is dead · LAW-SURFACE-0211).
  22. task
    the third verb: call a tool (nika: builtin or mcp: server); its room: /verbs/invoke
    on_finally
    the third verb: call a tool (nika: builtin or mcp: server); its room: /verbs/invoke
  23. jitterretry
    retry
    booleanrandomize delays so retries never stampede in phase
  24. max_attemptsretryrequired in retry
    retry*
    integerthe retry ceiling, the leash on flake
  25. task
    integerCap concurrent for_each iterations · default unbounded · 1 = sequential.
  26. infer
    integer | stringper-call output token cap
  27. agent
    integer | stringthe agent’s total spend bound across all turns
  28. agent
    integer | stringthe agent’s loop bound; the worst case is finite
  29. modelenvelopeinferagent
    envelope
    stringDefault model · `<provider>/<name>` (e.g. ollama/qwen3.5:9b · anthropic/claude-sonnet-4-6 · mock/echo).
    infer
    string
    agent
    string
  30. nikaenveloperequired in envelope
    envelope*
    "v1"Language contract version · exactly `v1` for the v1 lifetime. NOT `v1.0` · `1` · `1.0`.
  31. on_codesretryon_error
    retry
    array
    on_error
    arrayOptional catch-side filter (mirror of retry.on_codes · same regex) · the action applies ONLY when the final error code is listed · unlisted codes fall through to the default fail (spec/05-errors.md §Fields).
  32. task
    the catch side: recover with a value, skip, or fail loudly, per error code
  33. task
    arrayCleanup mini-tasks · ALWAYS run (success/fail/timeout/cancel) · sequential · best-effort.
  34. outputtask
    task
    objectNamed jq-expression bindings · `${{ tasks.X.<name> }}`. jq is the single data extraction-and-transform language (the former RFC 9535 JSONPath was dropped · jq is a superset · per spec/04-variables.md §216-225). Reserved names forbidden at parse time (spec/04-variables.md §Rules): output · status · error · started_at · ended_at · duration_ms — enforced via propertyNames.
  35. outputsenvelope
    envelope
    objectThe workflow's return value · symmetric to inputs. Each entry is a `${{ tasks.X.output }}` reference (untyped form · string) OR a typed declaration { value · type · description }. Powers `nika run` result + the output half of the callable-workflow schema.
  36. permitsenvelope
    envelope
    objectThe declared capability boundary · once present every category is default-deny unless listed (spec/01-envelope.md §permits · NIKA-SEC-004).
  37. policyenvelope
    envelope
    objectNamed workflow law · hard families (require/forbid/allow/limits) are judged at check (NIKA-POLICY-001) · soft families (prefer/optimize) are recorded, never judged in v1 (spec/10-authority.md).
  38. promptinferagentrequired in infer · agent
    infer*
    stringthe model job, in words: interpolate ${{ }} references, never paste secrets
    agent*
    stringthe model job, in words: interpolate ${{ }} references, never paste secrets
  39. recoveron_error
    on_error
    Recovery output · a `${{ }}` ref OR a literal (merges the former fallback/value per spec/05-errors.md).
  40. retrytask
    task
    the leash: attempts, backoff, jitter, per-code filters
  41. task
    The task's output contract (spec 09-types.md) — exclusive with a verb-level schema: (NIKA-TYPE-003)
  42. schemainferagent
    infer
    objectJSON Schema · structured output contract.
    agent
    objectJSON Schema · validate the agent's final message as structured output.
  43. secretsenvelope
    envelope
    objectVault-backed masked references · `${{ secrets.X }}` · never inline literals.
  44. shellexec
    exec
    stringOne shell line, run via /bin/sh -c — the EXPLICIT dangerous door (pipes · redirects · globs). The blocklist applies here; interpolating untrusted values here is on the author. Exactly one of command|shell.
  45. skillsagent
    agent
    arrayAgent Skill (SKILL.md) file paths · agentskills.io shape · explicit static paths only (no globs · no templates) · loaded at compose time and injected into the system context.
  46. stdinexec
    exec
    stringtext piped to the command’s standard input
  47. systeminferagent
    infer
    stringthe standing instruction: who the model is for this task
    agent
    stringthe standing instruction: who the model is for this task
  48. tasksenveloperequired in envelope
    envelope*
    objectThe task map · the KEY is the task's identity (snake_case · CEL-safe). Source order is presentation only — the graph alone schedules.
  49. temperatureinferagent
    infer
    number | string0-2 · number or `${{ }}`.
    agent
    number | string
  50. infer
    objectextended-reasoning budget for models that expose it
  51. timeouttaskon_finally
    task
    stringGo-duration string · quoted · e.g. "30s" "5m" "1h30m" "2.5s". Max 24h.
    on_finally
    string
  52. toolinvoke
    invoke
    stringTool reference · nika:<path> (closed v0.1 builtin set) OR mcp:<server>/<tool> (requires the slash). The namespace set is CLOSED at v1 (spec/02-verbs.md) — an x-<vendor>: prefix is RESERVED, not valid (engine-specific tools route through mcp: · spec/06-stdlib-contract.md §Namespace ownership).
  53. toolsagent
    agent
    arrayWhitelist · DEFAULT-DENY (no tools if absent) · gitignore-style globs · `!` negation.
  54. typesenvelope
    envelope
    objectNamed type declarations (spec 09-types.md · PascalCase · acyclic)
  55. visioninfer
    infer
    arrayimage inputs for multimodal models
  56. whentaskon_finally
    task
    boolean | stringLOCAL business condition · evaluated POST-gate over {vars · env · with · item · index} — tasks.* is illegal here (NIKA-VAR-021 · hoist into with:). false → skipped (spec/03-dag.md §when).
    on_finally
    boolean | stringCleanup condition · may read the PARENT task's record (tasks.<parent>.status / .error — the only legal tasks.* target inside on_finally · spec/03-dag.md §on_finally).
  57. withtask
    task
    objectTask-level scope injection · `${{ with.X }}`.
  58. workflowenvelopeinvokerequired in envelope
    envelope*
    objectThe workflow object · a stable home for identity and metadata (W1 'the map').
    invoke
    stringCompose another workflow (spec 14) · a STATIC target: a filesystem path OR registry:owner/name@version (pinned). A templated target is refused at check (NIKA-COMP-001). Exactly one of tool: | workflow: (the invoke tagged union · G21).

A key the schema doesn't declare is a nika check finding before anything runs. The language teaches itself. Try it in the playground, walk the four verbs or the standard library. Read the spec →