Ralph PRD Converter
Converts existing PRDs to the prd.json format that Ralph uses for autonomous execution.
The Job
Take a PRD (markdown file or text) and convert it to scripts/ralph/prd.json.
Output Format
{
"project": "Resumate",
"branchName": "ralph/[feature-name-kebab-case]",
"description": "[Feature description from PRD title/intro]",
"userStories": [
{
"id": "US-001",
"title": "[Story title]",
"description": "As a [user], I want [feature] so that [benefit]",
"acceptanceCriteria": [
"Criterion 1",
"Criterion 2",
"npm run lint passes",
"npm run build passes"
],
"priority": 1,
"passes": false,
"notes": ""
}
]
}
Story Size: The Number One Rule
Each story must be completable in ONE Ralph iteration (one context window).
Ralph spawns a fresh Claude instance per iteration with no memory of previous work. If a story is too big, the LLM runs out of context before finishing and produces broken code.
Right-sized stories:
- •Add a database column and migration
- •Add a UI component to an existing page
- •Update a server action with new logic
- •Add a filter dropdown to a list
Too big (split these):
- •"Build the entire dashboard" - Split into: schema, queries, UI components, filters
- •"Add authentication" - Split into: schema, middleware, login UI, session handling
- •"Refactor the API" - Split into one story per endpoint or pattern
Rule of thumb: If you cannot describe the change in 2-3 sentences, it is too big.
Story Ordering: Dependencies First
Stories execute in priority order. Earlier stories must not depend on later ones.
Correct order:
- •Schema/database changes (migrations)
- •Server actions / backend logic
- •UI components that use the backend
- •Dashboard/summary views that aggregate data
Wrong order:
- •UI component (depends on schema that does not exist yet)
- •Schema change
Acceptance Criteria: Must Be Verifiable
Each criterion must be something Ralph can CHECK, not something vague.
Good criteria (verifiable):
- •"Add
statuscolumn to tasks table with default 'pending'" - •"Filter dropdown has options: All, Active, Completed"
- •"Clicking delete shows confirmation dialog"
- •"npm run lint passes"
- •"npm run build passes"
Bad criteria (vague):
- •"Works correctly"
- •"User can do X easily"
- •"Good UX"
- •"Handles edge cases"
Always include as final criteria:
"npm run lint passes" "npm run build passes"
For stories that change UI, also include:
"Verify in browser manually"
Conversion Rules
- •Each user story becomes one JSON entry
- •IDs: Sequential (US-001, US-002, etc.)
- •Priority: Based on dependency order, then document order
- •All stories:
passes: falseand emptynotes - •branchName: Derive from feature name, kebab-case, prefixed with
ralph/ - •Always add: "npm run lint passes" and "npm run build passes" to every story's acceptance criteria
Splitting Large PRDs
If a PRD has big features, split them:
Original:
"Add user notification system"
Split into:
- •US-001: Add notifications table to database
- •US-002: Create notification service for sending notifications
- •US-003: Add notification bell icon to header
- •US-004: Create notification dropdown panel
- •US-005: Add mark-as-read functionality
- •US-006: Add notification preferences page
Each is one focused change that can be completed and verified independently.
Archiving Previous Runs
Before writing a new prd.json, check if there is an existing one from a different feature:
- •Read the current
scripts/ralph/prd.jsonif it exists - •Check if
branchNamediffers from the new feature's branch name - •If different AND
scripts/ralph/progress.txthas content beyond the header:- •Create archive folder:
scripts/ralph/archive/YYYY-MM-DD-feature-name/ - •Copy current
prd.jsonandprogress.txtto archive - •Reset
progress.txtwith fresh header
- •Create archive folder:
The ralph.sh script handles this automatically when you run it, but if you are manually updating prd.json between runs, archive first.
Checklist Before Saving
Before writing prd.json, verify:
- • Previous run archived (if prd.json exists with different branchName, archive it first)
- • Each story is completable in one iteration (small enough)
- • Stories are ordered by dependency (schema to backend to UI)
- • Every story has "npm run lint passes" and "npm run build passes" as criteria
- • UI stories have "Verify in browser manually" as criterion
- • Acceptance criteria are verifiable (not vague)
- • No story depends on a later story