A Rust CLI tool implementing the Ralph Wiggum technique - iterative AI development loops that let AI agents (Cursor, Claude) work autonomously while you supervise.
Ralph is a development methodology based on continuous AI agent loops. As Geoffrey Huntley describes it: "Ralph is a Bash loop" - a simple while true that repeatedly feeds an AI agent a prompt file, allowing it to iteratively improve its work until completion.
The technique is named after Ralph Wiggum from The Simpsons, embodying the philosophy of persistent iteration despite setbacks.
# Traditional Ralph (bash loop):
while :; do cat PROMPT.md | claude ; done
# ralph does this with any supported AI agent:
ralph loop build --max-iterations 50Each iteration:
- Reads the prompt file (PROMPT_plan.md or PROMPT_build.md)
- Invokes the agent with the prompt
- Waits for completion
- Runs validation (backpressure)
- Checks for idle detection or max iterations
- Git commits and pushes changes
- Repeats with fresh context
# Clone the repository
git clone https://github.com/your-org/ralph.git
cd ralph
# Build and install
cargo install --path .# Build and run directly
nix run github:your-org/ralph
# Or install into your profile
nix profile install github:your-org/ralph
# Build locally
nix build
./result/bin/ralph --help# Enter the development shell with all tools
nix develop
# Or use direnv (recommended)
direnv allowRun checks:
# Run all checks (build, clippy, fmt, tests)
nix flake check
# Individual checks
nix build .#checks.x86_64-linux.ralph-clippy
nix build .#checks.x86_64-linux.ralph-fmt
nix build .#checks.x86_64-linux.ralph-test# Initialize Ralph in your project
cd /path/to/your/project
ralph init
# Edit the configuration files:
# - ralph.toml - Select your agent (cursor or claude)
# - AGENTS.md - Add your build/test commands
# - specs/ - Create specification files for your features
# - PROMPT_plan.md / PROMPT_build.md - Customize if needed
# Run planning mode to generate IMPLEMENTATION_PLAN.md
ralph loop plan --max-iterations 5
# Review the plan, then start building
ralph loop build --max-iterations 50Initialize Ralph files in the current project.
ralph init # Create default files
ralph init --force # Overwrite existing filesCreates:
ralph.toml- Project configurationPROMPT_plan.md- Planning mode promptPROMPT_build.md- Building mode promptAGENTS.md- Operational guide (build/test commands).cursor/rules/ralph.mdc- Cursor rules for Ralph
Start a Ralph loop.
# Planning mode (generates IMPLEMENTATION_PLAN.md)
ralph loop plan --max-iterations 5
# Building mode (implements from plan)
ralph loop build --max-iterations 50
# Skip Docker sandbox (run directly on host)
ralph loop build --no-sandbox
# Use custom prompt file
ralph loop build --prompt my-custom-prompt.mdOptions:
--max-iterations <N>- Stop after N iterations (default: unlimited)--no-sandbox- Run without Docker isolation--prompt <FILE>- Use custom prompt file
Show current loop status.
ralph statusCancel an active loop.
ralph cancelRevert Ralph commits.
ralph revert --last 3 # Revert last 3 commitsRemove Ralph state files.
ralph clean # Remove state file only
ralph clean --all # Remove all Ralph files[agent]
# Which AI agent to use: "cursor" or "claude"
provider = "cursor"
# Cursor CLI configuration
# See: https://cursor.com/docs/cli/overview
[agent.cursor]
# Path to Cursor agent CLI
# - Default: "agent" (standard installation)
# - NixOS: "cursor-agent"
# - Custom: "/path/to/agent"
path = "agent"
output_format = "text"
# Claude Code CLI configuration
# See: https://docs.anthropic.com/en/docs/claude-code
[agent.claude]
path = "claude"
skip_permissions = true # Required for autonomous operation
output_format = "stream-json"
[sandbox]
# Enable Docker sandboxing for isolation
enabled = true
image = "ralph:latest"
[sandbox.network]
# Network policy: "allow-all", "allowlist", "deny"
policy = "allow-all"
# Allowed domains when policy = "allowlist"
# allowed = ["github.com", "registry.npmjs.org"]
[sandbox.resources]
memory = "8g"
cpus = "4"
timeout_minutes = 60
[git]
auto_push = true
protected_branches = ["main", "master", "production"]
[completion]
# Stop after N consecutive idle iterations (validation passes, no new commits)
idle_threshold = 2Ralph can automatically validate code after each agent iteration to catch compilation errors and test failures:
[validation]
# Enable code validation after each iteration
# If disabled, the loop relies entirely on the agent to validate code
enabled = true
# Validation command to run
# Can be a single command or space-separated command with arguments
# Examples:
# - "nix flake check" (default, recommended for Nix projects)
# - "cargo check"
# - "cargo test"
# - "./validate.sh"
command = "nix flake check"When validation fails:
- Error is logged and a notification is sent (if configured)
- Loop continues (agent can fix the issue in the next iteration)
- State tracks the validation error for
ralph status
[agent]
provider = "cursor"
[agent.cursor]
path = "agent" # Use "cursor-agent" on NixOS
# model = "claude-sonnet-4-20250514" # Optional, uses Cursor's default
output_format = "text"[agent]
provider = "claude"
[agent.claude]
path = "claude"
skip_permissions = true # Required for autonomous operation
# model = "opus" # Optional
output_format = "stream-json"
verbose = falseUsed in planning mode to generate IMPLEMENTATION_PLAN.md:
- Studies specs and existing code
- Performs gap analysis
- Creates prioritized task list
- Does NOT implement anything
Used in building mode:
- Studies specs and implementation plan
- Picks the most important task
- Implements and runs tests
- Commits and pushes on success
- Updates plan with learnings
Operational guide with build/test commands:
## Build & Run
npm install
npm run build
## Validation
- Tests: `npm test`
- Typecheck: `npm run typecheck`
- Lint: `npm run lint`Ralph runs with maximum autonomy, which requires containment. The philosophy: "It's not if it gets popped, it's when. And what is the blast radius?"
By default, ralph runs the AI agent inside a Docker container:
- Workspace mounted read-write at
/workspace - Credentials mounted read-only (~/.ssh, ~/.gitconfig)
- Resource limits (CPU, memory, timeout)
- Network policy (allow-all by default, configurable)
docker build -t ralph:latest .For trusted environments:
ralph loop build --no-sandboxOr in ralph.toml:
[sandbox]
enabled = falseCreate specification files in specs/:
specs/
├── user-authentication.md
├── product-catalog.md
└── shopping-cart.md
Each spec should define:
- What to build (requirements)
- Acceptance criteria
- Edge cases
ralph loop plan --max-iterations 5Ralph will:
- Study all specs
- Analyze existing code
- Identify gaps
- Generate
IMPLEMENTATION_PLAN.md
Review the plan before proceeding.
ralph loop build --max-iterations 50Ralph will:
- Pick the most important task from the plan
- Implement it fully (no stubs!)
- Run tests
- Commit and push on success
- Update the plan
- Repeat
Don't aim for perfect on first try. Let the loop refine the work.
"Deterministically bad" means failures are predictable and informative. Use them to tune prompts.
Success depends on writing good prompts, not just having a good model.
Keep trying until success. The loop handles retry logic automatically.
Let Ralph ralph. But use sandboxing, protected branches, and review commits.
Ralph cannot force-push to branches listed in protected_branches:
[git]
protected_branches = ["main", "master", "production"]# Emergency stop
ralph cancel
# Revert uncommitted changes
git reset --hard
# Revert Ralph commits
ralph revert --last 3All commits are recoverable via git reflog.
| Environment | How it Works |
|---|---|
| Cursor Editor | Run CLI in terminal, Cursor runs in background mode |
| cursor-cli | Direct CLI invocation in headless mode |
| Git Worktrees | Isolated state per worktree |
| Cursor Cloud | API-based invocation (future) |
ralph needs an AI agent CLI. Depending on your configuration:
For Cursor:
# Install Cursor CLI
curl https://cursor.com/install -fsS | bash
# On NixOS, configure in ralph.toml:
[agent.cursor]
path = "cursor-agent"For Claude:
# Install Claude Code CLI
npm install -g @anthropic-ai/claude-codeIf you see Docker connection errors:
# Start Docker
sudo systemctl start docker
# Or disable sandbox
ralph loop build --no-sandboxAlways set --max-iterations or rely on idle detection (idle_threshold in config):
# Safe defaults
ralph loop build --max-iterations 50MIT
- Geoffrey Huntley - Original Ralph Wiggum technique
- Ralph Playbook - Comprehensive Ralph documentation