Create and manage user stories in proper narrative format for Ralph Loop
Create, manage, and track user stories in proper narrative format. Stories feed into Ralph Loop for autonomous implementation.
The /story skill provides an interactive workflow for creating well-structured user stories that follow the proven "As a / I want / So that" narrative format. Stories are:
/story new
You'll be prompted for:
/story show # List all stories with status
/story view STORY-001 # Show full details for one story
/story list --priority 1 # Filter by priority
/story list --status in_progress # Filter by status
/story list --files src/auth.ts # Find stories touching a file
/story update STORY-001
Interactively change: status, priority, acceptance criteria
/story export > stories.md
Generate markdown summary grouped by priority and status.
When you run /story new, you choose your approach:
Traditional narrative format - fast for simple stories.
Ryan's methodology - comprehensive planning for complex work.
Choose Structured when:
Why Structured prevents spiraling:
Stories follow the user story narrative:
As a [user role]
I want to [desired action]
So that [business value]
Why this format?
Example story:
As a developer in a Ralph loop
I want to see my task context in a collapsible JSON card
So that I can quickly reference my context without switching windows
Acceptance Criteria:
- Card displays TIER 0 project context
- Card shows top 5 relevant golden rules for current domain
- JSON is syntax-highlighted (keys, values, strings colored differently)
- Card has 'Collapse all' button to minimize nested objects
- Card loads in <500ms
- Works offline (no external CDN dependencies)
pending (waiting for work)
↓
in_progress (Ralph Loop assigned it)
↓
done ✓ (Ralph completed + tests passed)
OR blocked ✗ (Ralph encountered an issue)
Automatic transitions:
in_progress when starting workdone if implementation + tests succeedblocked if tests fail or error occurs/story update as needed/story newCreate a new story interactively.
First, you choose your path: [Q] Quick (default) or [S] Structured
[Q/S, default=Q][S][Y/n, default=Y]Output (Quick Path):
✓ Created story: [STORY-001] Your Story Title
Output (Structured Path):
✓ Created story: [STORY-006] Your Story Title
Linked subtasks: 4
/story showList all stories with visual status and brief info.
Output:
STORIES (5 total, 2 complete)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ ] [P1] STORY-001: User Authentication
Status: pending | Files: 2
[~] [P2] STORY-002: Dashboard UI
Status: in_progress | Files: 4
[X] [P1] STORY-003: Database Migration
Status: done | Files: 3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Status icons: [ ] pending, [~] in_progress, [X] done, [!] blocked
/story view STORY-001Show complete details for a single story.
Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STORY-001: User Authentication
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Description:
As a developer, I want to implement JWT-based authentication,
so that users can login securely.
Priority: 1 (High)
Status: pending
Acceptance Criteria:
- Users can login with email/password
- JWT tokens are issued on successful auth
- Protected routes require valid token
- Token expiration is enforced
Files:
- src/auth/login.ts
- src/auth/middleware.ts
- tests/auth.test.ts
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/story update STORY-001Interactively modify a story's status, priority, or criteria.
Prompts:
Output:
✓ Updated story STORY-001
/story list [OPTIONS]Filter and display stories matching criteria.
Options:
--priority 1|2|3 # Filter by priority
--status pending|in_progress|done|blocked # Filter by status
--files src/path/file.ts # Find stories touching specific file
Examples:
/story list --priority 1 # All high-priority stories
/story list --status in_progress # What Ralph is currently working on
/story list --files src/components/Card.tsx # Stories affecting Card component
/story exportGenerate markdown summary of all stories.
Output: Markdown file with:
Redirect to file:
/story export > stories.md
1. /story new → Create story in narrative format
2. /prd validate → Verify format (warns on issues)
3. /loop start → Ralph picks next story from prd.json
4. Ralph implements → Writes code
5. Code review step → Catches issues
6. Simplify code → Cleans up
7. Run tests → Validates correctness
8. If pass:
- Commit to git
- Set "passes": true in prd.json
- Log learnings to progress.txt
- Pick next story → back to step 3
9. If fail:
- Set status to "blocked"
- Log failure analysis
- Human review required
Stories start as pending → Ralph changes to in_progress → ends as done (✓ tests passed) or blocked (✗ failed)
You can manually update status with /story update if needed.
When a story has subtasks (created with structured path):
Why this prevents spiraling:
Example flow:
STORY-007: Search Context Card
├─ TASK-001: Create feature branch [DONE]
├─ TASK-002: Search is case-insensitive [DONE]
├─ TASK-003: Highlights matching [DONE]
├─ TASK-004: Returns count [IN_PROGRESS]
└─ TASK-005: Filters nested objects [PENDING]
Ralph is working on TASK-004. When done, moves to TASK-005. Once all complete, STORY-007 marked done.
Stories are validated for:
✅ Required fields:
⚠️ Warnings (don't block):
Validate stories:
/prd validate # Validates all stories (including format checks)
✅ "As a developer debugging a failed loop" ❌ "As a user"
✅ "I want to see the exact JSON state that triggered the failure" ❌ "I want to see something"
✅ "So that I can understand what went wrong without digging through logs" ❌ "So that I have a feature"
✅ "Card displays TIER 0 project context" ✅ "JSON is syntax-highlighted" ❌ "Card is nice" ❌ "UI is better"
/story vs /prd| Aspect | /story |
/prd |
|---|---|---|
| Input | Interactive prompts | Manual JSON editing |
| Format | Guided narrative | Free-form |
| Validation | Enforced | Optional |
| ID Prefix | STORY-XXX (user stories) | TASK-XXX (technical tasks) |
| Use case | Feature work | Project setup/management |
| Best for | Ralph Loop automation | Overall PRD management |
When to use /story:
When to use /prd:
Both tools read/write the same prd.json - they're complementary!
/story show lists it/prd validate shows no errorsprd.json was updated: tail prd.json/prd validateSTORY- or TASK-progress.txt for errors/story show/story update STORY-001 (interactive mode)/prd - Full PRD management and validation/loop - Start Ralph Loop for autonomous executionprd.json - Raw data file (view with /story show)progress.txt - Learnings and execution logprompt.md - Ralph's work order (generated per iteration)$ /story new
Story ID [STORY-006]:
Path [Q/S, default=Q]: Q
User role (As a): developer in a React project
Desired action (I want to): implement a collapsible JSON card component
Business value (So that): display context at a glance without opening other windows
Title [Implement Collapsible JSON Card]:
Priority [1=high, 2=normal, 3=low, default=2]: 1
Files (comma-separated, optional): src/components/ContextCard.tsx, src/hooks/useContext.ts, tests/ContextCard.test.tsx
Add acceptance criteria (blank line to finish, need at least 1):
- Component accepts JSON data as prop
- Sections collapse/expand on click
- JSON is syntax-highlighted
- Works with deeply nested objects
- Component is <500ms to render
- No external dependencies
(blank to finish)
✓ Created story: [STORY-006] Implement Collapsible JSON Card
$ /story new
Story ID [STORY-007]:
Path [Q/S, default=Q]: S
=== Problem Statement ===
What problem does this solve? Users can't easily search through large heuristics in the context card
Create narrative: 'As a X, I want Y, so that Z'
User role (As a): developer in Ralph loop with large knowledge base
Desired action (I want to): search the context card by domain or keyword
Business value (So that): I can find relevant heuristics without manual scrolling
Title [Search Context Card By Domain Or Keyword]:
Priority [1=high, 2=normal, 3=low, default=2]: 1
=== Functional Requirements ===
List what the system must do (blank to finish):
Requirement: Search is case-insensitive
Requirement: Highlights matching keys and values
Requirement: Returns count of matches
Requirement: Filters work with nested objects
Requirement: Search input is sticky while scrolling
Requirement: (blank to finish)
=== Constraints & Non-Goals ===
What should this NOT do? Any limits? (blank to finish):
Constraint: Don't add external search libraries (keep it lightweight)
Constraint: Don't modify the JSON structure for search purposes
Constraint: (blank to finish)
=== Success Metrics ===
How do we measure success? (blank to finish, at least 1):
Metric: Search returns results in <100ms
Metric: All criteria work with 1000+ item datasets
Metric: Works offline without external dependencies
Metric: (blank to finish)
Files (comma-separated, optional): src/components/ContextCard.tsx, src/components/SearchFilter.tsx
Add acceptance criteria (blank line to finish, need at least 1):
- Search box accepts text input
- Results highlight in card
- Count displayed: "X matches found"
- Escape key clears search
- (blank to finish)
Generate subtasks to prevent Ralph spiraling? [Y/n]: Y
=== Generating Subtasks ===
- [TASK-001] Create feature branch
- [TASK-002] Search is case-insensitive
- [TASK-003] Highlights matching keys and values
- [TASK-004] Returns count of matches
- [TASK-005] Filters work with nested objects
- [TASK-006] Search input is sticky while scrolling
✓ Generated 5 subtasks (plus feature branch)
✓ Created story: [STORY-007] Search Context Card By Domain Or Keyword
Linked subtasks: 6
$ /story list --priority 1 --status pending
[STORY-001] User Authentication
[STORY-005] Dashboard KPI Display
[STORY-009] Error Handling Framework
→ Ralph will process these in order
$ /story show
$ /prd validate # Ensure all stories are valid
$ /loop # Start Ralph Loop
To improve the /story skill:
/story list/prd validate)