ralph-claude-code/docs/user-guide/03-writing-requirements.md
Test User dff2d358f6 docs: add user guide and example projects (#139)
New users were confused about which files they write vs. which Ralph
manages, and how PROMPT.md, specs/, and fix_plan.md relate to each other.

Added:
- docs/user-guide/ with quick start tutorial, file reference, and
  requirements writing guide
- examples/simple-cli-tool/ showing minimal Ralph configuration
- examples/rest-api/ demonstrating when to use specs/
- README section explaining Ralph files and their relationships

Also documents specs/stdlib/ purpose for reusable patterns.
2026-01-29 13:51:10 -07:00

323 lines
7.7 KiB
Markdown

# Writing Effective Requirements
Ralph works best when it understands what you want. This guide shows you how to write clear requirements in PROMPT.md, when to use specs/, and how fix_plan.md evolves during development.
## PROMPT.md: Good vs Bad Examples
### Bad Example
```markdown
# Project
Make a good API for managing stuff. Use best practices.
Should be fast and work well.
```
**Problems**:
- What "stuff"? Too vague.
- What are "best practices"? Claude will guess.
- "Fast" and "work well" aren't measurable.
### Good Example
```markdown
# Ralph Development Instructions
## Context
You are Ralph, building a REST API for a pet adoption shelter.
The API manages animals, adopters, and adoption records.
## Technology Stack
- Python 3.11+ with FastAPI
- PostgreSQL with SQLAlchemy (async)
- pytest for testing
- Pydantic for validation
## Key Principles
- RESTful endpoints following standard conventions
- All endpoints require authentication except GET /animals
- Soft delete for all entities (is_deleted flag, not actual deletion)
- Pagination on all list endpoints (default 20, max 100)
## Data Entities
- Animal: name, species, breed, age, status (available/adopted/pending)
- Adopter: name, email, phone, approved (boolean)
- Adoption: animal_id, adopter_id, date, status
## Quality Standards
- Every endpoint needs at least one happy-path test
- Input validation with clear error messages
- OpenAPI documentation for all endpoints
```
**Why this works**:
- Clear domain (pet adoption shelter)
- Specific technology choices
- Measurable constraints (pagination limits)
- Concrete data model
- Defined quality bar
## fix_plan.md: Task Writing
### The Goldilocks Principle
Tasks should be **not too big, not too small**.
**Too big** (Ralph doesn't know where to start):
```markdown
- [ ] Build the entire authentication system
```
**Too small** (wastes loop iterations):
```markdown
- [ ] Create the auth folder
- [ ] Create the auth/__init__.py file
- [ ] Create the auth/routes.py file
```
**Just right** (one loop of meaningful work):
```markdown
- [ ] Create auth routes with POST /login and POST /logout endpoints
- [ ] Add JWT token generation and validation middleware
- [ ] Create refresh token endpoint POST /auth/refresh
```
### Task Structure Template
```markdown
# Fix Plan - [Project Name]
## Priority 1: [Foundation/Critical Path]
- [ ] [Specific, actionable task]
- [ ] [Another specific task]
## Priority 2: [Core Features]
- [ ] [Feature task]
- [ ] [Feature task]
## Priority 3: [Polish/Nice-to-have]
- [ ] [Enhancement]
- [ ] [Documentation]
## Discovered
<!-- Ralph adds tasks it discovers here -->
```
### How fix_plan.md Evolves
**Initial state** (you write this):
```markdown
## Priority 1: Database
- [ ] Set up database models for Animal, Adopter, Adoption
## Priority 2: API
- [ ] Create CRUD endpoints for animals
```
**After Loop 1** (Ralph updates):
```markdown
## Priority 1: Database
- [x] Set up database models for Animal, Adopter, Adoption
## Priority 2: API
- [ ] Create CRUD endpoints for animals
## Discovered
- [ ] Add database migration with Alembic
- [ ] Create pytest fixtures for test database
```
**After Loop 3**:
```markdown
## Priority 1: Database
- [x] Set up database models for Animal, Adopter, Adoption
## Priority 2: API
- [x] Create CRUD endpoints for animals
- [ ] Create CRUD endpoints for adopters
## Discovered
- [x] Add database migration with Alembic
- [x] Create pytest fixtures for test database
- [ ] Add pagination to GET /animals endpoint
```
Ralph adds tasks it discovers and checks them off as it works. You can:
- Reorder tasks by moving them to different priority sections
- Delete tasks that are no longer relevant
- Add new tasks anytime
## When to Use specs/
### Use specs/ for complex features
**PROMPT.md says**:
```markdown
Add a matching algorithm that suggests animals to adopters.
```
**This is too vague.** Create `.ralph/specs/matching-algorithm.md`:
```markdown
# Animal Matching Algorithm
## Inputs
- Adopter preferences: species, max_age, size_preference
- Available animals list
## Algorithm
1. Filter by species (required match)
2. Score by age preference (0-100 points)
- Within range: 100 points
- Within 2 years: 50 points
- Outside: 0 points
3. Score by size preference (0-50 points)
4. Return top 5 by total score
## Output Format
```json
[
{"animal_id": 1, "score": 145, "reasons": ["species match", "age within preference"]},
{"animal_id": 3, "score": 120, "reasons": ["species match"]}
]
```
## Edge Cases
- No matches: return empty array
- Tie scores: sort by animal.created_at (oldest first)
```
**Then in fix_plan.md**:
```markdown
- [ ] Implement matching algorithm per specs/matching-algorithm.md
```
### Use specs/stdlib/ for conventions
When you want consistency across the project, document it:
`.ralph/specs/stdlib/error-responses.md`:
```markdown
# Error Response Standard
All API errors return this structure:
```json
{
"error": {
"code": "ANIMAL_NOT_FOUND",
"message": "No animal with ID 42 exists",
"field": null,
"details": {}
}
}
```
## Error Codes
| Code | HTTP Status | When |
|------|-------------|------|
| VALIDATION_ERROR | 400 | Invalid input |
| NOT_FOUND | 404 | Resource doesn't exist |
| ALREADY_ADOPTED | 409 | Animal not available |
| UNAUTHORIZED | 401 | Missing/invalid token |
```
### Don't use specs/ for everything
**Overkill** - You don't need specs/ for:
```markdown
# User Password Requirements
Passwords must be at least 8 characters.
```
**Just put it in PROMPT.md**:
```markdown
## Authentication
- Passwords: minimum 8 characters, at least one number
- JWT tokens expire after 1 hour
```
## Common Mistakes
### Mistake 1: Assuming Claude knows your preferences
**Bad**:
```markdown
Use standard authentication.
```
**Good**:
```markdown
Use JWT authentication with 1-hour token expiry.
Refresh tokens last 7 days and rotate on use.
```
### Mistake 2: Mixing implementation with requirements
**Bad** (in PROMPT.md):
```markdown
Create a file called auth.py and add these imports:
import jwt
from datetime import datetime
```
**Good** (in PROMPT.md):
```markdown
Use JWT for authentication. Tokens should expire after 1 hour.
```
Let Ralph figure out the implementation details.
### Mistake 3: Over-specifying tests
**Bad**:
```markdown
- [ ] Write test_create_animal_success
- [ ] Write test_create_animal_invalid_species
- [ ] Write test_create_animal_missing_name
- [ ] Write test_create_animal_negative_age
```
**Good**:
```markdown
- [ ] Write tests for animal creation (success and validation errors)
```
Ralph knows how to write tests. Tell it what to test, not how.
### Mistake 4: Forgetting the "why"
**Bad**:
```markdown
Add a 100ms delay to all API responses.
```
**Good**:
```markdown
Add a 100ms delay to all API responses (required for rate limiting compliance with external payment API).
```
When Ralph understands *why*, it makes better decisions.
## Checklist: Before Running Ralph
Before `ralph --monitor`, verify:
- [ ] **PROMPT.md has clear context** - Does Ralph know what it's building?
- [ ] **Technology stack is specified** - Did you pick the frameworks?
- [ ] **Key constraints are documented** - Auth approach? API conventions?
- [ ] **fix_plan.md has specific tasks** - Can Ralph start on task 1 immediately?
- [ ] **Complex features have specs/** - Is anything too vague for PROMPT.md?
If you can answer "yes" to these, Ralph will do good work.
## Quick Reference
| Need to... | Put it in... |
|------------|--------------|
| Set project vision and principles | PROMPT.md |
| Define technology stack | PROMPT.md |
| List specific implementation tasks | fix_plan.md |
| Document complex feature requirements | specs/feature-name.md |
| Establish coding conventions | specs/stdlib/convention-name.md |
| Configure Ralph behavior | .ralphrc |