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 prd.json in your project root.
Output Format
{ "project": "[Project Name]", "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", "Typecheck 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 Antigravity chat per iteration (or batch) with no memory of previous work. If a story is too big, the agent 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 status column to tasks table with default 'pending'"
-
"Filter dropdown has options: All, Active, Completed"
-
"Clicking delete shows confirmation dialog"
-
"Typecheck passes"
-
"Tests pass"
Bad criteria (vague):
-
"Works correctly"
-
"User can do X easily"
-
"Good UX"
-
"Handles edge cases"
Always include as final criterion:
"Typecheck passes"
For stories with testable logic, also include:
"Tests pass"
For stories that change UI, also include:
"Verify in browser"
Frontend stories are NOT complete until visually verified.
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: false and empty notes
-
branchName: Derive from feature name, kebab-case, prefixed with ralph/
-
Always add: "Typecheck 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.
Example
Input PRD:
Task Status Feature
Add ability to mark tasks with different statuses.
Requirements
- Toggle between pending/in-progress/done on task list
- Filter list by status
- Show status badge on each task
- Persist status in database
Output prd.json:
{ "project": "TaskApp", "branchName": "ralph/task-status", "description": "Task Status Feature - Track task progress with status indicators", "userStories": [ { "id": "US-001", "title": "Add status field to tasks table", "description": "As a developer, I need to store task status in the database.", "acceptanceCriteria": [ "Add status column: 'pending' | 'in_progress' | 'done' (default 'pending')", "Generate and run migration successfully", "Typecheck passes" ], "priority": 1, "passes": false, "notes": "" }, { "id": "US-002", "title": "Display status badge on task cards", "description": "As a user, I want to see task status at a glance.", "acceptanceCriteria": [ "Each task card shows colored status badge", "Badge colors: gray=pending, blue=in_progress, green=done", "Typecheck passes", "Verify in browser" ], "priority": 2, "passes": false, "notes": "" }, { "id": "US-003", "title": "Add status toggle to task list rows", "description": "As a user, I want to change task status directly from the list.", "acceptanceCriteria": [ "Each row has status dropdown or toggle", "Changing status saves immediately", "UI updates without page refresh", "Typecheck passes", "Verify in browser" ], "priority": 3, "passes": false, "notes": "" }, { "id": "US-004", "title": "Filter tasks by status", "description": "As a user, I want to filter the list to see only certain statuses.", "acceptanceCriteria": [ "Filter dropdown: All | Pending | In Progress | Done", "Filter persists in URL params", "Typecheck passes", "Verify in browser" ], "priority": 4, "passes": false, "notes": "" } ] }
Archiving Previous Runs
Before writing a new prd.json, check if there is an existing one from a different feature:
-
Read the current prd.json if it exists
-
Check if branchName differs from the new feature's branch name
-
If different AND progress.txt has content beyond the header:
-
Create archive folder: archive/YYYY-MM-DD-feature-name/
-
Copy current prd.json and progress.txt to archive
-
Reset progress.txt with fresh header
Note: This archiving happens automatically in jpralph-iterate and jpralph-auto skills, 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 → backend → UI)
-
Every story has "Typecheck passes" as criterion
-
UI stories have "Verify in browser" as criterion
-
Acceptance criteria are verifiable (not vague)
-
No story depends on a later story