Nika Workflow
Nika is an open-source Rust engine that captures a
repeatable AI task as one plain-text *.nika.yaml file. The file is
audited before a single token is spent, runs against local or cloud
providers under a spend ceiling, and records a hash-chained journal you
can verify afterwards.
Use it for the work that repeats. Nika is not a coding agent and does not
compete with one: OpenClaude writes the code, Nika runs the chore that
comes back every week and hands you a receipt for it.
Use this skill when
- The user describes a prompt or prompt chain they run more than once — a
weekly digest, an inbox triage pass, a release-note draft — and wants it
captured as something re-runnable.
- A shell or Python script in the repo calls a model API, or wraps HTTP,
file and JSON plumbing around model output.
- The user asks for a hard spend ceiling on an AI task, or asks what a
task will cost before it runs.
- The user needs a record of what an AI run actually did: a receipt, an
audit trail, something a reviewer can check independently.
- A
*.nika.yaml file is open or being written, or nika check reported
a NIKA-XXXX finding that needs fixing.
Do NOT use this skill when
- The user wants a one-off answer or a single tool call — answer directly,
a workflow file is overhead.
- The user wants application code written, refactored or reviewed — that
belongs to a coding skill.
- The task needs conversational back-and-forth mid-execution — workflows
are non-interactive by design; a confirm gate asks one question, it does
not hold a discussion.
Procedure
- Confirm the engine is present:
nika --version. If it is missing, say
so and stop — installing is the user's move
(brew install supernovae-st/tap/nika, or the paths listed at
nika.sh). Never improvise workflow YAML from memory.
- Start from a skeleton, never a blank file.
nika new --from '?' lists
the embedded templates, nika new --from <template> <file>.nika.yaml
writes one, and bare nika try lists complete runnable lessons.
- Fill it in. The envelope opens with
nika: <kebab-case-name> — that
one key carries both the mark and the file's name, and there is no
workflow: envelope key — plus a tasks: map keyed by task id.
Exactly one verb per task: infer (a model call) · exec (a
subprocess, whose command: is an argv list) · invoke (a builtin or
MCP tool) · agent (a bounded multi-turn loop). Every value the file
depends on is declared in one of three authorities: inputs: ·
const: · secrets: — a deployment-supplied value is an inputs:
entry with required: false and a default:.
- Declare the boundary.
permits: states what the workflow may touch,
and an ABSENT block means zero authority — any effect without a grant
is refused at check time. nika check <file> --infer-permits prints
the tightest block the workflow actually needs; paste it in.
- Audit before anything runs:
nika check <file>. Exit 0 is clean, exit
2 carries findings. Each finding names its task and the fix it wants;
nika check <file> --fix applies the mechanical repairs. Decode an
unfamiliar code with nika explain NIKA-XXXX. Loop until clean.
- Report cost from the check output, never from a guess.
≤ $X is a
ceiling; ≥ $X FLOOR means at least one task is unbounded, and you
name why. A model running locally is unpriced compute — say unpriced,
never free.
- Hand the run to the user. Typing
nika run <file> is their move; give
them the line, with --max-cost-usd <n> when spend matters. An offline
rehearsal costs nothing: --model mock/echo.
- After a run that mattered, prove it.
nika trace verify <trace> checks
the hash-chained journal under .nika/traces/, and
nika trace evidence <trace> exports a pack a reviewer can check without
trusting you. Cite the trace, never a memory of the run.
Examples
In scope: "every Monday I paste a competitor changelog into a model and
ask what changed" → capture it as a workflow with a fetch task, a bounded
infer, and a written report; audit it clean; hand over the run line.
In scope: "this deploy script calls a model to draft the release note" →
port the model call to infer:, the file writes to the nika:write
builtin, declare the permits, pin the behavior with
nika test <file> --update, and leave the old script for the user to
retire.
Out of scope: "explain what this regular expression does" → answer
directly; no file, no workflow.
Out of scope: "refactor this module" → a coding skill owns that. Nika
does not write application code.
Self-check before responding
- Did
nika check exit 0 on the exact file being handed over? If it did
not, the file is not ready to hand over.
- Is the cost reported the way the audit reported it — a ceiling, or a
floor with a named reason — with no local model described as free?
- Does the file declare a
permits: block, or is the body genuinely pure
compute and saying so with an empty one?
- Was the run proposed as a command line rather than executed?
- Is every credential referenced through the declared
secrets: block,
with no literal value written anywhere in the file?
1---2name: nika-workflow3description: Captures a repeated AI chore as a Nika workflow file — audited before it runs, cost-capped while it runs, hash-chain traced after.4license: MIT5---67# Nika Workflow89[Nika](https://nika.sh) is an open-source Rust engine that captures a10repeatable AI task as one plain-text `*.nika.yaml` file. The file is11audited before a single token is spent, runs against local or cloud12providers under a spend ceiling, and records a hash-chained journal you13can verify afterwards.1415Use it for the work that repeats. Nika is not a coding agent and does not16compete with one: OpenClaude writes the code, Nika runs the chore that17comes back every week and hands you a receipt for it.1819## Use this skill when2021- The user describes a prompt or prompt chain they run more than once — a22 weekly digest, an inbox triage pass, a release-note draft — and wants it23 captured as something re-runnable.24- A shell or Python script in the repo calls a model API, or wraps HTTP,25 file and JSON plumbing around model output.26- The user asks for a hard spend ceiling on an AI task, or asks what a27 task will cost before it runs.28- The user needs a record of what an AI run actually did: a receipt, an29 audit trail, something a reviewer can check independently.30- A `*.nika.yaml` file is open or being written, or `nika check` reported31 a `NIKA-XXXX` finding that needs fixing.3233## Do NOT use this skill when3435- The user wants a one-off answer or a single tool call — answer directly,36 a workflow file is overhead.37- The user wants application code written, refactored or reviewed — that38 belongs to a coding skill.39- The task needs conversational back-and-forth mid-execution — workflows40 are non-interactive by design; a confirm gate asks one question, it does41 not hold a discussion.4243## Procedure44451. Confirm the engine is present: `nika --version`. If it is missing, say46 so and stop — installing is the user's move47 (`brew install supernovae-st/tap/nika`, or the paths listed at48 nika.sh). Never improvise workflow YAML from memory.492. Start from a skeleton, never a blank file. `nika new --from '?'` lists50 the embedded templates, `nika new --from <template> <file>.nika.yaml`51 writes one, and bare `nika try` lists complete runnable lessons.523. Fill it in. The envelope opens with `nika: <kebab-case-name>` — that53 one key carries both the mark and the file's name, and there is no54 `workflow:` envelope key — plus a `tasks:` map keyed by task id.55 Exactly one verb per task: `infer` (a model call) · `exec` (a56 subprocess, whose `command:` is an argv list) · `invoke` (a builtin or57 MCP tool) · `agent` (a bounded multi-turn loop). Every value the file58 depends on is declared in one of three authorities: `inputs:` ·59 `const:` · `secrets:` — a deployment-supplied value is an `inputs:`60 entry with `required: false` and a `default:`.614. Declare the boundary. `permits:` states what the workflow may touch,62 and an ABSENT block means zero authority — any effect without a grant63 is refused at check time. `nika check <file> --infer-permits` prints64 the tightest block the workflow actually needs; paste it in.655. Audit before anything runs: `nika check <file>`. Exit 0 is clean, exit66 2 carries findings. Each finding names its task and the fix it wants;67 `nika check <file> --fix` applies the mechanical repairs. Decode an68 unfamiliar code with `nika explain NIKA-XXXX`. Loop until clean.696. Report cost from the check output, never from a guess. `≤ $X` is a70 ceiling; `≥ $X FLOOR` means at least one task is unbounded, and you71 name why. A model running locally is unpriced compute — say unpriced,72 never free.737. Hand the run to the user. Typing `nika run <file>` is their move; give74 them the line, with `--max-cost-usd <n>` when spend matters. An offline75 rehearsal costs nothing: `--model mock/echo`.768. After a run that mattered, prove it. `nika trace verify <trace>` checks77 the hash-chained journal under `.nika/traces/`, and78 `nika trace evidence <trace>` exports a pack a reviewer can check without79 trusting you. Cite the trace, never a memory of the run.8081## Examples8283In scope: *"every Monday I paste a competitor changelog into a model and84ask what changed"* → capture it as a workflow with a fetch task, a bounded85`infer`, and a written report; audit it clean; hand over the run line.8687In scope: *"this deploy script calls a model to draft the release note"* →88port the model call to `infer:`, the file writes to the `nika:write`89builtin, declare the permits, pin the behavior with90`nika test <file> --update`, and leave the old script for the user to91retire.9293Out of scope: *"explain what this regular expression does"* → answer94directly; no file, no workflow.9596Out of scope: *"refactor this module"* → a coding skill owns that. Nika97does not write application code.9899## Self-check before responding100101- Did `nika check` exit 0 on the exact file being handed over? If it did102 not, the file is not ready to hand over.103- Is the cost reported the way the audit reported it — a ceiling, or a104 floor with a named reason — with no local model described as free?105- Does the file declare a `permits:` block, or is the body genuinely pure106 compute and saying so with an empty one?107- Was the run proposed as a command line rather than executed?108- Is every credential referenced through the declared `secrets:` block,109 with no literal value written anywhere in the file?