CCLearn

The Ralph loop: fresh context every iteration

Re-running one prompt file through `claude -p` in a shell loop — one task per iteration, each starting from empty context — is a build strategy, not just a batch trick: the loop's job is to keep the context window small rather than to remember.

docs corroborate

The official documentation describes the mechanism this relies on. The technique itself is community practice.

What this costs you if it is wrong

An unattended loop needs scoped permissions and a revertable target. The docs' own auto-mode classifier treats "launching an autonomous agent loop that runs without human approval or a sandbox" as a blocked action, so a loop built on `--dangerously-skip-permissions` is running exactly the pattern Claude Code is designed to stop. Point it at a sandbox or a throwaway branch, gate each iteration on green tests, and treat the $50,000-for-$297 figure as an unaudited anecdote rather than a budget.

You have a big, well-specified job — a migration, a port, a feature with forty pieces — and you are running it as one long session. Around the third hour the session is mostly its own history: earlier failed approaches, files read twice, a compaction summary standing in for the reasoning that produced the current state. Quality drops and you cannot say exactly when it started dropping.

The Ralph technique, named by Geoffrey Huntley, inverts the instinct that got you there. Stop trying to carry state forward. Put the state on disk, and run a loop where every iteration begins with an empty context window, does exactly one thing, and dies.

bash
#!/usr/bin/env bash
# ralph.sh — run as: bash ralph.sh
while :; do
  cat PROMPT.md | claude -p \
    --allowedTools "Read,Edit,Bash(npm test),Bash(git commit *)"
done

The loop is not there to remember. It is there to guarantee that nothing is remembered.

What has to live in PROMPT.md

The prompt file is the whole design. It is re-read verbatim on every iteration, so anything not written there does not exist. Huntley's named failure modes map almost one-to-one onto lines the file has to carry:

Failure modeThe line that prevents it
Reimplementing something that already existsSearch the codebase for the feature before assuming it is missing. This is his top failure mode — a fresh context has no memory of iteration 12 building the thing
Placeholder implementations that satisfy the compilerState that a stub, a TODO, or a function returning a fixed value does not count as done
Context exhaustion mid-taskScope each iteration to one item, so no single run needs the whole plan in context
A spec that was simply wrongNothing in the prompt file fixes this. The loop builds a bad spec faithfully and at speed

It also has to define what counts as validation — compiles, tests pass, lints clean — because otherwise "looks done" is the only signal the agent has. That part the docs agree with: the glossary defines a verification loop as the prerequisite for unattended runs, since without one "the only thing deciding the agent is finished is the agent itself."

How this differs from the loops Claude Code ships

Three built-ins look like this and are not:

Context per iterationStops when
while :; do ... claude -p; doneEmpty, re-read from diskYou kill it
/loop 5m <prompt>The open session's, accumulatingYou stop it, or the session ends
/goal <condition>One session, one growing contextAn evaluator model judges the condition met or impossible
/batch <instruction>Fresh per subagent, in its own worktreeThe 5–30 subagents finish and open PRs

/goal is the closest built-in answer to "keep going until it's right," and with -p it runs the loop to completion in a single invocation — one context, many turns. That is the opposite trade from Ralph. /batch is the closest in spirit: independent fresh contexts, one unit of work each. The gap Ralph fills is sequential work where iteration N+1 depends on N having landed, which fan-out cannot express.

What the docs do and do not back

The mechanism is entirely documented. The best-practices page shows the shell loop over claude -p with --allowedTools scoping for unattended runs, and it recommends writing a spec to a file and then starting a fresh session to execute it — spec on disk, clean context, exactly Ralph's move performed once by hand. It also states the underlying principle outright: a clean session with a better prompt almost always outperforms a long session with accumulated corrections.

What no page says is that you should do this on repeat, without supervision, as the way you build a feature. Nor do the docs anywhere mention the duplicate-implementation failure mode, which is the single most useful thing in Huntley's writeup and the one you will hit first.

What is unverified here

Nobody has run this and measured it. Specifically:

  • The economics are self-reported. A $50,000 contract delivered for $297 of tokens is one person's anecdote about one project, with no baseline for what the same work cost in a normal session. Treat it as evidence the technique is not absurd, not as a cost model.
  • "Beats one long session" is untested. There is no A/B anywhere — same spec, same repo, loop versus session, quality and cost compared. That comparison is the experiment that would settle this, and it is cheap to run on a small feature.
  • Iteration count is unbounded by design. The loop has no completion condition. You decide it is done by looking, which reintroduces the human in the place the technique claims to remove them.

Huntley is himself explicit that there is no perfect prompt — the loop, not the wording, is the artefact you are engineering. Which is a nice way of saying the technique's value is a claim about process, and process claims are the hardest kind to check.

Checkpoint

  • Why does re-reading the spec from disk each iteration beat carrying it in context?
    Show answer

    Because the loop's job is to guarantee that nothing is remembered. A carried context fills with failed approaches, files read twice, and a compaction summary standing in for the reasoning that produced the current state — the quality drop you cannot date. Re-reading PROMPT.md verbatim keeps the state on disk exactly as written, and claude -p still loads CLAUDE.md and your working-directory configuration unless you pass --bare, so conventions stay ambient while only the transcript is thrown away. The docs back the underlying principle that a clean session with a better prompt beats a long one carrying corrections; that running it on repeat beats one long session is the half nobody has A/B tested.

  • Your loop keeps rebuilding a helper that already exists. Which line of PROMPT.md is missing?
    Show answer

    The line telling it to search the codebase for the feature before assuming it is missing. That is Huntley's top failure mode and a direct consequence of the design: a fresh context has no memory of iteration 12 building the helper, so the instruction has to live in the file that gets re-read rather than in the run that made the discovery. Anything not written in PROMPT.md does not exist as far as the next iteration is concerned — and the docs never mention this failure mode anywhere, so you will not find it warned about officially.

  • When would /batch or /goal be the better tool than a while : loop?
    Show answer

    /batch when the work fans out: independent units on disjoint files, each subagent starting from a fresh context in its own worktree and opening a pull request. /goal when you want "keep going until it's right" inside one session — an evaluator model checks your condition after every turn and stops when it is met or judged impossible, and under -p it runs to completion in a single invocation: one context growing across many turns, the opposite trade from Ralph. The while : loop earns its place on sequential work where iteration N+1 depends on N having landed, which fan-out cannot express, and it buys that with no completion condition at all — you are the one who decides it is done.

Where this came from

Official pages that back this