An agentic loop runner for Claude Code.
# Install
git clone https://github.com/dschartman/ralph.git
cd ralph
uv sync
# Run tests
uv run pytest tests/ -v
# Install as a tool (recommended)
uv tool install --editable .Ralph is built on a core insight: LLMs in agentic loops are stateless within invocations. They can do genuine work, but they cannot maintain continuity of intention across context boundaries.
The name comes from Ralph Wiggum—a character who exists entirely in the present moment:
- No memory across invocations
- No self-monitoring for drift
- Genuine labor happens, but continuity is absent
Ralph (the tool) embraces this reality instead of fighting it. It provides external scaffolding for the executive functions the model cannot provide internally.
For the full conceptual framework, see THEORY.md.
Ralph uses a multi-agent architecture with three distinct agents per iteration:
Iteration N:
┌─────────────┐
│ Planner │ Reads spec + memory + feedback, outputs iteration intent
└──────┬──────┘
│
┌──────▼──────┐
│ Executor │ Does the assigned work, outputs efficiency notes
└──────┬──────┘
│
┌──────▼──────┐
│ Verifier │ Compares spec to reality, outputs DONE/CONTINUE/STUCK
└──────┬──────┘
│
▼
Next iteration or exit
Each agent runs as a fresh Claude session with its own tools and responsibilities:
| Agent | Role | Tools |
|---|---|---|
| Planner | Reads spec + trace + feedback, curates memory, outputs iteration intent | Bash, Read, Write |
| Executor | Does the assigned work, leaves comments in Trace | Read, Edit, Write, Bash, Glob, Grep |
| Verifier | Compares spec vs reality (no iteration context) | Read, Bash, Glob, Grep |
ralph run # Run Ralph (requires Ralphfile in current directory)
ralph status # Show current run status
ralph history # Show past runs
ralph input "msg" # Add human input for next iteration
ralph pause # Pause current run gracefully
ralph resume # Resume a paused run
ralph abort # Abort current runRalph uses Trace for task management:
trc ready # Show unblocked tasks
trc list # Show full backlog
trc show <id> # Show task details
trc create "title" --description "..." # Create a task
trc close <id> # Mark task complete- Python 3.13+
- uv (Python package manager)
- Git repository (Ralph requires git)
- Trace CLI (
trccommand)
git clone https://github.com/dschartman/ralph.git
cd ralph
uv syncInstalling as a tool allows Ralph to be run in any directory:
uv tool install --editable .
ralph # Now available globallyNote: The Ralphfile approach is experimental and may change in favor of using Trace for spec management.
A Ralphfile is a specification that Ralph tries to satisfy. Place it in your project root:
# My Project Spec
Build a CLI tool that does X.
## Acceptance Criteria
- [ ] CLI accepts --verbose flag
- [ ] Output is JSON formatted
- [ ] Tests pass with >80% coverageRalph iterates until all criteria are met (checkboxes checked) or it gets stuck.
Ralph stores state outside your repo at ~/.ralph/projects/<project-id>/:
~/.ralph/projects/<uuid>/
├── ralph.db # SQLite database (runs, iterations, agent outputs)
├── outputs/ # JSONL files for each agent invocation
├── summaries/ # Markdown summaries for completed runs
└── memory.md # Project memory (accumulated efficiency knowledge)
The project ID is a UUID stored in .ralph-id at your repo root (gitignored).
Ralph maintains a memory.md file that accumulates efficiency knowledge across iterations:
- Use UV for packages: `uv run pytest`, `uv add <pkg>` (not pip)
- Tests live in tests/, run with `uv run pytest -v`
- Database schema is in src/db/schema.sqlGood memory entries are:
- Actionable and project-specific
- Save 2+ tool calls when consulted
- Not ephemeral state ("tests passed") or obvious facts ("uses Python")
ralph/
├── src/ralph/
│ ├── cli.py # Typer CLI commands
│ ├── runner.py # Main iteration loop
│ ├── project.py # Project context and memory
│ ├── trace.py # Trace CLI wrapper
│ ├── agents/
│ │ ├── planner.py # Planner agent
│ │ ├── executor.py # Executor agent
│ │ └── verifier.py # Verifier agent
│ └── state/
│ ├── db.py # SQLite operations
│ └── models.py # Data models
└── tests/ # Test suite
# Run tests
uv run pytest tests/ -v
# Run Ralph on itself
uv run ralph
# Check task backlog
trc ready- Hermetized agents — Agents don't read CLAUDE.md or repo settings (SDK defaults only)
- Verifier has no iteration context — Only sees spec vs reality, prevents premature DONE
- Memory over rediscovery — Efficiency notes flow to shared project memory
- Test-driven executor — Write failing tests first, then make them pass
- External state — All Ralph data lives outside the repo
MIT