rwl 0.1.7
dotnet tool install --global rwl --version 0.1.7
dotnet new tool-manifest
dotnet tool install --local rwl --version 0.1.7
#tool dotnet:?package=rwl&version=0.1.7
nuke :add-package rwl --version 0.1.7
<div align="center">
π Ralph Wiggum Loop
@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@ @@@@@@ @@@ @@@ @@ @@@@ @@@@@@@@@@
@@@@@ @@@@@@@ @@ @@@ @@ @@ @@ @@ @@@@@@@@@
@@@@@ @@@@ @@@ @@ @@@ @@ @@ @@ @@@ @@@@@@@@@@
@@@@@@ @@@ @@@ @@@ @@ @@ @ @@ @@ @@@@@@@@@@@
@@@@@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@ @@@@@@@
@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@
@@@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@@@
@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@
@@@ @@ @@ @@ @ @@ @ @@ @@ @@ @@ @@ @@@@@
@@ @@ @@ @@ @@ @@ @ @ @@ @ @ @@ @@ @@@
@@ @ @@ @@@ @@ @@ @@ @@
@@ @@ @@ @@ @@ @@ @
@@ @@ @@ @@ @@ @@@@@@@@@@@@@ @@@@@@@@@@@ @@
@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@
@@ @@ @@ @@ @@ @@ @@ @@ @@
@@ @@ @@ @@ @@ @@ @@ @@ @@
@ @@ @@ @@ @@ @@ @ @ @@@ @ @@
@ @ @@ @@@@ @ @@ @@@ @@ @@
@@@@@@@ @@ @@ @@ @ @ @@
@@@ @@@ @@ @ @@ @@@ @@
@@ @@@ @@ @@@@@@@@ @@@@ @@@ @
@@ @@@@ @@@@ @@@ @@@@@@ @@@@@@ @@
@ @ @ @@@@@ @@ @
@@ @ @@ @@ @@
@@@ @@ @@@@@ @@ @@@
@@@@ @ @@@@@ @@@ @@ @@
@@@@@@@ @@@@ @@@@@@@@@@ @@
@@ @@@ @@@@ @@
@@ @@ @@@ @@
@@@ @@ @@ @@ @@@ @@
@@ @@ @@ @@@@@@@@@@@ @@@@
@@@ @@@@@@@@@ @@@ @@ @@@@@@
@@ @@@@ @@ @ @@@@@@@@@@@@@@@@@@@
@@ @@@ @ @@@@ @@@ @@
@@ @@@@@ @ @ @@ @
@ @@@@@@ @ @@ @@
@@ @@@@@@@@@ @@@@@ @ @@ @@@@
@@@@ @@@@@@@@@@@@@@ @@@@@@ @@ @@@@
@@@@@@@ @@ @@@@ @@ @@@ @@ @@@
@@@ @@@ @@ @@@@ @@@ @@ @@@ @@
@ @@@@ @@ @@@@ @@ @@ @@@ @@
@@ @@@@@ @@@ @@@ @@ @@@@@@ @@
@ @@@@@ @@@ @@@ @@ @@@ @@ @@@
@@ @@@@@ @@ @@ @@ @@ @@@ @@@@
@ @@@@ @@@@@@@ @@@ @@@@ @@
@@ @@@@ @@@ @@@ @@@ @@
@@ @@ @ @@
@@@ @@ @@
@@@@ @@@ @@
@@ @@ @@@ @@@
@ @@ @@@ @@@
@ @@@ @@@ @@@@
@@ @@@ @@@ @@@@
"I'm in danger!"
An iterative, fresh-context agent loop pattern for GitHub Copilot CLI
Complete complex coding tasks reliably by running an AI agent in a loop where each iteration starts fresh, reads persistent state from disk, completes one bounded task, and writes results back.
</div>
Table of Contents
- Overview
- Why This Works
- Architecture
- Quick Start
- CLI Reference (
rwl) - VS Code Agents
- Components
- Configuration
- Usage Examples
- Failure Modes & Detection
- Best Practices
- Troubleshooting
- Attribution
- License
Overview
The Ralph Wiggum Loop is an agent design pattern created by Geoffrey Huntley that turns the biggest weakness of large language models β context window degradation β into a feature.
Instead of letting an AI agent run until its context fills up and it starts making mistakes, the loop:
- Starts the agent with a fresh context
- Reads task state from persistent files (
TASKS.md,PROGRESS.md) - Executes exactly ONE bounded task
- Writes results back to disk
- Terminates and restarts β fresh context, no accumulated confusion
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RALPH WIGGUM LOOP β
β β
β βββββββββββββ ββββββββββββ ββββββββββββ β
β β Read ββββββΆβ Execute ββββββΆβ Write β β
β β State β β ONE Task β β Results β β
β βββββββββββββ ββββββββββββ ββββββββββββ β
β β² β β
β β ββββββββββββ β β
β βββββββββββββ Fresh ββββββββββββββ β
β β Context β β
β ββββββββββββ β
β β
β State Files (persistent on disk): β
β π TASKS.md π PROGRESS.md βοΈ LOOP_CONFIG β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
This repository provides the pattern as a complete set of reusable components for GitHub Copilot CLI and VS Code Agents.
Why This Works
The Context Degradation Problem
LLMs have a well-documented performance curve within their context window:
Performance
β²
100%βββββββββββββ
β ββββ
β ββββ
β ββββ
β ββββ
β ββββ β "Dumb Zone"
0% ββββββββββββββββββββββββββββββββββΆ Context Fill %
0% 40% 70% 100%
At ~60-70% context utilization, models enter a "dumb zone" where they:
- Forget earlier instructions
- Contradict previous decisions
- Make increasingly poor choices
- Hallucinate solutions
The Fresh Context Solution
The Ralph Wiggum Loop sidesteps this entirely:
| Traditional Approach | Ralph Wiggum Loop |
|---|---|
| One long session | Many short sessions |
| Context accumulates until degraded | Context resets every iteration |
| Agent "forgets" early decisions | Agent re-reads decisions from files |
| Errors compound silently | Errors recorded and fed back |
| Hard to resume after crash | Natural crash recovery (state on disk) |
| Unclear progress | Progress tracked in PROGRESS.md |
Key Insight: Failures Are Data
When an iteration fails, the full error output is written to PROGRESS.md. The next iteration reads this and course-corrects. This is the pattern's superpower β errors don't corrupt context, they enrich it.
Architecture
ImInDanger/
βββ .github/
β βββ agents/ # Custom agent profiles
β β βββ ralph-wiggum-loop.agent.md # Main orchestrator
β β βββ loop-planner.agent.md # Task decomposition
β β βββ loop-reviewer.agent.md # Health analysis
β βββ skills/ # Reusable skills
β β βββ loop-runner/ # Main loop execution
β β β βββ SKILL.md
β β β βββ run-loop.sh
β β βββ task-state-manager/ # State file management
β β β βββ SKILL.md
β β β βββ init-state.sh
β β βββ convergence-detector/ # Pathology detection
β β β βββ SKILL.md
β β β βββ check-convergence.sh
β β βββ loop-guardrails/ # Safety enforcement
β β βββ SKILL.md
β β βββ check-guardrails.sh
β βββ instructions/ # Path-specific instructions
β β βββ loop-tasks.instructions.md
β β βββ loop-progress.instructions.md
β βββ copilot-instructions.md # Repository-wide instructions
βββ templates/ # Starter templates
β βββ TASKS.md
β βββ PROGRESS.md
β βββ PROMPT.md
β βββ LOOP_CONFIG.md
βββ hooks/ # Git hooks
β βββ pre-commit
β βββ post-iteration.sh
β βββ setup-hooks.sh
βββ examples/ # Example configurations
β βββ test-driven-refactor/
β β βββ TASKS.md
β β βββ README.md
β βββ build-fix/
β βββ TASKS.md
β βββ README.md
βββ AGENTS.md # Root agent instructions
βββ README.md # This file
GitHub Copilot SDK Integration
The rwl CLI integrates natively with the GitHub Copilot SDK (GitHub.Copilot.SDK v0.2.2+) to replace fragile shell-outs with a first-class .NET agent experience. When the SDK is available and authenticated, rwl run and rwl run-one drive the agent programmatically β with streaming output, custom tools, and enforced guardrails β all from within the process.
How It Works
Instead of spawning an external copilot CLI process, rwl uses the SDK to:
- Create a
CopilotClient(CopilotService) β registers custom tools and hooks once at startup - Open a fresh
CopilotSessionper iteration β implements the core Ralph Wiggum Loop pattern; fresh context every time, no leakage between iterations - Inject the loop protocol as a system message β uses
SystemMessageMode.Appendso the agent knows it must complete exactly one task and update state files - Stream output in real time β
AssistantMessageDeltaEventevents are rendered live in the terminal via Spectre.Console
rwl run-one
[Iteration 3] Executing task: "Add unit tests for AuthService"
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΆ Agent: Reading current task list...
βΆ Agent: Reading recent progress...
βΆ Agent: Checking config for allowed paths...
βΆ Agent: [Editing src/AuthService.Tests/AuthServiceTests.cs]
βΆ Agent: Running validation: dotnet test
All tests passed (47 tests, 0 failures)
βΆ Agent: Updating task status to done...
βΆ Agent: Appending progress entry...
β
Iteration complete β 1 task done
Authentication
The SDK requires GitHub Copilot access via the GitHub CLI:
gh auth login # Authenticate with GitHub
gh auth status # Verify authentication
rwl doctor # Verify SDK connectivity and tool registration
rwl doctor will show:
β
SDK available and authenticated
β
Ping: Connected
β
Tools registered: 6
β
Hooks registered: 1
If authentication fails or the SDK is unavailable, rwl automatically falls back to process-based execution (spawning gh copilot suggest or the run-loop.sh script) β no configuration required.
Custom Agent Tools
The agent can call these tools to interact with RWL state files:
| Tool | Description |
|---|---|
read_tasks |
Returns all tasks from TASKS.md with their current status markers |
read_progress |
Returns recent iteration entries from PROGRESS.md |
read_config |
Returns loop configuration from LOOP_CONFIG.md |
update_task_status |
Updates a task's status ([ ] β [~] / [x] / [!]) |
append_progress |
Writes a new formatted iteration entry to PROGRESS.md |
run_validation |
Executes the validation command from LOOP_CONFIG.md and returns output |
Using tools (rather than dumping all state into the system prompt) is more token-efficient β the agent pulls exactly the state it needs, when it needs it.
Guardrails
The SDK integration enforces guardrails via an OnPreToolUse hook (GuardrailHooks). Before any tool call is executed, the hook checks:
- Path restrictions β operations on files outside
AllowedPathsfromLOOP_CONFIG.mdare blocked - Operation limits β file writes per iteration are capped to
MaxFilesPerIteration - Protected patterns β deletions of test files or bulk lint suppressions are rejected
Blocked operations return an error result without executing, and the rejection is logged so the next iteration can see what was attempted.
Fallback Behavior
Both rwl run and rwl run-one follow this priority:
- SDK mode (default) β
CopilotService.RunIterationAsync()if SDK initializes successfully - Process fallback β spawns
copilot --agent=ralph-wiggum-loopor equivalent if SDK is unavailable - Script fallback β runs
run-loop.shif no agent binary is found
The fallback chain is automatic and transparent. Running rwl doctor before your first loop run is the easiest way to confirm which mode is active.
Quick Start
Option A: Using the rwl CLI (Recommended)
# Clone this repo
git clone https://github.com/michaelstonis/ImInDanger.git
# Install the CLI
cd ImInDanger && make link
# β or β
bash install.sh
# Navigate to your project and initialize
cd /path/to/your/project
rwl init
The rwl init wizard will:
- Detect your project type (Node, Go, Python, .NET, Rust, etc.)
- Copy agents, skills, instructions, and templates into your project
- Auto-configure validation commands and allowed paths
- Optionally install git hooks for safety guardrails
Then create your task plan:
rwl plan # Interactive task planning wizard
rwl doctor # Verify everything is set up correctly
rwl status # View the dashboard
Option B: Manual Setup
Copy the components into your repository:
# Clone or copy the components
cp -r .github/agents/ /path/to/your/project/.github/agents/
cp -r .github/skills/ /path/to/your/project/.github/skills/
cp -r .github/instructions/ /path/to/your/project/.github/instructions/
cp .github/copilot-instructions.md /path/to/your/project/.github/
cp AGENTS.md /path/to/your/project/
2. Initialize State Files
bash .github/skills/task-state-manager/init-state.sh
This creates TASKS.md, PROGRESS.md, and LOOP_CONFIG.md from templates.
3. Define Your Tasks
Edit TASKS.md with your objective and task list:
## Objective
Refactor authentication module to use JWT tokens
## Task List
### 1. Create JWT utility module
- **Status:** [ ]
- **Files:** `src/utils/jwt.ts`
- **Description:** Create JWT sign/verify functions using jsonwebtoken
- **Validation:** `npx tsc --noEmit`
### 2. Update auth middleware
- **Status:** [ ]
- **Depends on:** Task 1
- **Files:** `src/middleware/auth.ts`
- **Description:** Replace session-based auth with JWT verification
- **Validation:** `npm test -- --grep "auth"`
4. Configure the Loop
Edit LOOP_CONFIG.md:
## Safety Limits
- max_iterations: 15
- timeout_minutes: 10
## Validation Commands
npm test
npm run build
## Allowed Paths
src/**
tests/**
5. Run the Loop
Option A β Using the skill script:
bash .github/skills/loop-runner/run-loop.sh
Option B β Using Copilot CLI directly:
Prerequisite: Install and authenticate Copilot CLI so the
copilotcommand is available first. See the official docs: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/copilot-cli
# Single iteration
copilot --agent=ralph-wiggum-loop
# Manual loop
while true; do
copilot --agent=ralph-wiggum-loop --prompt "Execute one task from TASKS.md"
# Check if all tasks are done
grep -q '\[ \]' TASKS.md || break
done
Option C β Using VS Code:
Open the Copilot Chat panel and type:
@ralph-wiggum-loop Execute the next pending task from TASKS.md
6. Install Safety Hooks (Optional)
bash hooks/setup-hooks.sh
CLI Reference (rwl)
The rwl CLI is a .NET single-file binary built with Spectre.Console for rich terminal UI. It provides interactive wizards, dashboards, and management commands for the Ralph Wiggum Loop.
Requirements: .NET 10.0 runtime (for dotnet tool install) or .NET SDK 10.0+ (for building from source).
Installation
# Option 1: Install as a global .NET tool (recommended)
dotnet tool install -g rwl
# Option 2: Build & install self-contained binary (no runtime needed)
make install
# Option 3: Build & symlink for development
make link
# Option 4: Direct install script
bash install.sh --prefix /usr/local
To update an existing installation:
dotnet tool update -g rwl
To uninstall:
dotnet tool uninstall -g rwl
Note: When installed as a dotnet tool,
rwluses embedded resources for templates β noRWL_HOMEneeded. If building from source, setRWL_HOMEto the repo root sorwlcan find source templates:export RWL_HOME="/path/to/ImInDanger"
Building the NuGet Package
# Create the .nupkg
make pack
# Install locally from the built package
make install-tool
# Push to NuGet.org
dotnet nuget push src/Rwl/bin/Release/rwl.2.0.0.nupkg \
-s https://api.nuget.org/v3/index.json -k YOUR_API_KEY
Commands
| Command | Description |
|---|---|
rwl init |
Interactive setup wizard β adds loop components to your project |
rwl doctor |
Verifies all components are installed and configured correctly |
rwl status |
Dashboard showing task progress, iteration history, and config |
rwl plan |
Guided task creation β builds a complete TASKS.md with objectives |
rwl add-task |
Add a single task to an existing TASKS.md |
rwl run |
Start the loop (pass-through to run-loop.sh) |
rwl run-one |
Execute a single iteration |
rwl stop |
Create a stop flag to halt the loop after the current iteration |
rwl compact [N] |
Compact PROGRESS.md, keeping last N iterations (default: 5) |
rwl reset |
Reset loop state for a fresh run |
rwl health |
Run convergence and guardrail checks |
rwl --help |
Show usage information |
rwl --version |
Print version |
rwl init β Setup Wizard
The init wizard detects your project type and configures everything automatically:
$ cd my-node-project
$ rwl init
βββββββββββββββββββββββββββββββββββββββββββββββββ
β π Ralph Wiggum Loop π β
β "I'm in danger!" β
βββββββββββββββββββββββββββββββββββββββββββββββββ
Detected: node project
Source: /path/to/ImInDanger
Install Mode:
1) Full install (recommended)
2) Custom β choose components
3) Minimal β agents + templates only
βΈ Choice [1/2/3]: 1
βΈ Also install git hooks? [y/N]: y
Installing components...
β
.github/agents/ralph-wiggum-loop.agent.md
β
.github/agents/loop-planner.agent.md
β
.github/agents/loop-reviewer.agent.md
β
.github/skills/loop-runner/
...
β
LOOP_CONFIG.md (auto-configured)
π Done! 15 files installed.
rwl plan β Task Planning
Creates a complete TASKS.md interactively:
$ rwl plan
# Prompts for: objective, success criteria, validation command
# Then loops: add tasks with titles, descriptions, files, dependencies
# Outputs a fully-formed TASKS.md ready for the loop
rwl status β Dashboard
π Ralph Wiggum Loop β Status Dashboard
Tasks
βββββ
[ββββββββββββββββββββββββββββββ] 40% (4/10)
Pending [ ] 4
In Progress [~] 1
Done [x] 4
Failed [!] 1
Progress
ββββββββ
Iterations: 6 (4β 2β)
File size: 142 lines
Config
ββββββ
Max iterations: 25 Timeout: 10m
rwl doctor β Health Check
Verifies all components are properly installed:
$ rwl doctor
Git
βββ
β
Git repository
Agents
ββββββ
β
ralph-wiggum-loop
β
loop-planner
β
loop-reviewer
Skills
ββββββ
β
loop-runner (executable β)
...
State Files
βββββββββββ
β
TASKS.md
β
PROGRESS.md
β
LOOP_CONFIG.md
0 issue(s), 0 warning(s)
VS Code Agents
The Ralph Wiggum Loop ships with agent definitions (.agent.md files) that VS Code Copilot discovers automatically. There is no "plugin install" step β VS Code loads agents directly from the filesystem.
Requires:
chat.useNestedAgentsMdFiles: truein VS Code settings (enable in Settings β search "nested agents").
Method 1 β Open as Workspace
The simplest approach: clone the repo and open it as your workspace. VS Code auto-loads all agents and skills from .github/.
git clone https://github.com/michaelstonis/ImInDanger.git
cd ImInDanger
code .
Agents appear in the @ picker immediately:
| Agent | Invoke |
|---|---|
@ralph-wiggum-loop |
@ralph-wiggum-loop run one iteration |
@loop-planner |
@loop-planner break down my tasks |
@loop-reviewer |
@loop-reviewer check loop health |
Skills appear as slash commands: /loop-runner, /task-state-manager, /convergence-detector, /loop-guardrails.
Agent Handoffs
Agents wire together with one-click handoffs:
@loop-plannerβ after planning, offers "βΆοΈ Start Loop" β hands off to@ralph-wiggum-loop@ralph-wiggum-loopβ after executing, offers "π Review Loop Health" β hands off to@loop-reviewer@loop-reviewerβ after reviewing, offers "βΆοΈ Continue Loop" or "π Replan Tasks"
Method 2 β Copy into Your Project
To use the agents and skills within your own project:
# From the ImInDanger repo root
cp -r .github/agents /your/project/.github/
cp -r .github/skills /your/project/.github/
cp -r .github/hooks /your/project/.github/
Open your project in VS Code β agents and skills are workspace-scoped to your project.
Method 3 β Install to User Profile (Global)
Copy .agent.md files to your VS Code profile's agents/ directory to make them available in all workspaces.
macOS:
# VS Code Agents - Insiders build
PROFILE_AGENTS="$HOME/Library/Application Support/Agents - Insiders/User/agents"
# VS Code Insiders: "$HOME/Library/Application Support/Code - Insiders/User/agents"
# VS Code Stable: "$HOME/Library/Application Support/Code/User/agents"
mkdir -p "$PROFILE_AGENTS"
cp /path/to/ImInDanger/.github/agents/*.agent.md "$PROFILE_AGENTS/"
Linux:
PROFILE_AGENTS="$HOME/.config/Code/User/agents"
mkdir -p "$PROFILE_AGENTS"
cp /path/to/ImInDanger/.github/agents/*.agent.md "$PROFILE_AGENTS/"
Windows (PowerShell):
$ProfileAgents = "$env:APPDATA\Code\User\agents"
New-Item -ItemType Directory -Force -Path $ProfileAgents
Copy-Item "path\to\ImInDanger\.github\agents\*.agent.md" -Destination $ProfileAgents
To also install skills globally, copy to ~/.copilot/skills/:
mkdir -p "$HOME/.copilot/skills"
cp -r /path/to/ImInDanger/.github/skills/* "$HOME/.copilot/skills/"
Lifecycle Hooks
Lifecycle hooks live at .github/hooks/hooks.json and run shell scripts at key agent events:
| Hook | Trigger | Script |
|---|---|---|
SessionStart |
First prompt of a new session | hooks/session-start.sh β injects TASKS.md/PROGRESS.md summary |
Stop |
Agent session ends | hooks/session-stop.sh β warns if tasks are still in-progress |
Hooks only fire when the workspace containing .github/hooks/hooks.json is open. Example output from session-start.sh:
π Ralph Wiggum Loop β 4/7 tasks done, 1 in-progress, 2 pending. Last recorded: ## Iteration 5 β 2025-01-15T10:30:00Z.
Components
Agents
ralph-wiggum-loop β Main Orchestrator
The core agent profile. Each invocation:
- Reads
TASKS.md,PROGRESS.md,LOOP_CONFIG.md - Identifies the next pending or failed task
- Executes exactly ONE task
- Validates using the configured commands
- Updates state files with results
Invoke: @ralph-wiggum-loop, /agent ralph-wiggum-loop, or copilot --agent=ralph-wiggum-loop
loop-planner β Task Decomposition
Converts a high-level objective into a structured task list suitable for the loop pattern.
Invoke: @loop-planner "Refactor the auth module to use dependency injection"
The planner will:
- Break the objective into bounded, independently-completable tasks
- Order tasks by dependencies
- Add validation commands to each task
- Write the result to
TASKS.md
loop-reviewer β Health Analysis
Analyzes loop health by examining PROGRESS.md and TASKS.md. Detects:
- Oscillation (fix A breaks B, fix B re-breaks A)
- Stagnation (no progress across iterations)
- Metric gaming (tests deleted, assertions weakened)
- Context overflow (state files too large)
Invoke: @loop-reviewer "Analyze the current loop health"
Skills
loop-runner
The main execution skill. Provides a bash script (run-loop.sh) that:
- Runs the agent loop with configurable iteration limits
- Loads settings from
LOOP_CONFIG.md - Handles stop conditions (all done, stop flag, timeout, oscillation)
- Triggers automatic health reviews
- Logs each iteration
# Basic usage
bash .github/skills/loop-runner/run-loop.sh
# Custom limits
bash .github/skills/loop-runner/run-loop.sh --max-iterations 30 --timeout 15
task-state-manager
Initializes the persistent state files from templates:
# Create state files (won't overwrite existing)
bash .github/skills/task-state-manager/init-state.sh
# Force overwrite
bash .github/skills/task-state-manager/init-state.sh --force
convergence-detector
Analyzes loop progress for pathological behaviors:
# Check all modes
bash .github/skills/convergence-detector/check-convergence.sh --mode all
# Check specific mode
bash .github/skills/convergence-detector/check-convergence.sh --mode oscillation
bash .github/skills/convergence-detector/check-convergence.sh --mode stagnation
bash .github/skills/convergence-detector/check-convergence.sh --mode gaming
Exit codes: 0 = healthy, 1 = warning, 2 = critical
loop-guardrails
Pre-commit safety validation:
bash .github/skills/loop-guardrails/check-guardrails.sh
Checks:
- β Changes are within allowed paths
- β Diff size within limits
- β No test files deleted
- β No test assertions weakened
- β No stop flags present
Instructions
| File | Scope | Purpose |
|---|---|---|
.github/copilot-instructions.md |
All files | Repository-wide loop context |
AGENTS.md |
Repository root | Primary agent instructions |
.github/instructions/loop-tasks.instructions.md |
TASKS.md |
Task file editing rules |
.github/instructions/loop-progress.instructions.md |
PROGRESS.md |
Progress log rules |
Templates
| Template | Purpose |
|---|---|
templates/TASKS.md |
Task list with status markers |
templates/PROGRESS.md |
Append-only iteration log |
templates/LOOP_CONFIG.md |
Loop configuration and limits |
templates/PROMPT.md |
Base prompt for manual usage |
Hooks
| Hook | Purpose |
|---|---|
hooks/pre-commit |
Blocks commits that violate guardrails |
hooks/post-iteration.sh |
Validates state after each iteration |
hooks/setup-hooks.sh |
Installs hooks into .git/hooks/ |
Configuration
LOOP_CONFIG.md Reference
## Safety Limits
- max_iterations: 20 # Maximum loop iterations
- timeout_minutes: 10 # Per-iteration timeout
- auto_review_interval: 5 # Run health review every N iterations
## Validation Commands
npm test # Commands run after each task
npm run build
## Allowed Paths
src/** # Glob patterns for modifiable files
tests/**
## Restricted Paths
.env # Files agent must NEVER modify
*.lock
node_modules/**
## Diff Limits
- max_lines_per_iteration: 200 # Maximum lines changed per iteration
- max_files_per_iteration: 10 # Maximum files changed per iteration
State File Markers
| Marker | Meaning |
|---|---|
[ ] |
Pending β not yet started |
[~] |
In progress β currently being worked on |
[x] |
Done β completed successfully |
[!] |
Failed β attempted but unsuccessful |
[STOP] |
Emergency stop β halts the loop immediately |
Usage Examples
Test-Driven Refactoring
The ideal use case: existing tests define correct behavior, and you're restructuring code.
# 1. Plan the tasks
copilot --agent=loop-planner --prompt \
"Refactor UserService to use dependency injection. Tests are in tests/services/"
# 2. Review the generated TASKS.md
cat TASKS.md
# 3. Run the loop
bash .github/skills/loop-runner/run-loop.sh
# 4. Check health if needed
copilot --agent=loop-reviewer --prompt "How is the loop doing?"
See examples/test-driven-refactor/ for a complete example.
Fixing a Broken Build
When CI is red and you have specific compiler/type errors:
# 1. Capture current errors
npx tsc --noEmit 2>&1 > .loop-logs/build-errors.txt
# 2. Plan tasks from the errors
copilot --agent=loop-planner --prompt \
"Fix the TypeScript build errors in .loop-logs/build-errors.txt"
# 3. Run the loop
bash .github/skills/loop-runner/run-loop.sh
See examples/build-fix/ for a complete example.
Large-Scale Cleanup
Removing deprecated APIs, updating import paths across hundreds of files:
# 1. Generate task list
copilot --agent=loop-planner --prompt \
"Replace all usage of deprecated api.v1.* with api.v2.* across the codebase"
# 2. Set high iteration limit
# Edit LOOP_CONFIG.md: max_iterations: 100
# 3. Run
bash .github/skills/loop-runner/run-loop.sh
Failure Modes & Detection
The loop can go wrong in specific, detectable ways. The convergence-detector and loop-reviewer watch for these:
1. Oscillation π
What: Fix A breaks B. Fix B re-breaks A. Infinite loop.
Detection: Same task toggling between [x] and [!] across iterations, or the same error message appearing 3+ times.
Resolution: Stop the loop, add explicit instructions or constraints to TASKS.md.
2. Stagnation π§
What: No tasks change status across multiple iterations.
Detection: No status changes for 3+ consecutive iterations.
Resolution: Review PROGRESS.md for what the agent is attempting. Simplify the current task or add more context.
3. Metric Gaming π°
What: Agent deletes tests, weakens assertions, adds @ts-ignore, or uses any types to make checks pass.
Detection: Git diff analysis for deleted test files, removed assert/expect calls, or added suppressions.
Resolution: The guardrails pre-commit hook blocks these automatically. If detected in review, revert and add explicit anti-gaming instructions.
4. Context Overflow π¦
What: PROGRESS.md grows so large that reading it consumes too much of the context window.
Detection: Progress file exceeds 500 lines.
Resolution: Compact PROGRESS.md β keep the last 5 iterations and a summary of earlier ones.
5. Hallucination Drift π«οΈ
What: Agent builds on false assumptions that become entrenched in state files.
Detection: Manual review reveals statements in PROGRESS.md that don't match reality.
Resolution: Stop the loop, correct the state files, add explicit constraints.
Best Practices
β DO
- Start with tests. The loop works best when success/failure is objectively measurable.
- Keep tasks small. Each task should touch 1-3 files maximum.
- Be specific in task descriptions. Write them as if for a developer who has never seen the codebase.
- Include validation commands. Every task should have a command that verifies success.
- Use the planner agent. Let it decompose objectives β it understands the task size constraints.
- Review
PROGRESS.mdperiodically. It's your window into what the agent is actually doing. - Install the pre-commit hook. It's your last line of defense against metric gaming.
β DON'T
- Don't use it for exploratory design. The pattern needs clear objectives.
- Don't skip validation commands. Without verification, the loop can't self-correct.
- Don't set iteration limits too high initially. Start with 10-15 and increase if needed.
- Don't mix unrelated objectives. One loop run = one coherent goal.
- Don't edit
PROGRESS.mdduring a run β it's append-only. - Don't use it for ambiguous requirements. "Make the code better" will not converge.
When to Use (And When Not To)
| Great Fit β | Poor Fit β |
|---|---|
| Test-driven refactoring | Exploratory prototyping |
| Fixing specific build errors | "Make it faster" (vague) |
| Large-scale code migration | Novel architecture design |
| API version upgrades | Greenfield development |
| Dependency injection retrofitting | UX/UI design decisions |
| Linter/formatter adoption | Requirements gathering |
Troubleshooting
The loop isn't making progress
- Check
PROGRESS.mdβ what is the agent attempting? - Run
bash .github/skills/convergence-detector/check-convergence.sh --mode stagnation - Simplify the current task in
TASKS.md - Add more explicit context or constraints
The loop is oscillating
- Run
bash .github/skills/convergence-detector/check-convergence.sh --mode oscillation - Look for the conflicting changes in
PROGRESS.md - Add a constraint to
TASKS.mdthat breaks the cycle - Consider splitting the task differently
The agent is gaming metrics
- Run
bash .github/skills/convergence-detector/check-convergence.sh --mode gaming - Check
git difffor deleted test files or weakened assertions - Revert the gaming changes
- Add explicit anti-gaming notes to the task description
- Ensure the pre-commit hook is installed
State files are too large
- Compact
PROGRESS.md: keep summary + last 5 iterations - Remove completed tasks from
TASKS.md(keep a summary count) - Run
bash .github/skills/task-state-manager/init-state.shto reset if starting fresh
Loop won't start
- Verify
TASKS.mdexists and has pending tasks ([ ]) - Check
LOOP_CONFIG.mdexists - Ensure scripts are executable:
chmod +x .github/skills/*//*.sh - Check for a stale
.loop-stopfile:rm -f .loop-stop
How It Works β Deep Dive
The Context Window Problem
Every LLM has a context window β the maximum amount of text it can process at once. As a conversation grows, the model's ability to use information from earlier in the context degrades:
Iteration 1: [System Prompt | Task State | Work] β clean, focused
Iteration 15: [System Prompt | Turn 1 | Turn 2 | ... | Turn 15 | Work] β degraded
By iteration 15 of a traditional session, the model has accumulated 14 turns of conversation history. It's spending most of its context "remembering" old work instead of focusing on the current task.
The Fresh Context Fix
The Ralph Wiggum Loop eliminates this entirely:
Every iteration: [System Prompt | Read TASKS.md | Read PROGRESS.md | Work] β always clean
The agent reads the same state files every time, but its context is always fresh. There's no accumulated conversation history weighing it down.
State Machine
START βββΆ READ_STATE βββΆ SELECT_TASK βββΆ EXECUTE βββΆ VALIDATE
β² β
β βββββ STOP (all done) βββββ YES βββββ β
β β β βΌ
βββββββββββββ΄ββββ WRITE_STATE ββββ CHECK_DONE βββ RECORD
β β²
ββββββββββββββββββββββββββββββββ
Why "Ralph Wiggum"?
The name comes from the Simpsons character Ralph Wiggum. In a famous scene, Ralph sits on a school bus as it drives into danger, cheerfully announcing "I'm in danger!" The AI agent, like Ralph, happily enters each iteration without awareness of what happened before β and that naivety is exactly what makes the pattern work. Each iteration is a fresh start, unburdened by accumulated context.
Adding to an Existing Project
The fastest way is rwl init:
cd /path/to/your/project
rwl init # interactive wizard
rwl plan # create tasks
rwl doctor # verify setup
Manual Setup β Minimal
The minimum you need is:
.github/agents/ralph-wiggum-loop.agent.mdβ the main agentTASKS.mdβ your task listPROGRESS.mdβ iteration log (can start empty)
Everything else (skills, hooks, templates, guardrails) enhances the pattern but isn't strictly required.
Manual Setup β Recommended
For production use, also add:
.github/agents/loop-reviewer.agent.mdβ health monitoring.github/skills/convergence-detector/β automated pathology detection.github/skills/loop-guardrails/β safety enforcementhooks/pre-commitβ blocks dangerous commitsLOOP_CONFIG.mdβ configuration
Manual Setup β Full
Copy the entire .github/agents/, .github/skills/, .github/instructions/ directories plus AGENTS.md and the hook scripts. Or just use rwl init with the "Full install" option.
Attribution
The Ralph Wiggum Loop pattern was created by Geoffrey Huntley. This implementation is inspired by:
- ghuntley.com/loop β Original pattern description and philosophy
- beuke.org/ralph-wiggum-loop β Comprehensive technical reference
- agentpatterns.ai β Fresh-Context Iteration Pattern
- dwmkerr.com β Real-world usage (451 files, 58K lines)
The canonical loop is beautifully simple:
while :; do cat PROMPT.md | claude-code; done
This project extends that simplicity into a full component system for GitHub Copilot CLI.
License
MIT License. See LICENSE for details.
The Ralph Wiggum Loop pattern itself is an open community pattern. This implementation is an independent adaptation for the GitHub Copilot CLI platform.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.7 | 97 | 4/28/2026 |