Ralph Loop with Guardrails

Production-ready Ralph implementation with circuit breakers, session continuity, rate limiting, and stuck-loop detection. For when you want autonomous but not reckless.

vvibecodoor
ยทJan 12, 2026ยท77 views
# Ralph Loop with Guardrails

The Ralph loop is powerful, but raw `while :; do ... ; done` can burn through your API budget or spin forever. This version adds safety rails.

## Enhanced Loop Script

```bash
#!/bin/bash
# ralph.sh - Ralph loop with guardrails

MAX_ITERATIONS=${MAX_ITERATIONS:-50}
ITERATION=0
LAST_HASH=""
STUCK_COUNT=0
MAX_STUCK=3

echo "๐Ÿ”„ Starting Ralph loop (max: $MAX_ITERATIONS iterations)"

while [ $ITERATION -lt $MAX_ITERATIONS ]; do
    ITERATION=$((ITERATION + 1))
    echo "โ”โ”โ” Iteration $ITERATION/$MAX_ITERATIONS โ”โ”โ”"

    # Run Claude
    OUTPUT=$(cat PROMPT.md | claude --continue 2>&1)
    echo "$OUTPUT"

    # Check for completion signal
    if echo "$OUTPUT" | grep -q "TASK_COMPLETE"; then
        echo "โœ… Task completed after $ITERATION iterations"
        exit 0
    fi

    # Circuit breaker: detect stuck loops
    CURRENT_HASH=$(git diff --stat | md5sum | cut -d' ' -f1)
    if [ "$CURRENT_HASH" = "$LAST_HASH" ]; then
        STUCK_COUNT=$((STUCK_COUNT + 1))
        echo "โš ๏ธ  No file changes detected ($STUCK_COUNT/$MAX_STUCK)"
        if [ $STUCK_COUNT -ge $MAX_STUCK ]; then
            echo "๐Ÿ›‘ Circuit breaker: $MAX_STUCK iterations without progress"
            exit 1
        fi
    else
        STUCK_COUNT=0
        LAST_HASH=$CURRENT_HASH
    fi

    # Rate limiting
    sleep 2
done

echo "๐Ÿ›‘ Max iterations reached without completion"
exit 1
```

## PROMPT.md Template

```markdown
# Task: [Your task here]

## Context
[What Claude needs to know]

## Requirements
- [ ] Requirement 1
- [ ] Requirement 2
- [ ] Requirement 3

## Validation Commands
Run these to verify your work:
- `npm test` - All tests must pass
- `npm run lint` - No lint errors
- `npm run build` - Build succeeds

## Completion Protocol
When ALL requirements are met AND all validation commands pass:
1. Commit your changes with a descriptive message
2. Output exactly: TASK_COMPLETE

## Session Continuity
- Check `git log -1` for your last commit
- Check `git status` for uncommitted work
- Continue from where you left off
```

## Safety Features

### 1. Circuit Breaker
Detects when Claude is stuck in a loop making no progress:
- Tracks file changes via git diff hash
- Stops after N iterations without changes
- Prevents infinite "I'll try again" loops

### 2. Max Iterations Cap
Hard limit on total iterations:
- Prevents runaway costs
- Default: 50 (adjust based on task complexity)
- Exit code 1 if limit reached

### 3. Rate Limiting
Simple sleep between iterations:
- Respects API rate limits
- Gives you time to Ctrl+C if needed
- Adjust based on your tier

### 4. Session Continuity
Using `--continue` flag:
- Preserves context across iterations
- Claude remembers what it tried
- More efficient than cold starts

### 5. Explicit Completion Signal
Requires `TASK_COMPLETE` output:
- No ambiguity about when to stop
- Claude must explicitly declare success
- Easy to grep/parse

## Advanced: Dual Exit Gate

For critical tasks, require BOTH:
1. Completion signal from Claude
2. Validation commands pass

```bash
if echo "$OUTPUT" | grep -q "TASK_COMPLETE"; then
    # Verify Claude's claim
    if npm test && npm run build; then
        echo "โœ… Verified complete"
        exit 0
    else
        echo "โš ๏ธ Claude claimed complete but validation failed"
        # Continue looping
    fi
fi
```

## Cost Awareness

Rough estimates per iteration:
- Simple task: ~$0.05-0.10
- Complex task with large codebase: ~$0.50-1.00
- 50 iterations worst case: $2.50-50.00

Set `MAX_ITERATIONS` accordingly. Start low, increase if needed.

## When Guardrails Save You

1. **3am runs** - Wake up to a finished task, not a $500 bill
2. **Flaky tests** - Circuit breaker catches "retry forever" loops
3. **Ambiguous tasks** - Max iterations forces you to refine the prompt
4. **API outages** - Rate limiting + retries handle transient failures

Comments

No comments yet

Be the first to share your thoughts!