PRD-Design-Code-Test Pipeline

James Phoenix
James Phoenix

Requirements docs for the WHAT. Design docs for the HOW. Code for the implementation. Tests for the proof.


The Four-Layer Documentation Stack

Every non-trivial feature needs four layers of documentation. Each layer serves a distinct purpose and audience.

┌─────────────────────────────────────────────────────────┐
│  PRD (Product Requirements Document)                    │
│  ─────────────────────────────────────────────────────  │
│  WHAT we're building and WHY                            │
│  Audience: Product, Engineering, Stakeholders           │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  Design Doc                                             │
│  ─────────────────────────────────────────────────────  │
│  HOW we're building it                                  │
│  Audience: Engineers                                    │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  Code                                                   │
│  ─────────────────────────────────────────────────────  │
│  The implementation                                     │
│  Audience: Engineers, Agents                            │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  Tests                                                  │
│  ─────────────────────────────────────────────────────  │
│  Proof that it works                                    │
│  Audience: Engineers, CI, Agents                        │
└─────────────────────────────────────────────────────────┘

Why This Structure Matters

1. Separation of Concerns

Each document answers ONE question:

Document Question Answered
PRD What problem are we solving?
Design Doc How will we solve it technically?
Code What does the solution look like?
Tests Does it actually work?

When these get conflated, documents become bloated and unfocused. A PRD that includes implementation details is doing two jobs poorly.

2. Decision Traceability

Six months from now, when someone asks “why is this built this way?”, the trail is clear:

  • PRD explains the business requirement
  • Design doc explains the technical approach
  • Code shows the implementation
  • Tests prove the behavior

3. Agent Compatibility

LLM agents work best with clear, focused context. A well-structured documentation stack allows agents to:

  • Read the PRD to understand the goal
  • Read the design doc to understand constraints
  • Generate code that fits the design
  • Write tests that validate requirements

Layer 1: PRD (Requirements)

Purpose: Define WHAT we’re building and WHY.

Template:

# PRD: [Feature Name]

## Problem Statement
[What problem does this solve? Who has this problem?]

## Goals
- [Measurable goal 1]
- [Measurable goal 2]

## Non-Goals
- [What we're explicitly NOT doing]

## User Stories
- As a [role], I want [capability] so that [benefit]

## Requirements

### Functional Requirements
| ID | Requirement | Priority |
|----|-------------|----------|
| FR-1 | System shall... | P0 |
| FR-2 | System shall... | P1 |

### Non-Functional Requirements
| ID | Requirement | Target |
|----|-------------|--------|
| NFR-1 | Response time | < 200ms |
| NFR-2 | Availability | 99.9% |

## Success Metrics
- [How will we know this succeeded?]

## Dependencies
- [What does this depend on?]

## Timeline
- Target: [Date]

Key Principles:

  • No implementation details
  • Measurable requirements
  • Clear scope boundaries (goals AND non-goals)
  • Stakeholder-readable language

Layer 2: Design Doc

Purpose: Define HOW we’ll build it technically.

Template:

# Design Doc: [Feature Name]

## Overview
[1-2 paragraph summary linking to PRD]

**PRD Reference**: <a href="/posts/prd-001-feature-name/">PRD 001 feature name</a>

## Architecture

### System Context
[How does this fit into the existing system?]

### Component Design
[Diagrams and descriptions of new/modified components]

### Data Model
[Schema changes, new entities]

### API Design
[Endpoints, contracts, protocols]

## Technical Decisions

### Decision 1: [Title]
**Options Considered**:
1. Option A: [pros/cons]
2. Option B: [pros/cons]

**Decision**: Option A because [reasoning]

## Implementation Plan

### Phase 1: [Name]
| Task | Dependencies | Notes |
|------|--------------|-------|
| Task 1 | - | |
| Task 2 | Task 1 | |

### Phase 2: [Name]
...

## Testing Strategy
- Unit tests: [approach]
- Integration tests: [approach]
- E2E tests: [approach]

## Risks & Mitigations
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Risk 1 | Medium | High | [strategy] |

## Open Questions
- [ ] [Unresolved question 1]
- [ ] [Unresolved question 2]

Key Principles:

  • References the PRD, never duplicates it
  • Focuses on technical decisions
  • Includes alternatives considered (for future archaeology)
  • Phased implementation with dependencies

Layer 3: Code

The code itself is documentation when structured properly.

Principles for Self-Documenting Code:

Leanpub Book

Read The Meta-Engineer

A practical book on building autonomous AI systems with Claude Code, context engineering, verification loops, and production harnesses.

Continuously updated
Claude Code + agentic systems
View Book
  1. Directory structure reflects architecture
src/
  services/        # Business logic layer
    TaskService.ts
  repositories/    # Data access layer
    TaskRepository.ts
  schemas/         # Data models
    task.ts
  cli/             # Interface layer
    commands/
  1. File names match concepts from design doc
  2. Types as documentation – TypeScript interfaces document contracts
  3. Minimal comments – Code explains HOW, comments explain WHY

Layer 4: Tests

Tests serve as executable documentation of behavior.

Test Structure Mirrors Requirements:

describe('TaskService', () => {
  // Maps to FR-1: System shall create tasks
  describe('create', () => {
    it('creates a task with valid input', async () => {...});
    it('rejects tasks with empty titles', async () => {...});
  });

  // Maps to FR-2: System shall track dependencies
  describe('block', () => {
    it('creates a blocking relationship', async () => {...});
    it('prevents circular dependencies', async () => {...});
  });
});

Test Types and Their Role:

Test Type Documents Runs
Unit tests Component behavior Fast, local
Integration tests Component interactions CI
E2E tests User journeys CI, staging
Property tests Invariants CI

File Organization

A clean separation of concerns in the filesystem:

project/
├── docs/
│   ├── index.md              # Navigation hub
│   ├── prds/
│   │   ├── index.md          # PRD listing
│   │   ├── PRD-001-feature.md
│   │   └── PRD-002-feature.md
│   └── design/
│       ├── index.md          # Design doc listing
│       ├── DESIGN-001-feature.md
│       └── DESIGN-002-feature.md
├── src/
│   └── ...                   # Code
└── tests/
    └── ...                   # Tests

Index Files

Each folder needs an index.md that provides navigation:

docs/prds/index.md:

# Product Requirements Documents

| ID | Title | Status | Design Doc |
|----|-------|--------|------------|
| PRD-001 | <a href="/posts/prd-001-task-management/">PRD 001 task management</a> | Approved | <a href="/posts/design-001-task-management/">DESIGN 001 task management</a> |
| PRD-002 | <a href="/posts/prd-002-mcp-integration/">PRD 002 mcp integration</a> | Draft | - |

docs/design/index.md:

# Design Documents

| ID | Title | PRD | Status |
|----|-------|-----|--------|
| DESIGN-001 | <a href="/posts/design-001-task-management/">DESIGN 001 task management</a> | <a href="/posts/prd-001-task-management/">PRD 001 task management</a> | Implemented |

Document Lifecycle

PRD Draft → PRD Review → PRD Approved
                              ↓
                    Design Draft → Design Review → Design Approved
                                                        ↓
                                              Implementation → Tests → Merge

Status Values:

  • Draft – In progress, not ready for review
  • Review – Ready for feedback
  • Approved – Signed off, ready for next phase
  • Implemented – Code complete
  • Deprecated – No longer relevant

Anti-Patterns

1. The Mega-Doc

One document that contains requirements, design, implementation notes, and meeting minutes. Impossible to navigate, impossible to maintain.

Fix: Split into PRD + Design Doc + ADRs.

2. The Orphan Code

Code with no PRD or design doc. No one knows why it exists or what problem it solves.

Fix: Every feature needs at least a brief PRD. If it’s too small for a design doc, document the approach in the PR.

3. The Stale Design Doc

Design doc written once, never updated as implementation diverged.

Fix: Update design doc during implementation OR mark sections as “implemented differently, see code”. Dead docs are worse than no docs.

4. Tests Without Context

Tests that verify behavior but don’t explain why that behavior matters.

Fix: Organize tests to mirror requirements. Use descriptive test names that reference user stories.


Agent Integration

This structure is particularly effective for LLM agents:

  1. Context Loading: Agent reads PRD to understand goals, design doc to understand constraints
  2. Scoped Implementation: Agent implements one phase at a time per design doc
  3. Verification: Agent runs tests to verify implementation matches requirements
  4. Traceability: Agent can reference specific PRD requirements in commit messages

Example Agent Workflow

1. Load PRD: "Understand what we're building"
2. Load Design Doc: "Understand how to build it"
3. Implement Phase 1 tasks in order
4. Run tests after each task
5. Mark tasks complete
6. Proceed to Phase 2

Related

Topics
Code QualityDesign DocsDocumentation ProcessPrd PipelineSoftware Development Lifecycle

Newsletter

Become a better AI engineer

Weekly deep dives on production AI systems, context engineering, and the patterns that compound. No fluff, no tutorials. Just what works.

Join 306K+ developers. No spam. Unsubscribe anytime.


More Insights

Cover Image for The Execution Harness That Lets Agents Ship Code

The Execution Harness That Lets Agents Ship Code

Why determinism, schema isolation, and enforced layering are the real unlocks for agentic coding.

James Phoenix
James Phoenix
Cover Image for Throw Errors as Agent Trajectory Corrections

Throw Errors as Agent Trajectory Corrections

When AI agents drive development, they mutate state. They create files, run scripts, generate configs. Sometimes they skip a step or do something in the wrong order. Traditional error messages describ

James Phoenix
James Phoenix