// concepts · 02

The reliable harness

The harness is Okami's engine: a ReAct loop with reliability invariants. It doesn't trust the model's prose — it decides on state and observable effects. This is wh…

The state machine

Every task runs through explicit states. It never stays IN_PROGRESS forever: max_steps (default 24), a wall-clock and the stall detector guarantee termination.

PENDING ─► IN_PROGRESS ─► COMPLETE      (exitCriteria verified)
                 ├─► BLOCKED        (structured reason)
                 ├─► NEEDS_INPUT    (missing a fact from you)
                 └─► FAILED         (budget exceeded)

Action-or-Terminate

Every turn ends in a tool-call OR a terminal signal (task_complete · task_blocked · need_input). Future-tense text (“I'll”, “let me”) with no action is caught by an intent–action reconciler (PT/EN), rejected and re-prompted: “you said you'd do X but didn't act — do it now or declare blocked.” There's no infinite “thinking”.

Verified exitCriteria

task_complete only counts if the criteria pass mechanically. If the model declares completion but a criterion fails, the harness emits complete_rejected with the exact list of what's missing — and the agent resumes.

criterionverifies
file_exists:<path>the file exists in the workspace
file_contains:<path>:<txt>the file exists AND contains the text
shell_ok:<cmd>the command exits 0 (e.g. pytest -q)
ui_gatethe design-contract gate passes (§ Skills)

Anti-loop

A weak model loves repeating the same tool and oscillating between two states. The harness breaks that without relying on the model to “notice”:

  • Fingerprint + dedup — each call hashes (tool + normalized args); repeated N times → blocked with a nudge.
  • Cycle detection — A,B,A,B / A,B,C,A,B,C patterns in the recent window → break.
  • Circuit breaker — the same command failing N times with the same error → that approach is forbidden.
  • Progress budget — lots of effect, zero progress against the exitCriteria → break.
  • Hard ceilingsmax_steps per task + per-tool cap.
  • Escalation ladder — nudge → re-decompose → escalate to a stronger model (--escalate) → BLOCKED with a diagnosis.

Anti-hallucination

  • Mandatory grounding — a claim about the code must be backed by a real observation (read-before-edit). The tool result is the truth, not the model's memory.
  • Existence check for a symbol/import/package before using it (anti-slopsquatting).
  • Abstention is first-class — “I don't know / need to check” is cheaper than guessing.
  • Gates as a filter — build/typecheck catch a hallucinated API/import on the spot.

Dual-mode (LLM parity)

capability.tool_mode defines how the model emits actions:

params json_text mode Action as a ``json`` block in the text — works on any model. json_constrained mode Forces valid JSON via grammar/response_format (local/weak) — a malformed tool-call stops being fatal. native mode The provider's native tool-calling (strong); the transport converts it back to the action protocol.

Checkpoints & rollback

Every write records the prior state in an append-only journal with lock + chained HMAC — tampering with or inserting an entry breaks the chain, and rollback ignores the forged entry. okami rollback N undoes the last N writes.

Budget and auto-compaction

There's a per-turn step/token ceiling. When context fills (~72% of the model's window), old turns become summary nodes and durable facts are promoted to long-term memory — compacting is promote + point, never forget.

Turn events

The harness emits an event stream (consumed by the CLI, the TUI and the event log). Each shows up live in okami task/chat:

eventmeans
start · steptask started · each tool-call with ✓/✗
violationa turn with no action (empty future tense) → rejected
looprepetition/cycle detected
escalateescalating to a stronger model
compactauto-compaction (n facts → memory)
complete_rejectedcompletion denied: an exitCriterion was missing

Open this page in the interactive docs