Module 6: The Fundamental Workflow — Research → Plan → Execute → Validate

Workflow Variants: PRD → Plan → Todo → Code, Spec-First, Explore → Plan → Code

Description

R→P→E→V isn't the only workflow that works with coding agents. It's the fundamental workflow — the base pattern from which others derive. In this capsule we explore three important variants that share a common principle (think before executing) but differ in emphasis, structure, and context of use.

You don't need to memorize the three variants. You need to know they exist, understand their differences, and know when each one has an advantage over basic R→P→E→V.


The Shared Principle

All the variants we'll see share one principle:

THINK ─── BEFORE ─── EXECUTING

Variant 1 (R→P→E→V):        Research → Plan → Execute → Validate
Variant 2 (PRD→Plan→Todo):  PRD → Plan → Todo → Code
Variant 3 (Spec-first):     Spec → Tests → Implement → Verify
Variant 4 (Explore→Plan):   Explore → Plan → Code

They all have:
→ An "understand" phase before coding
→ A "design" phase before implementing
→ An expectation of "verify" after executing

The difference is in where they place the emphasis.


Variant 1: PRD → Plan → Todo → Code

Origin

This variant comes from the best practices published by Anthropic for Claude Code. It's designed specifically for complex tasks where you need the agent to maintain coherence throughout a long implementation.

The four phases

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│   PRD    │ ──▶ │   PLAN   │ ──▶ │   TODO   │ ──▶ │   CODE   │
│          │     │          │     │          │     │          │
│ Product  │     │ Technical│     │ Task     │     │ Implement│
│ Require- │     │ Design   │     │ Break-   │     │ each     │
│ ments    │     │ Document │     │ down     │     │ task     │
│ Document │     │          │     │          │     │          │
└──────────┘     └──────────┘     └──────────┘     └──────────┘

Phase 1: PRD (Product Requirements Document)

The PRD isn't formal company documentation. It's a concise document that answers:

WHAT am I building?
→ A clear description of the feature/change

FOR WHOM?
→ End user or consuming system

WHAT should it do?
→ Expected behavior (functional)

WHAT should it NOT do?
→ Explicit limits (out of scope)

HOW DO I KNOW IT'S DONE?
→ Acceptance criteria

Phase 2: Plan (Technical Design)

With the PRD defined, you create a technical plan:

ARCHITECTURE
→ Components involved
→ How they interact
→ What changes vs what stays

APPROACH
→ Main technical decisions
→ Trade-offs considered
→ Justification for each decision

FILES
→ A list of files to create/modify/delete

Phase 3: Todo (Task Breakdown)

The plan gets broken down into atomic tasks the agent can execute one by one:

TODO LIST:
[ ] 1. Create the UserProfile interface in types/user.ts
[ ] 2. Implement the GET /api/users/:id/profile endpoint
[ ] 3. Add the validation middleware
[ ] 4. Write tests for the happy path
[ ] 5. Write tests for error cases
[ ] 6. Update API documentation

Each task is:

  • Atomic: It can be completed in one step
  • Verifiable: You can confirm whether it was done or not
  • Ordered: The sequence matters (dependencies)

Phase 4: Code

You implement each task in the todo list, one by one:

"Implement task 1 of the todo list: create the
 UserProfile interface in types/user.ts according to the technical plan."

→ Review → ✅

"Implement task 2: the GET /api/users/:id/profile endpoint.
 Use the interface we just created."

→ Review → Adjustment → ✅

[... each task ...]

When to use PRD → Plan → Todo → Code

✅ USE THIS VARIANT when:
→ The task is complex (multiple components)
→ You need coherence throughout the implementation
→ The agent needs persistent context (PRD as a reference)
→ You're working with new features (not refactoring)
→ The scope could expand without control

❌ DON'T USE IT when:
→ The task is simple (excessive overhead)
→ You're doing refactoring (there's no "product requirement")
→ The task is exploratory (you don't know what to build yet)

Relationship with R→P→E→V

PRD → Plan → Todo → Code    ≈    R → P → E → V

PRD  ←→  Research + part of Plan (defines the "what")
Plan ←→  Plan (defines the "how")
Todo ←→  Detailed Plan (breaks the "how" into steps)
Code ←→  Execute (implements)

And Validate?
→ In this variant, Validate is IMPLICIT in each Todo task
→ Each task is verified before moving to the next
→ But it's NOT explicit as a separate phase ← this is a risk

Main advantage

The breakdown into Todo tasks keeps the agent focused and produces more coherent implementations on long tasks.

Main risk

Validate isn't an explicit phase. If you don't actively verify, you can complete all the todos and have a feature that "looks complete" but has subtle bugs.


Variant 2: Spec-First + TDD

Origin

This variant comes from the Tweag methodology for development with AI and aligns with Test-Driven Development (TDD) principles. The premise is radical: define the tests BEFORE writing the code.

The four phases

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│   SPEC   │ ──▶ │  TESTS   │ ──▶ │IMPLEMENT │ ──▶ │  VERIFY  │
│          │     │          │     │          │     │          │
│ Define   │     │ Write    │     │ Code     │     │ All      │
│ behavior │     │ tests    │     │ until    │     │ tests    │
│ formally │     │ FIRST    │     │ tests    │     │ pass +   │
│          │     │          │     │ pass     │     │ review   │
└──────────┘     └──────────┘     └──────────┘     └──────────┘

Phase 1: Spec (Specification)

You formally define what the code should do — without implementing it. The spec is a contract:

SPEC: Rate Limiter Middleware

BEHAVIOR:
→ Accepts configuration: { windowMs, maxRequests, message }
→ Counts requests per IP in the time window
→ If count < max: allows the request, adds headers
→ If count >= max: returns 429 with message and Retry-After
→ Resets the counter when the window expires

HEADERS (always present):
→ X-RateLimit-Limit: maxRequests
→ X-RateLimit-Remaining: maxRequests - count
→ X-RateLimit-Reset: reset timestamp

EDGE CASES:
→ IP not available: use "unknown" as the key
→ Multiple proxies: respect X-Forwarded-For
→ windowMs = 0: disable rate limiting

Phase 2: Tests (written BEFORE the code)

The tests implement the spec. The code doesn't exist yet — the tests fail.

describe('RateLimiter', () => {
  it('allows requests under the limit', () => {
    // Arrange: limiter with max=5
    // Act: send 3 requests
    // Assert: all return 200 with correct headers
  })
  
  it('blocks requests over the limit', () => {
    // Arrange: limiter with max=5
    // Act: send 6 requests
    // Assert: the 6th returns 429 with Retry-After
  })
  
  it('resets counter after window expires', () => {
    // Arrange: limiter with max=5, windowMs=1000
    // Act: send 5 requests, wait 1.1s, send 1 more
    // Assert: the last request passes (counter reset)
  })
  
  it('handles missing IP gracefully', () => {
    // Arrange: request without IP
    // Assert: uses "unknown" as the key, doesn't crash
  })
})

Phase 3: Implement

Now you write the code — with a clear definition of "done": all the tests pass.

Developer: "Implement a rate limiter middleware that makes
all these tests pass. Don't modify the tests."

→ The agent has a clear contract
→ There's no ambiguity about what it should do
→ The success criterion is binary: tests pass or not

Phase 4: Verify

The tests pass. But Verify goes beyond:

→ Do the tests cover the spec completely?
→ Is there unspecified behavior that should be tested?
→ Is the implementation maintainable?
→ Are there side effects not captured by the tests?

When to use Spec-First + TDD

✅ USE THIS VARIANT when:
→ The behavior is clearly definable
→ Correctness is critical (auth, payments, data integrity)
→ You want the agent to have an unambiguous contract
→ The team values tests as documentation
→ You're building something others are going to maintain

❌ DON'T USE IT when:
→ You're exploring (you don't know what behavior you want)
→ The code is UI/visual (behavior tests are insufficient)
→ The task is refactoring without a behavior change
→ The overhead of writing specs/tests first isn't justified

Relationship with R→P→E→V

Spec-first + TDD         ≈    R → P → E → V

Spec      ←→  Research + Plan (defines what and how)
Tests     ←→  Detailed Plan (the definition of done IS the test)
Implement ←→  Execute (implements)
Verify    ←→  Validate (the tests ARE the validation)

Key advantage:
→ Validate isn't subjective — it's binary (tests pass or not)
→ The "definition of done" is codified, not in a document

Main advantage

The definition of done is binary and automated. There's no ambiguity about whether something "works."

Main risk

Writing specs and tests first requires upfront time and discipline. For exploratory tasks or ones with changing requirements, the overhead can be counterproductive.

Why it works especially well with AI

THE AGENT WORKS BETTER WITH CLEAR CONTRACTS

Without a spec:
"Implement rate limiting" → many possible interpretations

With a spec + tests:
"Make these tests pass" → a single correct interpretation

The result:
→ Less ambiguity = fewer hallucinations
→ Tests as automatic validation
→ The agent can iterate on its own until the tests pass

Variant 3: Explore → Plan → Code

Origin

This variant is native to modern coding agents. It's the workflow that tools like Claude Code, Cursor Agent, and others promote implicitly when the developer doesn't have their own process. It's the most "organic" of the three variants.

The three phases

┌──────────┐     ┌──────────┐     ┌──────────┐
│ EXPLORE  │ ──▶ │   PLAN   │ ──▶ │   CODE   │
│          │     │          │     │          │
│ Read     │     │ Design   │     │ Implement│
│ files,   │     │ approach │     │ with     │
│ search   │     │ based on │     │ agent    │
│ codebase │     │ findings │     │          │
└──────────┘     └──────────┘     └──────────┘

Phase 1: Explore

Explore is a streamlined version of Research. Instead of a formal process, you use the agent to navigate the codebase quickly:

"Read src/routes/ and show me the structure"
"Find how errors are handled in this project"
"What middleware is currently used?"
"Are there tests? What testing framework?"

Phase 2: Plan

With the exploration done, you define an approach — generally lighter than a formal plan:

"Based on what we saw:
→ We're going to create the middleware in src/middleware/
→ Follow the pattern of the existing middleware  
→ Add tests in the same style as the current ones
Can you think of anything I'm missing?"

Phase 3: Code

Direct implementation, possibly in a single cycle or in steps:

"Okay, implement the rate limiter based on what we discussed.
 Follow the codebase's patterns."

When to use Explore → Plan → Code

✅ USE THIS VARIANT when:
→ The codebase is new to you (you need to explore first)
→ The task is moderate (it doesn't require a formal PRD)
→ You want speed with some structure
→ The agent is your main source of information about the codebase
→ You're doing refactoring or improvements

❌ DON'T USE IT when:
→ The task is complex and multi-component (you need a PRD)
→ Correctness is critical (you need Spec-first)
→ You already know the codebase well (Explore is redundant)

Relationship with R→P→E→V

Explore → Plan → Code    ≈    R → P → E → (V?)

Explore ←→  Research (lighter, faster)
Plan    ←→  Plan (generally less formal)
Code    ←→  Execute (sometimes with less direction)

And Validate?
→ It DOESN'T EXIST as an explicit phase ← this is the biggest risk
→ It's up to the developer to add validation

Main advantage

Speed and naturalness. It's the workflow that requires the least overhead and feels the most "fluid" with a coding agent.

Main risk

Validate doesn't exist as a phase. It's easy to declare "done" when the code compiles, without verifying that it works correctly.


Comparison of Variants

Comparison table

┌───────────────────┬──────────┬──────────┬──────────┬──────────┐
│                   │  R→P→E→V │ PRD→Plan │ Spec-    │ Explore  │
│                   │          │ →Todo    │ first    │ →Plan    │
│                   │          │ →Code    │ +TDD     │ →Code    │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Setup             │ Medium   │ High     │ High     │ Low      │
│ complexity        │          │          │          │          │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Overhead          │ Moderate │ High     │ High     │ Low      │
│                   │          │          │          │          │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Validate          │ Explicit │ Implicit │ Automatic│ Absent   │
│                   │          │          │ (tests)  │          │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Best for          │ General  │ Complex  │ Critical │ Explora- │
│                   │ purpose  │ features │ code     │ tion +   │
│                   │          │          │          │ moderate │
│                   │          │          │          │ tasks    │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Main risk         │ None     │ Validate │ Excessive│ No       │
│                   │ (it's the│ not      │ overhead │ Validate │
│                   │ most     │ explicit │ for      │          │
│                   │ complete)│          │ simple   │          │
│                   │          │          │ tasks    │          │
├───────────────────┼──────────┼──────────┼──────────┼──────────┤
│ Agent as          │ Collabo- │ Task     │ Executor │ Explorer │
│                   │ rator    │ executor │ with     │ + Coder  │
│                   │ in all   │          │ clear    │          │
│                   │ phases   │          │ contract │          │
└───────────────────┴──────────┴──────────┴──────────┴──────────┘

Decision diagram

Which variant to use?

The task is...

COMPLEX + NEW FEATURE
→ PRD → Plan → Todo → Code
→ You need coherence throughout many steps
→ The PRD keeps the agent aligned

CORRECTNESS IS CRITICAL
→ Spec-first + TDD
→ Authentication, payments, sensitive data
→ The tests are your safety net

NEW CODEBASE + MODERATE TASK
→ Explore → Plan → Code (+ add Validate)
→ You need to understand before acting
→ But you don't need formal overhead

ANYTHING ELSE
→ R→P→E→V
→ It's the safe default
→ Adapt the intensity to the size of the task

The four workflows as a spectrum

LIGHTER ─────────────────────────────────── MORE RIGOROUS

Explore→     R→P→E→V      PRD→Plan→       Spec-first
Plan→Code                  Todo→Code       + TDD

Less         Moderate      More            Maximum
overhead     overhead      overhead        overhead

Less         Good          Good            Maximum
validation   validation    coherence       validation

Maximum      Balance       Maximum         Maximum
speed                      control         correctness

Combining Variants

In practice, you don't use a single variant rigidly. You combine them based on what you need:

Example: Complex feature with a critical component

FEATURE: Payment system with Stripe

Global phase: PRD → Plan → Todo → Code
→ The feature is complex, I need coherence

But for the payment processing module:
→ Spec-first + TDD
→ It's the critical part where errors are costly

And for the checkout UI:
→ Explore → Plan → Code
→ I need to explore the existing design system

And for the integration:
→ Complete R→P→E→V
→ The safe default for connecting everything

Example: Database migration

MIGRATION: PostgreSQL to MongoDB

Deep research (R→P→E→V):
→ Understand the complete current schema
→ Map existing queries

Formal plan (PRD→Plan→Todo→Code):
→ PRD: what gets migrated, what changes, what stays
→ Todo list: migration table by table

Tests for critical queries (Spec-first):
→ Spec: "this query should return the same results"
→ Tests: compare PostgreSQL vs MongoDB output

Exploration of MongoDB features (Explore→Plan→Code):
→ Explore aggregation pipeline, indexes, etc.

The combination rule

1. USE R→P→E→V as the base (always applies)
2. ADD PRD when the scope is large
3. ADD Spec-first when correctness is critical
4. USE Explore when the codebase is unknown

They're not mutually exclusive — they're tools
in your workflow toolkit.

Common Mistakes When Choosing a Variant

MistakeConsequenceCorrection
Using PRD for simple tasksUnnecessary overhead, frustrationBasic R→P→E→V is enough
Using Explore→Plan→Code for critical codeLack of rigorous validationAdd Spec-first for the critical part
Always using the same variantSuboptimal for the contextEvaluate each task
Not adding Validate to variants without itSilent bugsAlways add an explicit validation phase
Over-engineering the workflowAnalysis paralysisThe workflow is to accelerate, not to bureaucratize

Practical Exercise

Exercise 1: Choose the variant

For each scenario, choose the most suitable variant and justify:

SCENARIO 1:
Add a "dark mode" button to an existing React app.
→ Variant: _______________
→ Why: _______________

SCENARIO 2:
Implement an OAuth2 + MFA authentication system.
→ Variant: _______________
→ Why: _______________

SCENARIO 3:
First day on a new project. You're asked to fix a bug
in the notifications module.
→ Variant: _______________
→ Why: _______________

SCENARIO 4:
Refactor a monolith into microservices (a 3-month project).
→ Variant: _______________
→ Why: _______________

SCENARIO 5:
Add input validation to an existing form.
→ Variant: _______________
→ Why: _______________

Exercise 2: Design your personal workflow

Based on the variants you learned, design your personal
workflow. Answer:

1. What's your "default" variant?
   _______________________________________________

2. When do you switch to PRD→Plan→Todo→Code?
   _______________________________________________

3. When do you use Spec-first?
   _______________________________________________

4. How do you handle Validate when the variant doesn't include it?
   _______________________________________________

5. Is there a variant of your own that you combine?
   _______________________________________________

Summary

FOUR VARIANTS, ONE PRINCIPLE:
Think before executing.

R→P→E→V:              The safe default, complete
PRD→Plan→Todo→Code:    For complex features, coherence
Spec-first + TDD:      For critical code, maximum correctness
Explore→Plan→Code:     For a new codebase, speed

HOW TO CHOOSE:
→ Evaluate complexity, criticality, and familiarity
→ Use R→P→E→V as the base
→ Add elements from other variants as needed
→ ALWAYS add Validate if the variant doesn't include it

THE VARIANTS COMBINE:
→ They're not mutually exclusive
→ A project can use different variants for different parts
→ The workflow is a toolkit, not a dogma

Next capsule: 04 - Verification: the step everyone skips — why it's the most important step, what it costs to skip it, and how to use the agent to verify.


Resources

  1. Anthropic: Claude Code Best Practices — PRD → Plan → Todo → Code explained
  2. Tweag: AI-Assisted Software Development — Spec-first methodology
  3. Kent Beck: TDD by Example — The fundamentals of TDD, applicable to Spec-first
  4. Martin Fowler: Is TDD Dead? — Discussion on when TDD makes sense and when it doesn't
  5. Cursor Documentation: Agentic Mode — Native Explore → Plan → Code