A hands-on example of the Ralph Loop (also known as the "Ralph Wiggum Loop"), an autonomous AI coding workflow originally introduced by Geoffrey Huntley.
This repository demonstrates the Ralph Loop by building a simple User CRUD API with Spring Boot 4 from a minimal PRD (Product Requirements Document).
The Ralph Loop is a pattern where an AI agent reads a PRD, implements one task at a time, verifies it with tests, and repeats until all tasks are complete. When you run ./ralph.sh, the following happens:
ralph.shinvokesclaude -pwith the contents ofprompt.md- Claude reads
prd.mdandprogress.md, then selects the next task to work on - Claude implements the task and writes unit tests
- Claude runs
./mvnw test— if tests fail, it fixes the code before proceeding - Claude marks the task as checked in
prd.mdand logs what it did inprogress.md - Claude stages all changes and creates a git commit
- If unchecked tasks remain,
ralph.shstarts the next iteration from step 1 with a fresh context window - When all tasks are checked, Claude outputs
<promise>COMPLETE</promise>and the loop exits
- Java 25+
- Claude Code CLI installed and authenticated
jqandbc(used byralph.shfor token usage tracking)
- Clone the repository:
git clone https://github.com/hainet50b/ralph-loop-example.git
cd ralph-loop-example- Create a branch for the Ralph Loop run (do not run on
main):
git switch -c example/ralph-loop-result-
(IMPORTANT) Review
prompt.mdandprd.mdbefore running. The loop uses--dangerously-skip-permissions, which allows the AI agent to execute arbitrary commands without confirmation. The exact behavior cannot be guaranteed. -
Run the loop:
./ralph.shBy default, the loop runs up to 10 iterations. To override:
./ralph.sh 20- Once complete, start the application and try the API:
./mvnw spring-boot:run
curl -s localhost:8080/actuator/health
curl -s -X POST localhost:8080/users -H 'Content-Type: application/json' -d '{"name":"Alice","email":"alice@example.com"}'
curl -s localhost:8080/users- To run again, archive the current result branch and start fresh from step 2:
git branch -m "$(git branch --show-current)-$(git merge-base --fork-point main | cut -c 1-7)"
git switch mainSee the example/ralph-loop-result branch for the result of a completed Ralph Loop run, including all generated source code, tests, and progress log.
The following run was based on example/ralph-loop-result-a9e88cc and completed using Claude Opus 4.6 in 9 iterations (871s total):
| # | Task | Time |
|---|---|---|
| 1 | Create User entity | 79s |
| 2 | Create UserRepository | 77s |
| 3 | Create UserService with CRUD methods | 60s |
| 4 | Create UserController with CRUD endpoints | 116s |
| 5 | Add exception handling for 404 | 105s |
| 6 | Add exception handling for 409 | 117s |
| 7 | Add Spring Actuator (health endpoint only) | 196s * |
| 8 | Configure H2 Console | 52s |
| 9 | Create users.http (Post Task) | 53s |
* Iteration 7 took significantly longer than others. From progress.txt:
In Spring Boot 4, TestRestTemplate moved from spring-boot-test to the spring-boot-resttestclient module (package org.springframework.boot.resttestclient), and it requires spring-boot-restclient as a transitive dependency for RestTemplateBuilder. Both were added as test-scoped dependencies.
The AI agent spent extra time discovering and resolving Spring Boot 4 dependency changes through trial and error. Tracking time per iteration helps identify where the agent struggles.
This example uses the following files to drive the Ralph Loop:
.
├── prd.md # What to build
├── prompt.md # How each iteration should behave
├── ralph.sh # Loop controller
├── progress.md # Work trail
└── metrics.csv # Token usage and cost per iteration
The Product Requirements Document. Defines what to build — API specification, data model, and tasks as checkboxes.
Note: In this example, specifications are written inline. You could also use dedicated specification formats (e.g., OpenAPI) as separate files and reference them from the PRD.
The PRD consists of the following sections:
- Goal — What to build, in one sentence.
- Tech Stack — Frameworks and libraries. Constrains the AI agent to technologies the developer can review and maintain.
- API Endpoints — The API contract the AI agent implements.
- Data Model — The data structure the AI agent implements.
- Tasks — Implementation work verified by unit tests. Each checkbox corresponds to one iteration of the loop.
- Post Tasks — Extra artifacts (e.g.,
.httpfiles) that do not require test verification. Also one checkbox per iteration. - Completion Criteria — A machine-verifiable definition of "done" that the AI agent checks after each task.
Defines how each iteration should behave — task selection, testing requirements, commit workflow, and completion signal. Passed to Claude on every iteration. Separated from ralph.sh to keep loop control and iteration behavior independent.
The loop controller. A bash script that:
- Runs up to N iterations
- Calls
claude -pwith the contents ofprompt.mdon each iteration - Tracks duration, token usage, and cost per iteration, and records them to
metrics.csv - Exits when:
- Claude outputs
<promise>COMPLETE</promise>(all tasks done) - The max iteration count is reached (exits with failure)
- Claude outputs
An initially empty file where the AI agent logs what it did after each iteration — what was done, what files were changed, and any remarks (issues, workarounds, lessons learned). Serves as both a work trail and inter-iteration memory (since each claude -p call starts with a fresh context window).
Note: This file is commonly named
progress.txtwith a.txtextension, since it is primarily written and consumed by the LLM and does not require a specific format. However, in practice, humans frequently review the progress log to track what decisions were made across iterations, so this example uses.mdfor better readability.
A CSV file where ralph.sh records duration, token usage, and cost for each iteration. Tracking time per iteration helps identify tasks that are difficult or require attention, and can inform how to adjust task granularity in the PRD. Tracking tokens and cost helps verify that changes to prd.md or prompt.md do not cause unexpected spending.
Note:
metrics.csvcaptures how the code was built, not what was built. In traditional development, this kind of process data would not belong in a Git repository. However, in AI-driven development, recording the cost and behavior of the generation process is gaining importance. Until the ecosystem for tracking AI development processes matures, committing this file to Git is a temporary workaround. Whether to do so depends on your organization and project needs.