
Ralph Loop
- 2 installs
- 21 repo stars
- Updated August 5, 2026
- joaquimscosta/arkhe-claude-plugins
Runs an autonomous build-verify-commit loop that picks one task per iteration in a fresh context window and commits the result.
About
Executes an autonomous development loop where each iteration picks one task, implements it, verifies it, and commits, using a fresh context window and a builder/verifier split. A developer uses it to automate iterative task completion against a tracked task list.
- Fresh context window per iteration
- Hat-lite builder (~65%) / verifier (~35%) split
Ralph Loop by the numbers
- 2 all-time installs (skills.sh)
- Ranked #1,839 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/joaquimscosta/arkhe-claude-plugins --skill ralph-loopAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 21 |
| Last updated | August 5, 2026 |
| Repository | joaquimscosta/arkhe-claude-plugins ↗ |
What it does
Runs an autonomous build-verify-commit loop that picks one task per iteration in a fresh context window and commits the result.
Files
Ralph Loop Execution Protocol
Autonomous development with fresh context per iteration and Hat-lite builder/verifier workflow.
Quick Start
# From project directory (after /create-prd)
./ralph.sh 20 # Run up to 20 iterations
./ralph.sh 5 # Quick test with 5 iterationsHow It Works
Each iteration runs in a fresh context window:
┌─────────────────────────────────────────────────────┐
│ ITERATION (Fresh Context) │
├─────────────────────────────────────────────────────┤
│ 1. ORIENT: Read activity.log + tasks.json + memories│
│ 2. BUILD: Pick ONE task, implement, verify │
│ 3. VERIFY: Review, update status, commit │
│ 4. LEARN: (Optional) Save insights to memories │
│ 5. DECIDE: All done? → RALPH_COMPLETE │
└─────────────────────────────────────────────────────┘Hat-Lite System
| Role | When | Responsibility |
|---|---|---|
| Builder | ~65% of iteration | Implement ONE task |
| Verifier | ~35% of iteration | Review, update, commit |
Key Files
| File | Purpose |
|---|---|
.ralph/current-taskset/tasks.json | Task state (source of truth) |
.ralph/current-taskset/activity.log | Iteration history |
.ralph/current-taskset/memories.md | Persistent learnings |
.ralph/current-taskset | Symlink to active task set |
PROMPT.md | Instructions per iteration |
ralph.sh | Loop runner script |
Task JSON Format
Tasks are stored in .ralph/current-taskset/tasks.json:
{
"tasks": [
{
"id": "setup-001",
"description": "Initialize project",
"verificationTier": "build",
"passes": false,
"iteration_completed": null
}
]
}Valid verificationTier values: "build" (default), "visual", "api", "e2e". See WORKFLOW.md for details.
Completion Signal
When all tasks pass, output:
RALPH_COMPLETE: All tasks verifiedCommands
Subcommands: /ralph run [N], /ralph status, /ralph init, /ralph taskset <new|list|switch|delete>, /ralph add-task, /ralph remember, /ralph memories.
Workflow Details
See WORKFLOW.md for the 5-phase iteration lifecycle (Orient, Build, Verify, Learn, Decide) and Hat-Lite role definitions.
Examples
See EXAMPLES.md for web app, API, resumption, and mid-loop status checking scenarios.
Troubleshooting
See TROUBLESHOOTING.md for immediate exit, premature completion, infinite loop, and context issues.
Ralph Loop Examples
Example 1: Simple Web App
Setup
mkdir my-todo-app && cd my-todo-app
/create-prd
# Answer: "Build a simple todo app with React"Generated tasks.json
{
"project": "my-todo-app",
"created": "2026-02-01T10:00:00Z",
"tasks": [
{
"id": "setup-001",
"category": "setup",
"description": "Initialize React project with Vite",
"steps": [
"Run npm create vite@latest",
"Select React + TypeScript",
"Install dependencies",
"Verify dev server starts"
],
"passes": false,
"iteration_completed": null
},
{
"id": "feat-001",
"category": "feature",
"description": "Create Todo list component",
"steps": [
"Create TodoList component",
"Add state for todo items",
"Render list of todos"
],
"passes": false,
"iteration_completed": null
},
{
"id": "feat-002",
"category": "feature",
"description": "Add new todo functionality",
"steps": [
"Create AddTodo component",
"Add input field and submit button",
"Connect to TodoList state"
],
"passes": false,
"iteration_completed": null
},
{
"id": "feat-003",
"category": "feature",
"description": "Add complete/delete functionality",
"steps": [
"Add checkbox for completion",
"Add delete button",
"Style completed items"
],
"passes": false,
"iteration_completed": null
},
{
"id": "style-001",
"category": "styling",
"description": "Add CSS styling",
"steps": [
"Style the todo list",
"Add responsive layout",
"Ensure accessibility"
],
"passes": false,
"iteration_completed": null
}
]
}Running the Loop
./ralph.sh 10Activity Log After 3 Iterations
=== ITERATION 1 | 2026-02-01 10:15:00 ===
TASK: setup-001 - Initialize React project with Vite
ACTIONS:
- Ran: npm create vite@latest . -- --template react-ts
- Ran: npm install
- Verified: Dev server starts on localhost:5173
STATUS: PASS
COMMIT: a1b2c3d "feat: initialize React project with Vite and TypeScript"
---
=== ITERATION 2 | 2026-02-01 10:25:00 ===
TASK: feat-001 - Create Todo list component
ACTIONS:
- Created src/components/TodoList.tsx
- Added useState for todo items
- Implemented list rendering with map()
- Ran lint and typecheck - all pass
STATUS: PASS
COMMIT: e4f5g6h "feat: create TodoList component with state management"
---
=== ITERATION 3 | 2026-02-01 10:35:00 ===
TASK: feat-002 - Add new todo functionality
ACTIONS:
- Created src/components/AddTodo.tsx
- Added input field with controlled state
- Connected to parent via onAdd prop
- Ran lint and typecheck - all pass
STATUS: PASS
COMMIT: i7j8k9l "feat: add AddTodo component with form handling"
------
Example 2: API Development
Setup
mkdir my-api && cd my-api
/create-prd
# Answer: "Build a REST API for user management with Node.js and Express"Generated tasks.json
{
"project": "my-api",
"tasks": [
{
"id": "setup-001",
"category": "setup",
"description": "Initialize Node.js project",
"steps": ["npm init", "Install Express and TypeScript", "Configure tsconfig"],
"passes": false,
"iteration_completed": null
},
{
"id": "feat-001",
"category": "feature",
"description": "Create user CRUD endpoints",
"steps": ["GET /users", "GET /users/:id", "POST /users", "PUT /users/:id", "DELETE /users/:id"],
"passes": false,
"iteration_completed": null
},
{
"id": "feat-002",
"category": "feature",
"description": "Add request validation",
"steps": ["Install zod", "Create user schema", "Add validation middleware"],
"passes": false,
"iteration_completed": null
},
{
"id": "test-001",
"category": "testing",
"description": "Add API tests",
"steps": ["Install vitest and supertest", "Write endpoint tests", "Achieve >80% coverage"],
"passes": false,
"iteration_completed": null
}
]
}---
Example 3: Resuming After Interruption
If the loop is interrupted (Ctrl+C, error, etc.), simply run it again:
# Loop was interrupted at iteration 5
./ralph.sh 20Ralph reads the activity log and tasks.json to understand the current state and continues from where it left off.
---
Example 4: Running with Limited Iterations
For testing or when you want more control:
# Run only 3 iterations
./ralph.sh 3
# Check progress
cat .ralph/current-taskset/tasks.json | jq '.tasks[] | select(.passes == false)'
# Continue with more iterations
./ralph.sh 10---
Example 5: Checking Status Mid-Loop
While the loop is running (in another terminal):
# See current task state
cat .ralph/current-taskset/tasks.json | jq '.tasks[] | {id, passes}'
# See recent activity
tail -n 20 .ralph/current-taskset/activity.log
# Check screenshots
ls -la screenshots/#!/usr/bin/env bash
# Ralph Wiggum Autonomous Development Loop
# =========================================
# Runs Claude Code in a continuous loop, each iteration with a fresh
# context window. Reads PROMPT.md and feeds it to Claude until all tasks
# are complete or max iterations is reached.
#
# Usage: ./ralph.sh [max_iterations]
# Example: ./ralph.sh 20
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Configuration
MAX_ITERATIONS=${1:-20}
COMPLETION_SIGNAL="RALPH_COMPLETE:"
PROMPT_FILE="PROMPT.md"
TASKSET_LINK=".ralph/current-taskset"
TASKS_FILE=".ralph/current-taskset/tasks.json"
ACTIVITY_LOG=".ralph/current-taskset/activity.log"
# Print banner
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE} Ralph Wiggum Autonomous Loop ${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
# Verify required files exist
if [[ ! -f "$PROMPT_FILE" ]]; then
echo -e "${RED}Error: $PROMPT_FILE not found${NC}"
echo "Run /create-prd first to set up your project for Ralph."
exit 1
fi
if [[ ! -L "$TASKSET_LINK" ]]; then
echo -e "${RED}Error: No active task set${NC}"
echo "Run /ralph taskset list to see available task sets."
echo "Run /ralph taskset switch <name> to activate one."
echo "Or run /create-prd to create a new project."
exit 1
fi
if [[ ! -f "$TASKS_FILE" ]]; then
echo -e "${RED}Error: $TASKS_FILE not found${NC}"
echo "Current task set appears broken. Check .ralph/current-taskset symlink."
exit 1
fi
# Create screenshots directory if it doesn't exist
mkdir -p screenshots
# Get current taskset name from symlink
CURRENT_TASKSET=$(basename "$(readlink "$TASKSET_LINK")")
# Display configuration
echo -e "Task set: ${GREEN}$CURRENT_TASKSET${NC}"
echo -e "Max iterations: ${GREEN}$MAX_ITERATIONS${NC}"
echo -e "Completion signal: ${GREEN}$COMPLETION_SIGNAL${NC}"
echo -e "Prompt file: ${CYAN}$PROMPT_FILE${NC}"
echo -e "Tasks file: ${CYAN}$TASKS_FILE${NC}"
echo ""
echo -e "${YELLOW}Starting in 3 seconds... Press Ctrl+C to abort${NC}"
sleep 3
echo ""
# Main loop
for ((i=1; i<=MAX_ITERATIONS; i++)); do
echo -e "${BLUE}======================================${NC}"
echo -e "${BLUE} Iteration $i of $MAX_ITERATIONS${NC}"
echo -e "${BLUE} Task Set: $CURRENT_TASKSET${NC}"
echo -e "${BLUE}======================================${NC}"
echo ""
# Run Claude with fresh context (read prompt file each time)
# --dangerously-skip-permissions: required for non-interactive tool execution
# --disallowedTools: prevent use of session-scoped task tools (Ralph uses tasks.json)
result=$(claude -p "$(cat "$PROMPT_FILE")" \
--dangerously-skip-permissions \
--output-format text \
--disallowedTools=TodoWrite,TaskCreate,TaskUpdate,TaskList,TaskGet \
2>&1) || true
echo "$result"
echo ""
# Check for completion signal
if echo "$result" | grep -q "$COMPLETION_SIGNAL"; then
echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN} RALPH COMPLETE! ${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
echo -e "Task set '${GREEN}$CURRENT_TASKSET${NC}' finished after ${GREEN}$i${NC} iteration(s)"
echo ""
echo "Next steps:"
echo " 1. Review the completed work in your project"
echo " 2. Check .ralph/current-taskset/activity.log for the full build log"
echo " 3. Check .ralph/current-taskset/memories.md for learnings"
echo " 4. Review screenshots/ for visual verification"
echo " 5. Run your tests to verify everything works"
echo ""
echo "To work on another task set:"
echo " /ralph taskset new \"next-feature\""
echo ""
exit 0
fi
echo ""
echo -e "${YELLOW}--- End of iteration $i ---${NC}"
echo ""
# Small delay between iterations to prevent hammering
sleep 2
done
# Max iterations reached without completion
echo ""
echo -e "${RED}======================================${NC}"
echo -e "${RED} MAX ITERATIONS REACHED ${NC}"
echo -e "${RED}======================================${NC}"
echo ""
echo -e "Task set '${RED}$CURRENT_TASKSET${NC}' reached max iterations (${RED}$MAX_ITERATIONS${NC}) without completion."
echo ""
echo "Options:"
echo " 1. Run again with more iterations: ./ralph.sh 50"
echo " 2. Check .ralph/current-taskset/activity.log to see current progress"
echo " 3. Check .ralph/current-taskset/tasks.json to see remaining tasks"
echo " 4. Check .ralph/current-taskset/memories.md for any learnings"
echo " 5. Manually complete remaining tasks"
echo ""
exit 1
Ralph Loop Troubleshooting
Common Issues
Issue: Loop exits immediately without doing anything
Symptoms:
- Script exits with error code 1
- No iterations are executed
Causes & Solutions:
1. Missing PROMPT.md
# Check if file exists
ls -la PROMPT.md
# Solution: Run /create-prd first
/create-prd2. Missing .ralph/current-taskset symlink or tasks.json
# Check if symlink and file exist
ls -la .ralph/current-taskset
ls -la .ralph/current-taskset/tasks.json
# Solution: Run /create-prd first
/create-prd3. ralph.sh not executable
# Make executable
chmod +x ralph.sh---
Issue: Loop completes on first iteration
Symptoms:
- Outputs "RALPH_COMPLETE:" immediately
- No work was done
Cause: All tasks already have passes: true
Solution:
# Check task status
cat .ralph/current-taskset/tasks.json | jq '.tasks[] | {id, passes}'
# Reset tasks if needed
# Edit .ralph/current-taskset/tasks.json and set passes: false---
Issue: Loop never completes (hits max iterations)
Symptoms:
- Reaches max iterations without "RALPH_COMPLETE:"
- Same task keeps failing
Causes & Solutions:
1. Task too vague
- Edit
.ralph/current-taskset/tasks.json - Add more specific steps
- Break large task into smaller ones
2. Verification always fails
# Check what's failing
npm run lint
npm run typecheck
npm run test
# Fix underlying issues manually if needed3. Task impossible to complete
- Review the task requirements
- Consider if it's achievable
- Modify or remove problematic task
---
Issue: Tasks not being marked as complete
Symptoms:
- Work is done in each iteration
- But tasks stay
passes: false
Cause: Claude not updating tasks.json properly
Solution:
# Manually verify the task.json format is correct
cat .ralph/current-taskset/tasks.json | jq .
# Check activity log for errors
tail -n 50 .ralph/current-taskset/activity.log---
Issue: No commits being created
Symptoms:
- Work is done
- But git log shows no new commits
Causes & Solutions:
1. Not a git repository
git init
git add .
git commit -m "Initial commit"2. Git configuration issues
git config user.name "Your Name"
git config user.email "your@email.com"---
Issue: Context seems to carry over
Symptoms:
- Later iterations reference things from earlier iterations
- Behavior changes unpredictably
Cause: This shouldn't happen with the external bash loop.
Solution: 1. Verify you're using ralph.sh (not running Claude directly) 2. Check that PROMPT.md doesn't have accumulated content 3. Restart the loop fresh
---
Issue: Activity log getting corrupted
Symptoms:
- Malformed entries in activity.log
- JSON parse errors
Solution:
# Backup current log
cp .ralph/current-taskset/activity.log .ralph/current-taskset/activity.log.bak
# Clear and start fresh
echo "" > .ralph/current-taskset/activity.log---
Debugging Tips
Verbose Mode
Run a single iteration manually to see what's happening:
claude -p "$(cat PROMPT.md)" --output-format textCheck Task State
# Pretty print tasks
cat .ralph/current-taskset/tasks.json | jq '.'
# Show only incomplete tasks
cat .ralph/current-taskset/tasks.json | jq '.tasks[] | select(.passes == false)'
# Count complete vs incomplete
echo "Complete: $(cat .ralph/current-taskset/tasks.json | jq '[.tasks[] | select(.passes == true)] | length')"
echo "Incomplete: $(cat .ralph/current-taskset/tasks.json | jq '[.tasks[] | select(.passes == false)] | length')"Review Activity
# Last iteration only
tail -n 15 .ralph/current-taskset/activity.log
# Search for failures
grep -A 5 "STATUS: FAIL" .ralph/current-taskset/activity.log
# Search for specific task
grep -A 10 "TASK: feat-001" .ralph/current-taskset/activity.logGit History
# See commits made by Ralph
git log --oneline -10
# See changes in last commit
git show --stat HEAD---
Recovery Procedures
Reset a Single Task
# Edit tasks.json and set specific task to passes: false
# Then run the loop again
./ralph.sh 5Reset All Tasks
# Set all tasks back to incomplete
cat .ralph/current-taskset/tasks.json | jq '.tasks[].passes = false | .tasks[].iteration_completed = null' > /tmp/tasks.json
mv /tmp/tasks.json .ralph/current-taskset/tasks.jsonStart Fresh
# Remove all Ralph state
rm -rf .ralph/
rm -f PROMPT.md ralph.sh
# Run PRD creation again
/create-prd---
Getting Help
If you're still stuck:
1. Check the activity log for specific error messages 2. Run a single iteration manually to observe behavior 3. Review the PROMPT.md to ensure instructions are clear 4. Verify tasks.json has valid JSON format
Ralph Loop Workflow
Detailed step-by-step guide for each iteration in the Ralph autonomous loop.
Iteration Lifecycle
┌─────────────────────────────────────────────────────────────────┐
│ RALPH ITERATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PHASE 1: ORIENT (5% of iteration) │ │
│ │ │ │
│ │ 1. Read .ralph/current-taskset/activity.log (last 5) │ │
│ │ 2. Read .ralph/current-taskset/tasks.json │ │
│ │ 3. Read .ralph/current-taskset/memories.md │ │
│ │ 4. Identify next incomplete task │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PHASE 2: BUILD (60% of iteration) │ │
│ │ │ │
│ │ 1. Select ONE task where passes=false │ │
│ │ 2. Read task description and steps │ │
│ │ 3. Implement the change │ │
│ │ 4. Run verification: │ │
│ │ - npm run lint (if available) │ │
│ │ - npm run typecheck (if available) │ │
│ │ - npm run build (if available) │ │
│ │ - npm run test (if available) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PHASE 3: VERIFY (25% of iteration) │ │
│ │ │ │
│ │ 1. Review implementation against acceptance criteria │ │
│ │ 2. Tier-specific verification (per verificationTier) │ │
│ │ 3. Update task status in tasks.json │ │
│ │ 4. Append entry to activity.log │ │
│ │ 5. Stage and commit changes │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PHASE 4: LEARN (5% of iteration) - OPTIONAL │ │
│ │ │ │
│ │ If you learned something useful: │ │
│ │ Append insight to .ralph/current-taskset/memories.md │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PHASE 5: DECIDE (5% of iteration) │ │
│ │ │ │
│ │ Check: All tasks have passes=true? │ │
│ │ │ │
│ │ YES → Output "RALPH_COMPLETE: All tasks verified" │ │
│ │ NO → End iteration (fresh context on next loop) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘Hat-Lite Roles
Ralph uses a simplified "hat" system. You switch between two personas within a single iteration.
Builder Hat (~65% of iteration)
Role: Implementation Executor
Mindset:
- "I build things that work"
- "I follow the plan precisely"
- "I verify my own work immediately"
Responsibilities: 1. Pick ONE task from the task list 2. Implement according to the steps provided 3. Run verification commands (lint, typecheck, tests) 4. Document what was done
Does NOT:
- Question the task requirements
- Work on multiple tasks
- Skip verification steps
- Leave partial work
Verifier Hat (~35% of iteration)
Role: Quality Gate
Mindset:
- "I ensure the work meets standards"
- "I update state accurately"
- "I commit clean, atomic changes"
Responsibilities: 1. Review the Builder's implementation 2. Check against acceptance criteria 3. Update task status in tasks.json 4. Append entry to activity.log 5. Create git commit
Does NOT:
- Re-implement the solution
- Add features not in the task
- Mark incomplete work as done
- Skip the commit step
Hat Switching
The switch happens naturally within each iteration:
Builder Hat → implement task → run verification
↓
Verifier Hat → review work → update state → commitWhy Hat-Lite?
| Full Ralph | Hat-Lite |
|---|---|
| Separate Builder agent | Same agent, Builder mindset |
| Separate Verifier agent | Same agent, Verifier mindset |
| Separate Confessor agent | Not used |
| Complex event system | Simple phase progression |
Common Anti-Patterns
Builder:
- Working on multiple tasks → One task per iteration only
- Skipping verification → Always run lint, typecheck, tests
- Partial implementation → Complete the task fully or don't start it
Verifier:
- Re-implementing instead of reviewing → Review what was built, don't rebuild
- Marking incomplete work as done → Only mark pass when ALL criteria are met
- Skipping the commit → One commit per task, always
---
Phase 1: Orient
Goal: Quickly understand current state from previous iterations.
Steps
1. Read Activity Log
# Read last 5 entries
tail -n 50 .ralph/current-taskset/activity.log2. Read Task State
cat .ralph/current-taskset/tasks.json3. Read Memories
cat .ralph/current-taskset/memories.mdReview any patterns, decisions, or fixes from previous iterations.
4. Identify Next Task
- Find first task where
passes: false - Note any failed attempts from activity log
- Consider relevant memories
Output
- Clear understanding of what's been done
- Specific task to work on this iteration
- Awareness of project patterns from memories
---
Phase 2: Build (Builder Hat)
Goal: Complete ONE task fully.
Steps
1. Read Task Details
- Description
- Steps to complete
- Acceptance criteria
2. Implement
- Follow the steps exactly
- Write clean, documented code
- Follow project conventions (check memories)
3. Self-Verify
- Run linter:
npm run lintor equivalent - Run type checker:
npm run typecheckor equivalent - Run build:
npm run buildor equivalent - Run tests:
npm run testor equivalent
Rules
- ONE task only - Do not work on multiple tasks
- Complete fully - Don't leave partial work
- Fix verification issues - Don't proceed with failures
---
Phase 3: Verify (Verifier Hat)
Goal: Ensure quality before marking complete.
Steps
1. Review Implementation
- Does it meet all acceptance criteria?
- Is the code clean and documented?
- Did all verification commands pass?
2. Visual Verification (Per verificationTier)
# If verificationTier is "visual" or "e2e", use playwright-cli
playwright-cli open http://localhost:3000
playwright-cli screenshot screenshots/task-name.png
playwright-cli close3. Update Task Status
// In .ralph/current-taskset/tasks.json
{
"id": "feat-001",
"passes": true,
"iteration_completed": 3
}4. Log Activity Append to .ralph/current-taskset/activity.log:
=== ITERATION 3 | 2026-02-01 14:30:00 ===
TASK: feat-001 - Add user login form
ACTIONS:
- Created LoginForm component
- Added form validation
- Connected to auth API
- Ran lint, typecheck, tests - all pass
STATUS: PASS
COMMIT: abc1234 "feat: add user login form with validation"
---5. Commit Changes
git add .
git commit -m "feat: descriptive commit message"---
Phase 4: Learn (Optional)
Goal: Save useful insights for future iterations.
When to Save a Memory
- Discovered a project pattern that's not obvious
- Found a solution to a tricky problem
- Made an architectural decision
- Learned something about a library or tool
How to Save
Append to .ralph/current-taskset/memories.md:
## 2026-02-01: Tailwind requires explicit color config
When using custom colors in Tailwind, you must add them to tailwind.config.js.
Just using `text-[#123456]` doesn't work in this project because purging removes them.
Solution: Add colors to `theme.extend.colors` in the config.
---Examples of Good Memories
- "Next.js API routes require explicit return types"
- "The project uses barrel exports - add new components to index.ts"
- "Database migrations must be run manually with
npm run migrate" - "Auth tokens expire after 1 hour - refresh logic is in utils/auth.ts"
---
Phase 5: Decide
Goal: Determine if loop should continue or complete.
Decision Logic
IF all tasks have passes=true THEN
Output: "RALPH_COMPLETE: All tasks verified"
EXIT
ELSE
End iteration (loop continues with fresh context)
ENDIFCompletion Signal
The exact output must be:
RALPH_COMPLETE: All tasks verifiedThis is detected by ralph.sh to exit the loop successfully.
---
State Files
.ralph/current-taskset/tasks.json
{
"project": "my-app",
"taskset": "initial",
"created": "2026-02-01T10:00:00Z",
"tasks": [
{
"id": "setup-001",
"category": "setup",
"description": "Initialize Next.js project",
"steps": [
"Run create-next-app with TypeScript",
"Install dependencies",
"Verify dev server starts"
],
"verificationTier": "build",
"passes": true,
"iteration_completed": 1
},
{
"id": "feat-001",
"category": "feature",
"description": "Add user authentication",
"steps": [
"Create auth API endpoints",
"Add login form",
"Implement session management"
],
"verificationTier": "build",
"passes": false,
"iteration_completed": null
}
]
}.ralph/current-taskset/activity.log
=== ITERATION 1 | 2026-02-01 10:15:00 ===
TASK: setup-001 - Initialize Next.js project
ACTIONS:
- Ran: npx create-next-app@latest my-app --typescript
- Ran: npm install
- Verified: Dev server starts on localhost:3000
STATUS: PASS
COMMIT: abc1234 "feat: initialize Next.js project with TypeScript"
---
=== ITERATION 2 | 2026-02-01 10:25:00 ===
TASK: feat-001 - Add user authentication
ACTIONS:
- Created /api/auth/login endpoint
- Created /api/auth/logout endpoint
- Added JWT token handling
STATUS: IN_PROGRESS (continuing next iteration)
---.ralph/current-taskset/memories.md
# Memories: initial
> Persistent learnings that survive across iterations.
## Patterns
## 2026-02-01: Next.js requires explicit TypeScript config
When using create-next-app, the TypeScript config isn't fully set up.
Need to manually add strict mode and paths to tsconfig.json.
---
## Decisions
## 2026-02-01: Using JWT for auth instead of sessions
Chose JWT because this is a frontend-only app with API routes.
No need for session storage on the server side.
---
## Fixes
## 2026-02-01: Tailwind utilities conflict with custom CSS
Found that using @apply with custom utilities causes build issues.
Better to use Tailwind classes directly or use CSS-in-JS.
---
## Context---
Important Principles
One Task Per Iteration
- Prevents context exhaustion
- Ensures focused work
- Makes debugging easier
Fresh Context Per Iteration
- Each iteration starts clean
- No accumulated context bloat
- Prevents hallucination buildup
Memories for Continuity
- Learnings persist across iterations
- Future iterations can avoid past mistakes
- Project patterns are documented
Verification Before Completion
- Never mark pass without verification
- Run all available checks
- Visual verification for UI changes
Atomic Commits
- One commit per completed task
- Clear, descriptive messages
- Easy to review and revert
---
Verification Tiers Reference
Tiers are cumulative — each higher tier includes all checks from lower tiers.
build (default)
└── lint + typecheck + test + build
│
├── visual
│ └── + start dev server → playwright-cli snapshot/screenshot → stop server
│
├── api
│ └── + start server → curl endpoints → verify status/body → stop server
│
└── e2e
└── + start server → playwright-cli full user flow (interact + verify) → stop serverTier Details
| Tier | When to Use | Additional Checks |
|---|---|---|
build | Most tasks (logic, refactoring, setup) | Standard lint/typecheck/test/build only |
visual | UI changes, styling, layout | Open page in browser, capture screenshot, verify rendering |
api | API endpoints, server responses | curl endpoints, check status codes and response bodies |
e2e | User flows, multi-page interactions | Full browser interaction: navigate, click, fill forms, verify |
Dev Server Management Pattern
For visual, api, and e2e tiers, manage the dev server within the iteration:
# Start dev server in background
npm run dev &
DEV_PID=$!
# Wait for server to be ready
curl --retry 5 --retry-delay 2 --retry-connrefused http://localhost:3000 > /dev/null 2>&1
# ... run tier-specific verification ...
# Stop dev server
kill $DEV_PIDPlaywright CLI Reference
For visual and e2e tiers, use the playwright-cli skill for browser interaction. See plugins/playwright/skills/playwright-cli/SKILL.md for the full command reference.
Common patterns:
- Visual:
open→snapshot→screenshot→close - E2E:
open→snapshot→ interact (click, type, fill) → verify →close
See plugins/playwright/skills/playwright-cli/EXAMPLES.md for interaction patterns.
Fallback Behavior
If playwright-cli is not installed: 1. Fall back to build tier checks 2. Log a warning in activity.log: WARNING: playwright-cli not available, fell back to build tier 3. Do NOT mark the task as failed — build-tier checks are still valid
Missing verificationTier
If a task has no verificationTier field, treat it as "build". This ensures backward compatibility with existing tasks.json files.