Ralph Wiggum — Continuous Self-Referential AI Loops

Autonomous Iteration Engine

Implements autonomous iteration where Claude works on a task repeatedly, reading its own previous output from files and git history to improve. Uses a Stop hook to block session exit and re-feed the prompt until a completion promise is satisfied.

3
Commands
1
Hook
8
Files
Shell
Language

🔄 Autonomous Loop🛑 Stop Hook📋 State Tracking✅ Completion Promise

📚 What is this & why does it exist?

Ralph Wiggum enables Claude Code to work autonomously in iterative loops. Instead of completing a single session and stopping, the plugin intercepts the session exit via a Stop hook, reads its own previous output from state files and git history, and re-feeds the prompt to continue improving. This creates a self-referential improvement cycle where each iteration builds on the last, controlled by a configurable completion promise and maximum iteration count.

💡 Real-world analogy

Think of a painter who steps back from the canvas, evaluates what they see, takes notes on what to improve, then steps forward again to make another pass — repeating until the painting matches their original vision statement. Ralph Wiggum is that evaluation-and-retry loop for Claude. The state file is the painter's notes, the completion promise is the vision statement, and the stop hook is the mechanism that keeps them at the easel instead of leaving the studio.

Architecture

flowchart LR
    subgraph UserEntry["User Interaction"]
        U["User"] -->|"/ralph-loop"| RL["Start Loop"]
        U -->|"/cancel-ralph"| CR["Cancel Loop"]
        U -->|"/ralph-wiggum:help"| HLP["Show Help"]
    end
    subgraph LoopEngine["Autonomous Loop Engine"]
        RL --> INIT["Initialize State File"]
        INIT --> WORK["Claude Performs Work"]
        WORK --> EXIT["Session Attempts Exit"]
        EXIT --> SH["stop-hook.sh Intercepts"]
        SH --> RS["Read State File"]
        RS --> CHECK{"Completion
Promise Met?"} CHECK -->|No| RF["Re-feed Prompt"] RF --> INCR["Increment Iteration"] INCR --> WORK CHECK -->|Yes| DONE["Allow Exit"] end subgraph StateManagement["State"] SF["ralph-loop.local.md"] GH["Git History"] RS --> SF RS --> GH end

Commands

CommandDescriptionArguments
/ralph-loopStarts the autonomous iteration loop. Initializes the state file with YAML frontmatter, sets the completion promise, and begins the first work cycle.--max-iterations <n> (default: 10), --promise "<text>"
/cancel-ralphGracefully stops the loop after the current iteration completes. Sets the state file's cancelled: true flag so the stop hook allows exit.None
/ralph-wiggum:helpDisplays usage information, current loop status, and configuration options.None

Hook Mechanism

stop-hook.sh

The core of the plugin is a Stop event hook that intercepts Claude Code's session exit. When the session would normally terminate, the hook:

  1. Reads the state file (ralph-loop.local.md) to get current iteration count and completion promise
  2. Checks git history for recent changes made in the current loop
  3. Evaluates whether the completion promise text is satisfied
  4. If not complete and under max iterations: blocks exit, increments counter, re-feeds the prompt
  5. If complete or max iterations reached: allows normal exit with a summary
sequenceDiagram
    participant User
    participant Claude as Claude Code
    participant Hook as stop-hook.sh
    participant State as ralph-loop.local.md
    participant Git as Git History

    User->>Claude: /ralph-loop --promise "all tests pass"
    Claude->>State: Create state file (iteration: 0, max: 10)
    Claude->>Claude: Perform work (iteration 1)
    Claude->>Hook: Session exit triggered
    Hook->>State: Read current state
    State-->>Hook: iteration: 1, promise: "all tests pass"
    Hook->>Git: Check recent commits & diff
    Git-->>Hook: Changes summary
    Hook->>Hook: Evaluate completion promise
    Hook-->>Claude: Promise NOT met → block exit
    Hook->>State: Update iteration: 2
    Hook->>Claude: Re-feed prompt with context
    Claude->>Claude: Perform work (iteration 2)
    Claude->>Hook: Session exit triggered
    Hook->>State: Read current state
    Hook->>Git: Check recent commits
    Hook->>Hook: Evaluate completion promise
    Hook-->>Claude: Promise MET → allow exit
    Claude-->>User: Loop complete (2 iterations)

State File Format

The state file ralph-loop.local.md uses YAML frontmatter to track loop state. It is created in the project root and is gitignored by convention (the .local. suffix).

---
iteration: 3
max_iterations: 10
completion_promise: "all tests pass and coverage exceeds 80%"
started_at: "2026-03-25T14:30:00Z"
last_iteration_at: "2026-03-25T14:45:22Z"
cancelled: false
status: "in_progress"
---

## Iteration Log

### Iteration 1
- Fixed failing test in auth module
- Coverage: 72%

### Iteration 2
- Added missing edge case tests
- Coverage: 78%

### Iteration 3
- Refactored test helpers, added integration tests
- Coverage: 83% ✓

Key Components

ComponentFileRole
ralph-loopcommands/ralph-loop.mdMain command to start autonomous iteration loop
cancel-ralphcommands/cancel-ralph.mdGracefully stop the loop after current iteration
ralph-wiggum:helpcommands/help.mdDisplay usage and current loop status
stop-hook.shhooks/stop-hook.shIntercepts session exit, evaluates state, re-feeds prompt
state-managerlib/state-manager.shReads and writes the YAML frontmatter state file
git-readerlib/git-reader.shExtracts recent git changes for context injection
promise-evaluatorlib/promise-evaluator.shChecks if completion promise is satisfied
plugin.json.claude-plugin/plugin.jsonPlugin manifest with hook registration

Data Flow

flowchart TD
    subgraph Initialization
        CMD["/ralph-loop --promise 'tests pass'"] --> PARSE["Parse Arguments"]
        PARSE --> CREATE["Create State File"]
        CREATE --> REGISTER["Register Stop Hook"]
    end
    subgraph IterationCycle["Each Iteration"]
        REGISTER --> WORK["Claude Performs Work"]
        WORK --> COMMIT["Changes Committed"]
        COMMIT --> TRIGGER["Exit Triggers Hook"]
        TRIGGER --> READ["Read State + Git"]
        READ --> EVAL{"Promise
Evaluation"} EVAL -->|"Not Met"| UPDATE["Update State File"] UPDATE --> REFEED["Re-feed Prompt"] REFEED --> WORK EVAL -->|"Met"| SUMMARY["Generate Summary"] end subgraph Termination SUMMARY --> LOG["Write Final Log"] LOG --> CLEANUP["Clean Up Hook"] CLEANUP --> EXIT["Session Exits"] end

Interactions

ModuleInterfaceData Exchanged
Claude Code CLIStop Hook eventSession exit signal intercepted and conditionally blocked
GitCLI commandsRecent commits, diffs, and file change lists for context
File SystemState file I/OYAML frontmatter state with iteration count and promise
Claude Code PromptRe-feed mechanismPrevious context, iteration log, and remaining work summary
UserCommandsLoop configuration, cancellation, and status queries

Directory Map

Source tree for Ralph Wiggum
ralph-wiggum/
├── .claude-plugin/plugin.json          ← Plugin manifest with hook registration
├── README.md                           ← Plugin documentation
├── commands/
│   ├── ralph-loop.md                   ← Start autonomous loop command
│   ├── cancel-ralph.md                 ← Cancel loop command
│   └── help.md                         ← Help and status command
├── hooks/
│   └── stop-hook.sh                    ← Core stop event interceptor
└── lib/
    ├── state-manager.sh                ← YAML state file read/write
    ├── git-reader.sh                   ← Git history context extraction
    └── promise-evaluator.sh            ← Completion promise checker

Configuration Reference

ParameterDefaultDescription
max_iterations10Maximum number of loop iterations before forced exit
completion_promise(required)Natural language description of the goal that must be satisfied to end the loop
state_file_pathralph-loop.local.mdPath to the state file relative to project root
git_context_depth5Number of recent commits to include as context
auto_committrueWhether to auto-commit changes after each iteration
cooldown_seconds0Delay between iterations to avoid rate limits
verbose_loggingfalseWrite detailed iteration logs to the state file body

Error Handling

⚠️ Max Iterations Reached

When the iteration count exceeds max_iterations, the hook allows exit and writes a summary noting the promise was not met. The state file status is set to max_reached.

🛑 Corrupted State File

If the state file is missing or has invalid YAML, the hook fails open (allows exit) and logs an error. The user can re-run /ralph-loop to start fresh.

🔄 Cancellation

Running /cancel-ralph sets cancelled: true in the state file. The next time the stop hook fires, it sees the flag and allows graceful exit with a partial summary.