Plan-Driven Development
Use PLAN.md, task decomposition, and checkpoint commits to keep AI agents on track for large features
title: "Plan-Driven Development" description: "Use PLAN.md, task decomposition, and checkpoint commits to keep AI agents on track for large features" section: "Workflows" readTime: "10 min"
Plan-Driven Development
Large features fail when you hand an AI agent a vague goal and walk away. Plan-driven development solves this: you create a structured plan file first, the agent uses it as a grounding document, and every checkpoint is a commit that can be rolled back.
Why Plans Matter for AI Agents
AI agents are excellent at executing well-defined steps but poor at decomposing ambiguous requirements autonomously. A plan file:
- Forces you to think through the design before any code is written
- Gives the agent clear acceptance criteria for each step
- Creates natural review points so you don't end up reviewing 2,000 lines of unreviewed AI code
- Serves as a shared artifact that any agent (Claude, Copilot, Cursor) can pick up
The PLAN.md Pattern
Create a PLAN.md in your repo root or feature branch:
# Feature: User Authentication
## Goal
Add email/password auth with JWT tokens and refresh rotation.
## Constraints
- Use existing Prisma schema — do not modify users table
- All endpoints must be protected by the existing rate limiter
- No new dependencies without approval
## Steps
### Step 1: Password hashing utilities [ ]
- Create `src/lib/auth/password.ts`
- Export: `hashPassword(plain: string): Promise<string>`
- Export: `verifyPassword(plain: string, hash: string): Promise<boolean>`
- Tests: `__tests__/auth/password.test.ts`
### Step 2: JWT utilities [ ]
- Create `src/lib/auth/jwt.ts`
- Export: `signToken(payload: JWTPayload): string`
- Export: `verifyToken(token: string): JWTPayload | null`
- 15min access token, 7-day refresh token
### Step 3: Auth endpoints [ ]
- POST /api/auth/register
- POST /api/auth/login → returns { accessToken, refreshToken }
- POST /api/auth/refresh → rotates refresh token
- POST /api/auth/logout → invalidates refresh token
### Step 4: Middleware [ ]
- `src/middleware/auth.ts` — validates JWT, attaches user to request
- Apply to all /api/protected/* routes
## Acceptance Criteria
- [ ] All tests pass
- [ ] No secrets logged
- [ ] Rate limiting applies to /register and /loginRunning a Plan with Claude Code
Option 1: Step-by-step with checkpoints
claude "Read PLAN.md. Execute Step 1 only.
After completing it, run the tests, then stop and wait for my approval
before moving to Step 2. Mark the step [x] in PLAN.md when done."After review:
claude "Step 1 looks good. Proceed to Step 2."Option 2: Autonomous execution with commits
claude "Read PLAN.md. Execute each step in order.
After each step: run tests, commit with message 'feat: PLAN step N — <description>',
then continue. If any step fails tests after 2 attempts, stop and report."Option 3: Plan mode first
Use Claude Code's built-in plan mode:
claude --plan "Add authentication as described in the requirements below: [paste requirements]"Review the generated plan, edit it, then:
claude "Execute the plan you just created."GitHub Copilot Plan-Driven Flow
Copilot doesn't have a native plan command, but you can achieve the same effect:
-
Create PLAN.md manually or ask Copilot to generate it first:
@workspace Before writing any code, create a PLAN.md for adding authentication. Break it into atomic steps, each with files to create/modify and test requirements. Wait for my approval before implementing. -
Execute step by step:
@workspace Implement only Step 1 from PLAN.md. Run the tests when done. Don't touch Step 2 yet.
Cursor Plan-Driven Flow
In Cursor Composer:
Read @PLAN.md. Implement Step 1 only.
After each file change, run @terminal npm test.
When Step 1 is complete and tests pass, update the checkbox in PLAN.md and stop.
Cursor's @file references keep the plan in context throughout the session.
Checkpoint Commits
Commit after every completed step — not at the end of the feature:
# Good: atomic, reviewable commits
git commit -m "feat: auth — password hashing utils (PLAN step 1/4)"
git commit -m "feat: auth — JWT sign/verify (PLAN step 2/4)"
git commit -m "feat: auth — register+login endpoints (PLAN step 3/4)"
git commit -m "feat: auth — middleware + route protection (PLAN step 4/4)"
# Bad: one 800-line commit
git commit -m "add authentication"Benefits: if Step 3 goes wrong, git reset --hard HEAD~1 gets you back to a working Step 2 state.
Plan Quality Checklist
When Plans Break Down
| Symptom | Fix |
|---|---|
| Agent skips to Step 4 without finishing Step 2 | Add explicit "stop and wait" instructions between steps |
| Plan becomes stale mid-implementation | Ask agent to update PLAN.md with what actually changed |
| Agent rewrites the plan to make it easier | Version-control the plan; tell agent it's read-only |
| Feature scope creeps | Add a "Non-goals" section to PLAN.md |