NEW: Claude Code Security — research preview

Plan-Driven Development

Use PLAN.md, task decomposition, and checkpoint commits to keep AI agents on track for large features

Read time: 10 min

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 /login

Running 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:

  1. 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.
    
  2. 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

SymptomFix
Agent skips to Step 4 without finishing Step 2Add explicit "stop and wait" instructions between steps
Plan becomes stale mid-implementationAsk agent to update PLAN.md with what actually changed
Agent rewrites the plan to make it easierVersion-control the plan; tell agent it's read-only
Feature scope creepsAdd a "Non-goals" section to PLAN.md