Skip to main content
The loop command group drives the durable agentic turn loop (the “harness”) — a loop that runs server-side inside your Machina pod (agents + workflows + prompts + documents, re-dispatched by the beat). Every turn is persisted before it advances and independently verified before it finalizes, so the loop survives crashes, async tools, and waiting on input — and never silently ships an unchecked answer. The CLI is a thin driver/observer (same pattern as factory): it starts sessions, streams turns, injects follow-ups, and reads state. All loop state lives in the pod as harness_session documents — the CLI holds none.

How a turn works

  • Reason → tool → respond — the loop decides whether to call a tool, runs it, and synthesizes an answer.
  • Verify (Cap 8) — a cheap deterministic gate (non-empty answer, no error marker, tool succeeded) plus an independent evaluator (a separate prompt, fresh context, “assume it’s wrong”). A turn finalizes idle only if both pass; otherwise it stops at needs_review — a human checkpoint, never a silent pass.
  • Self-repair (Cap 8.2) — if the gate passes but the evaluator rejects the answer, the loop repairs it once (fed the rejection reason) and re-verifies before deciding idle vs needs_review.
  • Durable — each turn is saved before advancing; a session left active is resumed by the beat.
Prerequisite — provision the loop in your pod. The loop’s server-side resources (loop-runner, loop-turn, loop-evaluate, …) must exist in the project pod. Stand them up once with the provisioning kit (stdlib, idempotent):
EVAL_MODEL (evaluator model — use a model stronger than the generator in production) and LOOP_MAX_ATTEMPTS (resume attempt budget) are tunable. See the kit’s VALIDATION.md for the full contract.

Usage

Point the CLI at the pod first (direct API-key mode):

run — start a session

--watch streams each turn — including the tool step and the verification verdict:
A turn that uses real project data (where a pod has sportradar-fixture documents):

Tools the loop can call

The reasoning step (loop-reasoning) picks from a catalog and emits tool_calls; the loop-tools connector dispatches them in-pod. Out of the box: So a turn can reason over real project data or live conversations, not just do math:
Add a tool by extending the loop-tools dispatcher and the loop-reasoning catalog in provision.py, then re-provision.

watch / say / stop / sessions

sessions shows each session’s terminal status, so a needs_review is easy to spot:

Verification & self-repair — how to test it

The verdict is part of the turn. These examples make each path visible. Pass — a good answer is verified and finalizes idle:
Gate fails closed → needs_review — a tool error never silently passes:
The calculate tool returns an error:, so the deterministic gate fails, the LLM evaluator is skipped, and the session stops at the human checkpoint instead of idle.
Use a stronger evaluator in production. A same-model evaluator (the generator judging itself) is lenient on plausible-but-unsupported facts. Provision with a different/stronger EVAL_MODEL:
Self-repair (Cap 8.2) — when the evaluator rejects a gate-passing answer, the loop repairs once and re-verifies; the CLI then appends · self-repaired. The evaluator rarely rejects a correct answer, so to force the path deterministically, swap in a temporary always-fail evaluator, run one turn, then restore:

Status model

--watch treats idle, needs_review, paused, completed, and failed as terminal.

Environment & config

  • Provisioning kit + validation guidedocs/harness-loop-kit/ (provision.py, VALIDATION.md, PLAYBOOK-SCORECARD.md) in the machina-cli repo.
  • Architecture, chapter by chapterdocs/agentic-harness-loop.md.
  • Delegating from an external agent — SportsClaw’s machina_loop tool + operator-sync route durable work to this loop over MCP.

Troubleshooting