KULDEEP LUVANI

The Harness · Chapter 1

The Loop

Every agent is a loop of observe, plan, act and verify. The hard parts are when it stops, when to run more than one, and how it survives a restart.

~15 MIN READ1 LIVE INSTRUMENTUPDATED OCT 2026

The agent class in mini-swe-agent is about 100 lines of Python. It has one tool, bash. Every step appends to a single list of messages and nothing is ever removed. With a strong model behind it, that loop resolves more than 74% of SWE-bench Verified.1 Whatever you picture when you hear the word agent, the working core is smaller than that.

A loop is all it is

Strip any coding agent down and you find the same shape: call the model, run the tool it asked for, append the result, call it again. The model does the thinking. Everything else, from which tools exist to what the model sees next turn to when it stops being called, belongs to the harness.

Claude Code's documentation names three phases, gather context, take action and verify results, and says they blend together. It also says the layer around the model that supplies tools and manages context is what the term agentic harness refers to.2 This chapter draws the same ring with four stops: observe, plan, act, verify. Plan is the phase that tends to hide inside the model's reasoning. Verify is the one that tends to go missing.

The interesting engineering sits at the edges of the loop, not in the middle. What goes into the context each turn is chapter 2. What the tools look like is chapter 3. This chapter is about the loop itself: where it came from, when it should stop, when to run several, and how it survives being shut down.

Where the loop came from

Every phase in that ring was a paper before it was a product feature.

ReAct (2022) interleaved reasoning traces with actions and observations. The authors argued that reasoning helps a model track and revise its plan, while actions let it reach outside sources. With one or two in-context examples it beat imitation and reinforcement-learning baselines by an absolute 34 points on ALFWorld and 10 on WebShop.3

Reflexion (2023) added the verify step. The agent receives a feedback signal, writes a reflection in plain text, keeps it in an episodic memory buffer and tries again. That reached 91% pass@1 on HumanEval against GPT-4's 80%.4 Tree of Thoughts (2023) added planning in the strong sense: several candidate paths, lookahead, backtracking. On the Game of 24 it took GPT-4 from 4% with chain-of-thought to 74%.5

Then the field learned how much the loop's surroundings matter. SWE-bench put 2,294 real GitHub issues in front of models, and Claude 2 resolved 1.96%.6 SWE-agent changed the interface instead of the model, designing commands, file viewers and error feedback for what its authors called a new category of end user, and reached 12.5%.7 Today a 100-line bash loop clears 74% on the Verified subset, with much stronger models doing the heavy lifting.1 The harness is a variable, and for a stretch it was the variable that moved fastest.

WorkYearPhase it addedHeadline result
ReAct [3]2022observe + act, interleaved+34 pts ALFWorld
Reflexion [4]2023verify, reflect, retry91% HumanEval
Tree of Thoughts [5]2023plan: lookahead, backtrack4% → 74% Game of 24
SWE-bench, raw model [6]2023(baseline)1.96%
SWE-agent [7]2024agent-computer interface12.5%
mini-swe-agent [1]2025less harness, better models>74% (Verified)

The last row is measured on SWE-bench Verified, a curated subset, so it is not a like-for-like comparison with the rows above it. The direction is the point.

“Looks done” is not a stop signal

Anthropic's widely cited taxonomy separates workflows, where LLMs and tools run through predefined code paths, from agents, where the model directs its own process and tool use.8 It lists five workflow patterns (prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer) and reserves agents for open-ended problems where the number of steps cannot be predicted. The price is latency, cost and compounding errors, which is why the same post recommends stopping conditions such as an iteration cap.8

Google's ADK makes the exits explicit. Its LoopAgent ends when it hits max_iterations or when a sub-agent sets escalate to true, and the docs' writer, critic and refiner example caps at five passes.9 Budget and escalation: every loop needs both.

The default exit in a coding agent is quieter and worse. The model stops when it believes it has finished. Claude Code's best-practices guide says so directly.

“Without a check it can run, ‘looks done’ is the only signal available, and you become the verification loop.”— Claude Code best practices, Anthropic

The guide lays out four escalating gates: a check written into the prompt, a /goal evaluator, a Stop hook that acts as a deterministic gate, and a verification subagent.10 A Stop hook can return a JSON decision of block with a reason, or exit with code 2, and the model keeps working with that reason in front of it. Its input carries a stop_hook_active flag so the hook itself can avoid looping forever.11 In your own loop the same gate is a check that runs whenever the model ends a turn without a tool call; on failure, its output goes back in as the next message.

The stepper below plays the six-step “fix the failing tests” sequence from Claude Code's docs.2 Turn the verification check off and watch what the loop reports.

Loop stepperdata · [2] [12] · illustrative

switch the Verification check off, press Run, and read the stop signal.

OBSERVE PLAN ACT VERIFY 0/6 READY
user: the tests are failing, fix them
CONTEXT WINDOW8.0k / 200k tokens
Stop signal IDLE tests run since edit: —

Ralph loop

20
800,000tokens spent
exit: promise iterations: 16

drag the cap below 16: the spend stops, the promise never lands, the work stays unfinished.

Upper panel: the six steps and tool sequence follow the “fix the failing tests” walkthrough in Claude Code's docs [2]; the file names, terminal lines and token counts are invented for illustration, and the 200k window is a nominal scale, not a current model's limit. The verify gate is the one the best-practices guide describes [10]; with it off, the dashed ghost shows the test run the agent never made. Lower panel: the exit rules (exact <promise> match, or iteration reaches the cap) come from the ralph-wiggum plugin [12]; when the promise arrives is simulated with a fixed seed and a 10% chance per iteration, so it is reproducible, not measured. Cost per iteration is held fixed here; real iterations get more expensive as the repository and progress files grow, so set the cap from a measured per-iteration cost, not an estimate.
Field noteName the check before you start the loop. A test command, a linter, a curl against a health endpoint: something the agent can run that returns pass or fail. If you cannot name one, the task is not ready for an agent.

Copy this: a minimal Stop-hook gate that runs the test suite and blocks Claude Code from stopping while it fails, checked against the current hooks reference (Oct 2026).11

// .claude/settings.json
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command",
    "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/tests-gate.sh",
    "timeout": 300 } ] } ] } }

#!/usr/bin/env bash
# save as .claude/hooks/tests-gate.sh, chmod +x (needs jq)
input=$(cat)
cd "$CLAUDE_PROJECT_DIR" || exit 1   # hooks run in the current dir, which follows cd
# Already continuing because a Stop hook blocked: allow the stop, never loop forever
[ "$(jq -r '.stop_hook_active' <<<"$input")" = "true" ] && exit 0
if out=$(npm test 2>&1); then exit 0; fi
jq -n --arg r "Tests are failing. Fix them and rerun npm test before stopping.
$(tail -n 20 <<<"$out")" '{decision: "block", reason: $r}'

The guard buys one forced retry per stop. Remove it and Claude Code's own backstop applies: after stop hooks continue the turn eight times in a row with no tool call between, it overrides the next block and ends the turn (raise it with CLAUDE_CODE_STOP_HOOK_BLOCK_CAP).11 Any other harness: when the model returns with no tool call, run the test command; if it fails, append the last 20 lines as a user message and call the model again, at most N times.

Ralph: the dumbest loop that works

Ralph is a pattern you can take to production: a deterministic outer loop around a nondeterministic worker, with all state on disk and a hard spend cap. Geoffrey Huntley's original is one line of shell, while :; do cat PROMPT.md | claude-code ; done.13 The same prompt runs every pass against a repository that changes underneath it. Each pass reads the files, does one item, and exits.

“That's the beauty of Ralph - the technique is deterministically bad in an undeterministic world.”— Geoffrey Huntley (2025)

When Ralph does something dumb, you do not swap the model; you add a sign to the prompt. Huntley's headline result, an MVP on a $50k contract for $297, is one practitioner's report, not a measurement.13

The original line will not run as written against the current CLI. A form that does, with both caps made explicit:

# Run only inside a container or VM, as a non-root user (e.g. the
# devcontainer): this skips every permission prompt, and Claude Code
# refuses the flag as root. --bare skips hooks and CLAUDE.md discovery
# and needs ANTHROPIC_API_KEY.
for i in $(seq 1 20); do                      # hard cap: 20 passes
  out=$(claude -p "$(cat PROMPT.md)" --bare \
        --dangerously-skip-permissions \
        --max-budget-usd 2.00)                # per-pass spend cap
  grep -q '<promise>DONE</promise>' <<<"$out" && break
done                                          # worst case about 20 x $2

--max-budget-usd stops a print-mode run once its estimated spend reaches the cap, counts subagent spend toward it, and can overshoot slightly, so leave headroom.14 Claude Code's docs limit skipping permissions to isolated containers and VMs, and on Linux and macOS it will not start in that mode as root or under sudo outside a recognized sandbox; an unattended loop belongs in a container, run as a non-root user.15 State lives in the repository and a progress file, never in the session.

Anthropic's ralph-wiggum plugin moves the loop inside the session with a Stop hook, started with a prompt, --max-iterations and --completion-promise. The hook blocks every stop until the output contains the exact promise string inside <promise> tags or the count reaches the cap. The README tells you to rely on --max-iterations as the primary safety mechanism.12 In the Ralph panel above, drag the cap below the iteration where the promise lands: the loop stops, the spend is fixed, and the work is unfinished. That is the correct failure. Without the plugin, the outer script above does the same job.

Fan-out and orchestration

Once one loop works, the obvious move is to run several. Anthropic's research system has a lead agent that plans and delegates to subagents running in parallel. In that 2025 setup, with Opus 4 leading Sonnet 4 workers, it beat single-agent Opus 4 by 90.2% on an internal research eval. Token usage alone explained 80% of the performance variance on BrowseComp, the system uses about 15 times the tokens of a chat, and parallel tool calls cut research time by up to 90%.16 Cognition's Walden Yan argued the opposite the same month: share full context and full agent traces, not just individual messages. His example is a Flappy Bird clone split between two subagents that return a background and a bird in mismatched styles.17

“Actions carry implicit decisions, and conflicting decisions carry bad results.”— Walden Yan, Cognition (2025)

The two positions reconcile once you look at what each side parallelizes. Research is reads. Subagents search, condense and report back, which Anthropic's context-engineering guidance frames as a clean separation between search and synthesis.18 Code is writes, and two writers with different assumptions collide. Claude Code keeps subagents in separate context windows that return summaries, recommends a fresh-context reviewer that will not be biased toward code it just wrote, and gives parallel writers their own git worktrees.10 Cursor 2.0 runs up to eight agents on one prompt the same way, isolated on worktrees or remote machines.19 In your own harness a subagent is a child loop with its own message list, and its final message is the only thing the parent reads.

Field noteParallelize reads, serialize writes. Fan out for search, review and investigation. When two agents must change code, give each its own worktree and merge through a single point that runs the tests.

Four shapes cover most multi-agent systems. Three map onto Anthropic's workflow taxonomy: orchestrator-workers, prompt chaining, and the review shapes, which combine evaluator-optimizer with parallelization's voting variant (the same task run several times).8 The fourth is what coding tools added: parallel writers, each isolated on its own worktree.

PatternShapeUse it forWatch for
Lead / workerA lead plans, spawns workers with narrow briefs, merges their reportsResearch, investigation, wide readsWorkers drifting from the brief; the lead stopping early
PipelineFixed stages, each output feeds the next, a check between stagesWork you can decompose ahead of timeAn early error compounding through every later stage
Review / voteOne agent produces and a fresh-context agent critiques, or several run the same task and voteCode review, plan review, claims that need checkingA reviewer that shares the writer's context and agrees with it
Parallel on worktreesN writers on separate checkouts, one merge point that runs the testsIndependent changes, migrations, trying N approachesConflicting implicit decisions surfacing at merge

What a subagent returns is an API. Anthropic's guidance notes a subagent may spend tens of thousands of tokens exploring and still return a condensed summary, often 1,000 to 2,000 tokens.18 Make that a contract: fixed fields, a hard cap of 2,000 tokens, and a lead that validates the shape before it reads the content. The field names below are a suggestion; the fixed shape is the point.

{
  "status": "done | partial | blocked",
  "answer": "the conclusion, in 3 to 8 sentences",
  "evidence": ["src/cart/pricing.py:27", "pytest -q: exit 0"],
  "changed": [],
  "open_questions": ["what the lead has to decide"],
  "tokens_used": 41200
}

A blocked status with a question is a legitimate answer. Without it, a worker that lacks information guesses.

Budget the tree, not the node. At fifteen times the tokens, per-agent caps still let a lead spawn its way past any sane total. Give the root one budget that every descendant draws from, and cap depth and width as well. Claude Code and its Agent SDK already count subagent spend toward the run's budget; once it is reached, spawning another subagent fails with “Budget limit reached” and running background subagents are stopped.20 In your own orchestrator, pass a shared budget down the tree, decrement it on every model response, and refuse to spawn when it is empty.

Check the failure modes before launch. A Berkeley study of more than 1,600 multi-agent traces across seven frameworks (MAST) found 14 failure modes in three categories, and verification is one of them.21 Read them as a pre-launch checklist:

CategoryFailure modesCheck before launch
System designdisobey task spec · disobey role spec · step repetition · loss of conversation history · unaware of stopping conditionsEvery agent has a written brief, a role it cannot widen, a turn cap and a named stop condition
Inter-agent misalignmentconversation reset · fail to ask for clarification · task derailment · information withholding · ignored other agent's input · reasoning-action mismatchHandoffs use the return contract; workers can return blocked; the lead records which reports it used
Task verificationpremature termination · no or incomplete verification · incorrect verificationA check that runs (tests, schema, resolved citations) gates the final answer, applied by a fresh-context agent

When the loop breaks

Production loops seldom fail in the model's reasoning. They fail at the seams: a 529 from the API, a tool that hangs, a write that half-happened before a crash, a retry that sends the email twice. Sort every failure into one of three classes, because each gets a different retry rule and the model sees something different.

ClassExamplesWho retriesWhat the model sees
Model / API error429 rate limit, 500, 529 overloadedThe harness, with exponential backoff and retry-after. Claude's SDKs retry twice by default. A spend-cap 429 keeps failing: stop, don't spin.22Nothing; the turn resumes
Tool errortimeout, non-zero exit, bad argumentsThe harness once, only if the tool is idempotent; otherwise the model decidesA short error flagged as one (is_error: true on Claude's API)23
Policy denypermission rule, hook deny, sandbox blockNever automaticallyThe denial and its reason, so it can choose another route11

Claude Code runs a separate StopFailure hook when a turn ends on an API error, with types such as rate_limit, overloaded and server_error, which is the place to hang an alert.11

Give every write tool an idempotency key. Retries and resumes replay calls, and a payment, email or ticket created twice is a real incident. Stripe's API is the reference design: the client sends a unique key, the server saves the first result, and a retry with the same key gets that saved result instead of a second action.24 For an agent, derive the key from the run id and the tool-call id, so a resumed run reuses it.

Put a timeout on every tool. A hung tool holds the whole loop and its budget. Claude Code's Bash tool defaults to two minutes and lets the model raise that to ten, and HTTP-based MCP requests time out after 60 seconds by default, but the overall MCP tool limit defaults to about 28 hours, so give slow servers their own timeout.25

Checkpoint before the side effect, not after. Write the intended call and its inputs to durable storage, run it, then record the result. On restart, a call with an intent and no result is the one to reconcile, using its key. Do not lean on the agent's undo: Claude Code's checkpoints track files edited in the session, not files changed only by Bash, and nothing outside the filesystem.26

Show the model one useful line. After a failure the model needs what failed, why, and what to try next, not 400 lines of traceback. SWE-agent's interface gains came partly from error feedback designed for the model,7 and Anthropic's tool-writing guidance says the same.27

“…prompt-engineer your error responses to clearly communicate specific and actionable improvements, rather than opaque error codes or tracebacks.”— Ken Aizawa, Anthropic (2025)

Surviving the session boundary

Long tasks outlive a context window, and each new session begins with no memory of the last.28 Anthropic's harness for long-running agents treats that as a handoff problem. An initializer agent writes an init.sh, a progress file and the first commit. Every later session is a coding agent that builds one feature against a JSON list of 200-plus features, each marked pass or fail. Each session opens with the same ritual: read the progress log, check git history, run the basic tests, pick the next failing feature.28

Drop the ritual and the failures are predictable: declaring the project done early, leaving bugs and undocumented changes behind, marking features passed without testing them, and spending tokens rediscovering state.28 Two of those four are verification failures.

Cloud agents face a harder version, where the gap is a CI run or a human review that takes hours. Cognition found containers cannot survive those gaps and now snapshots memory, process trees and filesystem at the hypervisor level so a task can stop and resume.29 OpenAI's Codex cloud gives each task its own workspace and hands back diffs, logs and test results with citations, not a claim that it worked.30 Claude Code stores sessions as JSONL that can be resumed or forked, but sessions are independent.2 Anything that must carry over belongs in files.

From my harness · CLAIMCLAIM, the memory system I built for coding agents, turns that opening ritual into a hook. Six lifecycle hooks capture tool uses, decisions and discoveries as a session runs. A SessionStart hook then injects a briefing of what is relevant, so the next session begins where the last one left off instead of rediscovering state. The memory is markdown I own, with SQLite alongside for speed, and the token cost lands on periodic sweep cycles rather than on every session. The pattern travels to any harness that can run a command at session start and put its output in context; in Claude Code, SessionStart is one of the few events whose output the model sees.11

What it costs

A while statement costs nothing; each pass through the model does. A cap is a budget: maximum iterations times tokens per iteration is the most a loop can spend, which is why the Ralph panel multiplies them, and for a tree of agents the cap belongs at the root. Agentic systems trade latency and cost for task performance by design,8 so spend on verification: the test run, the fresh reviewer, the Stop hook that refuses “looks done.” Cost per task, model routing, and how to staff and govern all of this are in Part 06. Every turn also feeds the model a context window, and that window is usually the first thing to degrade. That is Chapter 2.

References
  1. SWE-agent team (Princeton/Stanford), “mini-swe-agent,” GitHub, 2025. github.com/SWE-agent/mini-swe-agent
  2. Anthropic, “How Claude Code works,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/how-claude-code-works
  3. Yao, Zhao, Yu, Du, Shafran, Narasimhan, Cao, “ReAct: Synergizing Reasoning and Acting in Language Models,” arXiv, Oct 2022. arxiv.org/abs/2210.03629
  4. Shinn et al., “Reflexion: Language Agents with Verbal Reinforcement Learning,” arXiv, Mar 2023. arxiv.org/abs/2303.11366
  5. Yao et al., “Tree of Thoughts: Deliberate Problem Solving with Large Language Models,” NeurIPS / arXiv, May 2023. arxiv.org/abs/2305.10601
  6. Jimenez, Yang et al., “SWE-bench: Can Language Models Resolve Real-World GitHub Issues?,” arXiv, Oct 2023. arxiv.org/abs/2310.06770
  7. Yang, Jimenez et al., “SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering,” arXiv, May 2024. arxiv.org/abs/2405.15793
  8. Schluntz, Zhang, “Building effective agents,” Anthropic, Dec 2024. anthropic.com/engineering/building-effective-agents
  9. Google, “Loop agents,” Agent Development Kit docs, accessed Oct 2026. adk.dev/agents/workflow-agents/loop-agents
  10. Anthropic, “Claude Code best practices,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/best-practices
  11. Anthropic, “Hooks reference,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/hooks
  12. Anthropic, “ralph-wiggum plugin and stop-hook.sh,” anthropics/claude-code on GitHub, 2025. github.com/anthropics/claude-code/…/ralph-wiggum
  13. Geoffrey Huntley, “Ralph Wiggum,” ghuntley.com, Jul 2025. ghuntley.com/ralph
  14. Anthropic, “CLI reference,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/cli-reference
  15. Anthropic, “Permission modes,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/permission-modes
  16. Anthropic, “How we built our multi-agent research system,” Anthropic, Jun 2025. anthropic.com/engineering/multi-agent-research-system
  17. Walden Yan, “Don't Build Multi-Agents,” Cognition, Jun 2025. cognition.com/blog/dont-build-multi-agents
  18. Anthropic, “Effective context engineering for AI agents,” Anthropic, Sep 2025. anthropic.com/engineering/effective-context-engineering-for-ai-agents
  19. Cursor, “Cursor 2.0,” Cursor changelog, Oct 2025. cursor.com/changelog/2-0
  20. Anthropic, “How the agent loop works,” Claude Agent SDK docs, accessed Oct 2026. code.claude.com/docs/en/agent-sdk/agent-loop
  21. Cemri et al. (UC Berkeley), “Why Do Multi-Agent LLM Systems Fail?,” arXiv, Mar 2025. arxiv.org/abs/2503.13657
  22. Anthropic, “Claude API errors,” Claude Platform docs, accessed Oct 2026. platform.claude.com/docs/en/api/errors
  23. Anthropic, “Handle tool calls,” Claude Platform docs, accessed Oct 2026. platform.claude.com/docs/…/handle-tool-calls
  24. Stripe, “Idempotent requests,” Stripe API reference, accessed Oct 2026. docs.stripe.com/api/idempotent_requests
  25. Anthropic, “Environment variables,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/env-vars
  26. Anthropic, “Checkpointing,” Claude Code docs, accessed Oct 2026. code.claude.com/docs/en/checkpointing
  27. Ken Aizawa, “Writing effective tools for agents — with agents,” Anthropic, Sep 2025. anthropic.com/engineering/writing-tools-for-agents
  28. Justin Young, “Effective harnesses for long-running agents,” Anthropic, Nov 2025. anthropic.com/engineering/effective-harnesses-for-long-running-agents
  29. Cognition, “What We Learned Building Cloud Agents,” Cognition, Apr 2026. cognition.com/blog/what-we-learned-building-cloud-agents
  30. OpenAI, “Codex cloud,” OpenAI docs, accessed Oct 2026. learn.chatgpt.com/docs/cloud