# Tao Loop

> Judge-gated autonomous coding loop runner. Port of pi-until-done's `/goal ... Ralph` pattern with single-metric termination via `tao_judge.judge`. One worker step per iteration, optional judge call every N iters, three independent abort axes from `kill_switch.LoopCounter` (MAX_ITERS, MAX_COST, HARD_STOP).

- Skill: `cleanexpo/tao-loop` (Agent Skill)
- Install (CLI): `npx skillmds@latest add cleanexpo/tao-loop`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cleanexpo/tao-loop/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cleanexpo (https://skillmd.com/u/cleanexpo)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cleanexpo/tao-loop

---


# tao-loop

Iterates a generator step + judge step until the judge says done or the kill-switch
fires. Returns a fully-populated LoopResult; never raises KillSwitchAbort to the
caller.

## When to trigger

- A user issues an autonomy-class brief that warrants more than one iteration.
- A higher-level orchestrator wants a budget-bounded, judge-gated worker loop
  rather than the wave-orchestrated path.

## Public API

```python
from app.server.tao_loop import run_until_done, LoopResult

result = await run_until_done(
    goal="implement X",
    workspace="/path/to/repo",
    max_iters=10,                # else honour TAO_MAX_ITERS
    max_cost_usd=1.50,           # else honour TAO_MAX_COST_USD
    judge_every_n_iters=2,       # cost-control knob
    timeout_per_iter_s=600,
    on_event=lambda evt: ...,    # streamed iter_complete payloads
)
# result.done; result.reason; result.iters; result.cost_usd;
# result.judge_history; result.final_state
```

## Autoresearch envelope

The judge's `score` ∈ [0, 1] is the single termination scalar. The kill-switch
provides the orthogonal cost / iteration / hard-stop bounds.

## Kill-switch dependency

RA-1966's `LoopCounter` is constructed once per loop. `tick()` advances iters
and adds cost atomically, raising `KillSwitchAbort` on any breach — captured
into `LoopResult.reason`.

## CLI

`python scripts/run_tao_loop.py --goal "..." --workspace /path --max-iters N --max-cost X --judge-every N`

### Lookahead mode (OM-1 / RA-1970)

Set `TAO_OM1_ENABLED=1` for a 15-step default horizon, or `TAO_PLANNER_HORIZON=1..20`
explicitly. The loop decomposes the goal up front via the Opus orchestrator planner,
executes one step per iteration, and re-plans on stall or horizon exhaustion
(capped by `TAO_PLANNER_MAX_REPLANS`, default 2).

```python
result = await run_until_done(
    goal="implement X",
    workspace="/path/to/repo",
    planner_horizon=15,   # or omit and rely on OM-1 / env
    max_replans=2,
    ...
)
```

Status: `GET /api/autonomy/status` → `planner` block (`mode`, `effective_horizon`).

