rwl 0.1.7

dotnet tool install --global rwl --version 0.1.7
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local rwl --version 0.1.7
                    
This package contains a .NET tool you can call from the shell/command line.
#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

Pattern Platform License

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

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:

  1. Starts the agent with a fresh context
  2. Reads task state from persistent files (TASKS.md, PROGRESS.md)
  3. Executes exactly ONE bounded task
  4. Writes results back to disk
  5. 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:

  1. Create a CopilotClient (CopilotService) β€” registers custom tools and hooks once at startup
  2. Open a fresh CopilotSession per iteration β€” implements the core Ralph Wiggum Loop pattern; fresh context every time, no leakage between iterations
  3. Inject the loop protocol as a system message β€” uses SystemMessageMode.Append so the agent knows it must complete exactly one task and update state files
  4. Stream output in real time β€” AssistantMessageDeltaEvent events 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 AllowedPaths from LOOP_CONFIG.md are 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:

  1. SDK mode (default) β€” CopilotService.RunIterationAsync() if SDK initializes successfully
  2. Process fallback β€” spawns copilot --agent=ralph-wiggum-loop or equivalent if SDK is unavailable
  3. Script fallback β€” runs run-loop.sh if 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

# 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 copilot command 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, rwl uses embedded resources for templates β€” no RWL_HOME needed. If building from source, set RWL_HOME to the repo root so rwl can 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: true in 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:

  1. Reads TASKS.md, PROGRESS.md, LOOP_CONFIG.md
  2. Identifies the next pending or failed task
  3. Executes exactly ONE task
  4. Validates using the configured commands
  5. 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.md periodically. 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.md during 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

  1. Check PROGRESS.md β€” what is the agent attempting?
  2. Run bash .github/skills/convergence-detector/check-convergence.sh --mode stagnation
  3. Simplify the current task in TASKS.md
  4. Add more explicit context or constraints

The loop is oscillating

  1. Run bash .github/skills/convergence-detector/check-convergence.sh --mode oscillation
  2. Look for the conflicting changes in PROGRESS.md
  3. Add a constraint to TASKS.md that breaks the cycle
  4. Consider splitting the task differently

The agent is gaming metrics

  1. Run bash .github/skills/convergence-detector/check-convergence.sh --mode gaming
  2. Check git diff for deleted test files or weakened assertions
  3. Revert the gaming changes
  4. Add explicit anti-gaming notes to the task description
  5. Ensure the pre-commit hook is installed

State files are too large

  1. Compact PROGRESS.md: keep summary + last 5 iterations
  2. Remove completed tasks from TASKS.md (keep a summary count)
  3. Run bash .github/skills/task-state-manager/init-state.sh to reset if starting fresh

Loop won't start

  1. Verify TASKS.md exists and has pending tasks ([ ])
  2. Check LOOP_CONFIG.md exists
  3. Ensure scripts are executable: chmod +x .github/skills/*//*.sh
  4. Check for a stale .loop-stop file: 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:

  1. .github/agents/ralph-wiggum-loop.agent.md β€” the main agent
  2. TASKS.md β€” your task list
  3. PROGRESS.md β€” iteration log (can start empty)

Everything else (skills, hooks, templates, guardrails) enhances the pattern but isn't strictly required.

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 enforcement
  • hooks/pre-commit β€” blocks dangerous commits
  • LOOP_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:

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.1.7 97 4/28/2026