| name | ralph |
| description | Set up Ralph for autonomous feature development. Use when starting a new feature that Ralph will implement. Triggers on: ralph, set up ralph, start ralph, new ralph feature, ralph setup. Chats through the feature idea, creates tasks with dependencies, and sets up everything for Ralph to run. |
Ralph Feature Setup
Interactive feature planning that creates ralph-ready tasks with dependencies.
The Job
Two modes:
Mode 1: New Feature
- Chat through the feature - Ask clarifying questions
- Break into small tasks - Each completable in one iteration
- Create task_list tasks - Parent + subtasks with
dependsOn - Set up ralph files - Save parent ID, reset progress.txt
Mode 2: Existing Tasks
- Find existing parent task - Search or let user specify
- Verify structure - Check subtasks have proper
dependsOn - Set up ralph files - Save parent ID to parent-task-id.txt
- Show status - Which tasks are ready, completed, blocked
Ask the user which mode they need:
Are you:
1. Starting a new feature (I'll help you plan and create tasks)
2. Using existing tasks (I'll set up Ralph to run them)
Step 1: Understand the Feature
Start by asking the user about their feature. Don't assume - ASK:
What feature are you building?
Then ask clarifying questions:
- What's the user-facing goal?
- What parts of the codebase will this touch? (database, UI, API, etc.)
- Are there any existing patterns to follow?
- What should it look like when done?
Keep asking until you have enough detail to break it into tasks.
Step 2: Break Into Tasks
Each task must be completable in ONE Ralph iteration (~one context window).
Ralph spawns a fresh Amp instance per iteration with no memory of previous work. If a task is too big, the LLM runs out of context before finishing.
Right-sized tasks:
- Add a database column + migration
- Create a single UI component
- Implement one server action
- Add a filter to an existing list
- Write tests for one module
Too big (split these):
- "Build the entire dashboard" → Split into: schema, queries, components, filters
- "Add authentication" → Split into: schema, middleware, login UI, session handling
- "Refactor the API" → Split into one task per endpoint
Rule of thumb: If you can't describe the change in 2-3 sentences, it's too big.
Step 3: Order by Dependencies
Tasks execute based on dependsOn. Earlier tasks must complete before dependent ones start.
Typical order:
- Schema/database changes (migrations)
- Server actions / backend logic
- UI components that use the backend
- Integration / E2E tests
Use dependsOn to express this:
Task 1: Schema (no dependencies)
Task 2: Server action (dependsOn: [task-1])
Task 3: UI component (dependsOn: [task-2])
Task 4: Tests (dependsOn: [task-3])
Parallel tasks that don't depend on each other can share the same dependency.
Step 4: Create Tasks
First, create the parent task:
task_list create
title: "[Feature Name]"
description: "[One-line description of the feature]"
repoURL: "https://github.com/snarktank/untangle"
Save the returned task ID - you'll need it for subtasks.
Then, create subtasks with parentID and dependsOn:
task_list create
title: "[Task title - action-oriented]"
description: "[Detailed description with:
- What to implement
- Files to create/modify
- Acceptance criteria
- How to verify (typecheck, tests, browser)]"
parentID: "<parent-task-id>"
dependsOn: ["<previous-task-id>"] // omit for first task
repoURL: "https://github.com/snarktank/untangle"
Task description format:
Write descriptions that a future Ralph iteration can pick up without context:
Implement category name to ID mapping for expenses.
**What to do:**
- Create function mapExpenseCategoryNameToId(name, isChildExpense)
- Query item_category table with category_type filter
- Add alias mapping for common synonyms (rent → Rent or Mortgage)
**Files:**
- workflows/tools/upsert-expense.ts
**Acceptance criteria:**
- Function returns category ID for valid names
- Returns null for unknown categories
- npm run typecheck passes
**Notes:**
- Follow pattern from upsert-income.ts
- EXPENSE type for family, CHILD_EXPENSE for child
Step 5: Set Up Ralph Files
After creating all tasks, run the shared setup steps from "Final Setup (Required for Both Modes)" section.
This ensures:
- Parent task ID is saved to
scripts/ralph/parent-task-id.txt - Previous progress.txt is archived if it has content
- Fresh progress.txt is created with Codebase Patterns preserved
Step 6: Confirm Setup
Show the user what was created:
✅ Ralph is ready!
**Parent task:** [title] (ID: [id])
**Subtasks:**
1. [Task 1 title] - no dependencies
2. [Task 2 title] - depends on #1
3. [Task 3 title] - depends on #2
...
**To run Ralph:**
```bash
./scripts/ralph/ralph.sh [max_iterations]
# or directly:
npx tsx scripts/ralph/ralph.ts [max_iterations]
To check status:
amp task list --parentID [parent-id] --limit 10
Mode 2: Setting Up Existing Tasks
If the user already has tasks created, help them set up Ralph to run them.
Find the parent task:
Ask the user:
What's the parent task? You can give me:
- The task ID directly
- A search term and I'll find it
- Or say "list recent" to see recent tasks
To search for tasks (always use limit to avoid context overflow):
task_list list
repoURL: "https://github.com/snarktank/untangle"
limit: 10
Verify subtasks exist:
Once you have the parent ID, check for subtasks (always use limit):
task_list list
parentID: "<parent-task-id>"
limit: 10
If no subtasks found, the parent task might BE the work (not a container). Ask:
This task has no subtasks. Is this:
1. A parent task with subtasks I should find differently?
2. The actual work task (I should create it as a parent with this as the first subtask)?
Check dependencies:
Review the subtasks and verify:
- Do they have
dependsOnset correctly? - Are there any circular dependencies?
- Is the first task(s) dependency-free so Ralph can start?
If dependencies are missing, offer to fix:
These tasks don't have dependencies set. Should I:
1. Add dependencies based on their order?
2. Leave them parallel (Ralph picks any ready task)?
Set up ralph files:
Run the shared setup steps from "Final Setup (Required for Both Modes)" section below.
Show status:
✅ Ralph is ready to use existing tasks!
**Parent task:** [title] (ID: [id])
**Status:**
- ✅ Completed: 3 tasks
- 🔄 Ready to work: 2 tasks
- ⏳ Blocked: 5 tasks (waiting on dependencies)
**Next task Ralph will pick:**
[Task title] - [brief description]
**To run Ralph:**
```bash
./scripts/ralph/ralph.sh [max_iterations]
# or directly:
npx tsx scripts/ralph/ralph.ts [max_iterations]
Final Setup (Required for Both Modes)
ALWAYS run these steps after creating tasks OR setting up existing tasks:
1. Save parent task ID:
echo "<parent-task-id>" > scripts/ralph/parent-task-id.txt
Verify it was saved:
cat scripts/ralph/parent-task-id.txt
2. Check if progress.txt needs archiving:
Read the current progress.txt:
cat scripts/ralph/progress.txt
Archive if:
- It has content beyond the header (learnings from a previous feature)
- The previous feature is different from the current one
Archive command:
DATE=$(date +%Y-%m-%d)
FEATURE="previous-feature-name-here"
mkdir -p scripts/ralph/archive/$DATE-$FEATURE
cp scripts/ralph/progress.txt scripts/ralph/archive/$DATE-$FEATURE/
echo "Archived to scripts/ralph/archive/$DATE-$FEATURE/"
3. Reset progress.txt:
Preserve useful Codebase Patterns from the previous run, then reset:
cat > scripts/ralph/progress.txt << 'EOF'
# Ralph Progress Log
Started: [current date]
## Codebase Patterns
[Copy any patterns from previous run that are still relevant]
---
EOF
4. Verify setup is complete:
# Confirm parent ID is saved
cat scripts/ralph/parent-task-id.txt
# Confirm progress.txt is reset
head -10 scripts/ralph/progress.txt
# List subtasks to confirm they exist
# (use task_list list with parentID)
Only after completing all 4 steps is Ralph ready to run.
Acceptance Criteria for Each Task
Each task description MUST include verifiable acceptance criteria:
Good criteria (verifiable):
- "Add
investorTypecolumn to investor table with default 'cold'" - "Filter dropdown has options: All, Cold, Friend"
- "npm run typecheck passes"
- "npm test -- path/to/test.ts passes"
Bad criteria (vague):
- ❌ "Works correctly"
- ❌ "Good UX"
- ❌ "Handles edge cases"
Always include:
npm run typecheck passes
For tasks with testable logic:
npm test passes
For UI/browser tasks:
For functional testing (checking behavior, not appearance):
Use Chrome DevTools MCP with take_snapshot to read page content (NOT screenshots)
take_snapshotreturns the a11y tree as text that Ralph can read and verifytake_screenshotreturns images which Ralph cannot interpret for functional checks- Only use screenshots when testing visual appearance/look and feel
For visual testing (checking appearance):
Use take_screenshot to capture and verify visual appearance
Example Conversation
User: set up ralph for adding expense tracking to the legal agent
Assistant: What feature are you building?
User: I want Grace (our legal chat agent) to be able to create, update, and delete expenses when users mention them in conversation.
Assistant: Got it - an expense upsert tool for the legal agent. A few questions:
- Are there existing tools in the legal agent I should follow as a pattern?
- Do expenses have different types (family vs child)?
- Should it also list expenses or just CRUD?
- Any task completion logic needed?
User: Follow upsert-income.ts. Yes family and child expenses (different tables). Yes list too. Mark APP_EXPENSES_ENTERED task complete.
Assistant: Perfect. Here's my proposed breakdown:
- Create tool skeleton - Zod schema, basic structure
- Category mapping - Map names like "rent" to category IDs
- Amount parsing - Handle currency formats, allow $0
- Duplicate detection - Check before creating
- Create family expenses - Insert into expense table
- Create child expenses - Insert into child_expense table
- Update action - Modify existing expenses
- Delete action - Remove expenses
- List action - Show all expenses with totals
- Task completion - Mark APP_EXPENSES_ENTERED done
- Register tool - Add to legal chat workflow
- UI progress indicator - Show progress during tool use
- Unit tests - Test helper functions
- E2E tests - Test via chat interface
Does this look right? Any tasks to add or remove?
User: Looks good, create the tasks
Assistant: [Creates parent task, then subtasks with dependencies, saves parent-task-id.txt]
✅ Ralph is ready!
Parent task: Legal Agent Expense Upsert Tool (ID: task-abc123)
Subtasks: 14 tasks created with dependencies
To run: ./scripts/ralph/ralph.sh 20
How Ralph Completes
When all subtasks are completed:
- Ralph marks the parent task as
completed - Ralph outputs
<promise>COMPLETE</promise> - The ralph.sh/ralph.ts loop detects this and exits
Important: Ralph uses limit: 5 when querying tasks to avoid context overflow. If you have many subtasks, they'll be processed over multiple iterations.
Checklist Before Creating Tasks
- Chatted through feature to understand scope
- Each task completable in one iteration (small enough)
- Tasks ordered by dependency (schema → backend → UI → tests)
- Every task has "npm run typecheck passes" in description
- UI tasks have browser verification in description
- Descriptions have enough detail for Ralph to implement without context
- Parent task ID saved to scripts/ralph/parent-task-id.txt
- Previous run archived if progress.txt had content