| name | plan-driven-development |
| description | Use when starting any feature (small or large), resuming work after context loss, or unsure if a feature plan already exists. For smaller features, use lightweight mode (no plan file, but all PDD rules still apply). |
Plan-Driven Development
Overview
Large features get a versioned plan file in plans/ that serves as the single source of truth โ what's been done, what's in progress, and what's left. The plan persists across context windows so any agent (or agent team) can pick up where the last one left off.
PDD requires powerups:best-practices โ invoke it, don't just reference it. Every practice there is mandatory here; PDD adds planning infrastructure on top. If you're unsure whether a best-practice applies: it does.
When to Use
PDD can be invoked for features of any size. The difference is whether you write a plan file.
Write a plan file (plans/v{N}-*.md) when:
- Feature spans multiple milestones or will take more than one session
- Multiple files/modules need coordinated changes
- You need to track progress across context resets
- Multiple agents will work on different pieces in parallel
Use lightweight mode (plan inline, no file) when:
- Feature is smaller but still touches multiple files
- Work fits in one session with no risk of context loss
- No milestones needed โ it's a single logical chunk of work
In lightweight mode, still write a plan โ present it inline for user review instead of writing a file: what you're changing, which files are affected, impact scan results, and the approach. Get approval before coding. All other PDD rules still apply: invoke powerups:best-practices, run the skill audit, branch, run the capped grilling session (workflow step 7), TDD, and run the post-completion audit.
On every session start for feature work:
- Spawn an
Explore subagent to check plans/ for an existing plan. Plan files are large โ never read them directly in the main conversation. The subagent returns a concise summary: current milestone, next unchecked task, blockers, key design decisions.
- If there's an active plan, orient from the summary. Only read specific plan sections directly if you need exact task wording or file paths.
- Update the progress summary table and check off completed tasks (small edits, fine in main context).
Plan Location & Naming
plans/
โโโ v0-initial-build.md
โโโ v1-auth-and-production-readiness.md โ initial plan
โโโ v1-auth-and-production-readiness-r2.md โ revised (approach changed)
โโโ v2-multi-provider-support.md
โโโ ...
Naming: v{N}-{short-action-description}.md (initial), v{N}-{description}-r{R}.md (revisions)
v{N} โ sequential version number (check existing files for the next number)
{short-action-description} โ lowercase, hyphens, action-oriented (e.g., multi-provider-support)
-r{R} โ revision suffix for major changes (r2, r3, โฆ). The initial version has no suffix.
- If
plans/ doesn't exist, create it
Title inside the file should match: # v1-r2: Auth & Production Readiness (WorkOS)
Create a revision (new -r{R} file) when: the core technical approach changes, major scope is added/removed, or the architecture fundamentally shifts. Not for: checking off tasks, small task edits, or wording. Previous revision files stay in plans/ as history โ never delete the original.
Plan Structure
Every plan has these sections:
1. Context
What problem this solves, why it's being built, key relationships and constraints. Written so an agent with zero prior context understands the full picture.
2. Design / Architecture
Data models, API endpoints, flow diagrams, key decisions and their rationale. Enough detail that implementation doesn't require guessing.
3. Scenario Map (for complex changes only)
Include for: complex refactors, upgrades to existing systems, anything changing behavior users rely on, or features where multiple actors interact with overlapping states. Skip for: lightweight mode and simple additive features. Plans written from a single happy-path perspective miss the failure modes and state interactions that cause production incidents โ this section forces the enumeration while gaps are still cheap to fix.
How to build the map:
- List the actors โ end user, admin, operator, background job, etc.
- List the state dimensions โ flags, connection states, permissions, API outcomes (200/4xx/5xx), cached vs fresh, etc.
- For each actor ร state combination, write a row: what the user does, what the system does, whether the plan covers it.
- Explicitly flag gaps โ rows where the plan is silent or ambiguous.
- Include adversarial and degraded states โ disconnected mid-flow, stale tokens, duplicate submissions, two tabs racing, concurrent toggles, rollback.
Table format:
### A โ [Actor name, e.g., "Admin dashboard user"]
| # | State | What happens | Plan coverage |
|---|---|---|---|
| A1 | Feature off, no connection | Existing behavior unchanged | OK |
| A2 | Feature on, mid-flow disconnect | ??? | Gap โ decide fallback |
| A3 | Feature on, API 5xx on write | Fall back vs hard fail | Gap โ ask user |
Group rows by actor (A, B, Cโฆ). One line per row โ detail lives in the milestone task.
Turn gaps into actions before plan approval. Each Gap row becomes one of: (a) a new milestone task, (b) an explicit "out of scope" note with a one-line rationale, or (c) an AskUserQuestion whose answer gets folded back in. Never leave a gap unresolved โ an unresolved gap in the plan becomes a bug in production.
(Real example: a ticket-routing upgrade's scenario map surfaced mid-chat API failure handling, whether disconnecting a connector should reset a toggle, duplicate ticket creation on double-submit, and toggle-off confirmation โ none obvious from the happy-path design, each changed a milestone.)
4. Milestones with Task Checkboxes
The core of the plan. Each milestone is a logical chunk of work:
### Milestone N: Short Name
**Goal:** One sentence.
Tests first (these will fail until implementation):
- [ ] Write failing tests for X
Then implement to make tests pass:
- [ ] Implement X
**Verification:**
- [ ] How to confirm this milestone is done
TDD is required by default. Every milestone that adds or changes behavior lists test tasks before implementation tasks, unless the user explicitly opts out ("skip tests"). Pure refactors of already-tested code need no new tests, but existing tests must pass.
Rules:
- Tasks are concrete and actionable ("Create
src/auth/models.py" not "Set up auth"), with file paths where relevant
- Check off tasks (
- [x]) as they complete; never remove completed tasks โ they're the history
5. Progress Summary Table
At-a-glance status at the bottom of the file; update as milestones progress:
| Milestone | Status | Notes |
|-----------|--------|-------|
| 1. Name | Done | |
| 2. Name | In progress | Blocked on X |
Multi-Agent Development
The plan file is the shared coordination point โ all agents read from and write to it. Identify milestones/tasks with no dependencies between them and spawn subagents to work them concurrently (e.g., one builds auth models while another builds rate limiting); each agent checks off its own tasks. Never parallelize sequential tasks.
Every agent prompt must include: a reference to the plan file ("Read plans/v{N}-{description}.md for full context"), which milestone/tasks the agent owns, and the TDD requirement (failing tests first).
Workflow
Starting a new feature
-
Set /effort max โ planning requires deep reasoning.
-
Check plans/ โ find the next version number.
-
Create a feature branch FIRST โ git checkout -b feat/{description}. Never write plans or code on main โ even the plan commit goes on a branch.
-
Invoke powerups:best-practices โ actually invoke it, so branching, investigation, and the impact scan happen before any code or plan is written.
-
Skill audit โ required before writing the plan. List every available powerups skill by name; for each, state whether it applies to this feature and why. Output the analysis to the user.
Skill audit for v10-sync-change-details:
- best-practices: YES โ always applies (already invoked)
- user-research: YES โ user-facing feature; ran discovery brief before this plan
- test-driven-development: YES โ new backend logic needs tests
- simple-design-principles: YES โ frontend UI with user-facing copy
- self-documenting-apis: YES โ new API endpoint
- update-docs: YES โ run after all milestones complete
- bug-fix: NO โ this is a new feature, not a bug fix
Every YES skill must appear as an explicit task or note in the relevant milestone. Don't rely on remembering โ write it into the plan.
-
Run powerups:user-research (user-facing features only) โ BEFORE writing the plan. Its brief feeds the Context and Design sections and turns silent assumptions into explicit decisions. Get the requester's answers to the hand-off questions first. That skill owns the skip conditions.
-
Grill the requester โ capped at 5โ10 questions. Invoke the grilling skill (Matt Pocock's skills, not bundled with powerups) on the feature idea: requirements, scope, edge cases, tradeoffs, what "done" means. Hard cap: 5โ10 questions total โ pick the highest-leverage ones, not grilling's default relentless depth; a planning session is not an interrogation. One question at a time, each with 2โ4 suggested answers and a recommended pick (use AskUserQuestion โ recommended option first, labeled "(Recommended)"). Stop early once the plan's open decisions are resolved. If the skill isn't installed, ask the user if they'd like to install it (install instructions at the repo above); either way, proceed with the same capped, one-at-a-time questioning via AskUserQuestion.
-
Create plans/v{N}-{description}.md
-
Write Context and Design sections โ grounded in the user-research brief when one was produced.
-
Scenario map โ build it per section 3 above for complex refactors/upgrades; resolve every gap before approval.
-
Write the Milestones โ include the skill tasks from step 5 and the gap-closing tasks from step 10.
-
Get user approval on the plan before coding.
-
Identify which milestones/tasks can be parallelized.
-
Begin work โ spawn subagents for independent pieces.
After planning (before coding)
Run /update-docs to check if the planning investigation revealed stale documentation (outdated CLAUDE.md entries, incorrect API references in sibling repos). Fix staleness before implementing.
Resuming work (new context, no memory)
Follow the session-start rule from "When to Use": Explore subagent summarizes the plan, you orient from the summary, find the first unchecked task, and continue from there.
During implementation
- Invoke
powerups:best-practices at the task level โ the plan organizes the work; best-practices governs how each task is executed.
- Check off each task immediately when done; update the progress table when a milestone completes.
- If you discover new work, add tasks to the appropriate milestone.
- Commit the plan file alongside code changes.
- If the approach fundamentally changes, create a new revision file (
-r2) rather than editing in place.
Plan drift โ keep the plan in sync with reality
The moment implementation diverges from what's written, the plan stops being trustworthy and any agent resuming from it repeats a failed approach. When a decision changes mid-flight, update the plan in the same commit as the code.
This rule covers small/medium drift โ a changed decision, an approach that didn't work, a different library. For fundamental changes, use the -r{R} revision mechanism instead.
Update additively โ never rewrite history:
- Leave the original task/decision text as-is.
- Directly under it, add a
> **Revised ({YYYY-MM-DD}):** callout: what was planned, what you actually did, why it changed.
- New tasks go as fresh checkboxes under the note; obsolete tasks get annotated
~~superseded โ see revised note~~, never deleted.
- Update the Design section the same way if the change affects documented design.
- Commit the plan update with the code change โ one commit, both files.
- [x] Use Redis for OTP storage with 5-minute TTL
> **Revised (2026-05-10):** Switched to Postgres with an `expires_at` column.
> Redis would have required a new dependency for one feature; the existing
> Postgres connection handles this with no infra change.
- [x] Add `expires_at` column and cleanup job for OTP rows
After each major milestone โ pause for user testing
When a milestone completes, stop and let the user test manually before moving on:
- Provide step-by-step test instructions โ prerequisites, exact commands (curl, URLs, SQL), expected output, how to verify success vs. failure.
- Include setup steps for any new dependencies, env vars, or configuration.
- Wait for user confirmation before starting the next milestone.
- Clear context after successful testing โ the plan file holds all the state needed to resume fresh.
After all milestones complete โ POST-COMPLETION AUDIT
The audit gates the PR. Output it to the user before creating the PR โ each step, its status, and evidence. Do not create the PR until every item is done.
Post-completion audit:
1. Skill audit review: DONE โ all 5 YES skills executed (best-practices, TDD, simple-design, update-docs, change-log)
2. Drift audit: DONE โ additive: 7 unplanned widgets + 3 deps recorded in plan;
subtractive: 4 orphan files deleted, 2 completed Post-MVP items removed
3. /simplify: DONE โ deleted 200 lines dead code, fixed 3 issues
4. change-log: DONE โ added entry "Your assistant can now..."
5. update-docs: DONE โ CLAUDE.md and connector guide updated
6. Linter: DONE โ no new warnings
7. Full test suite: DONE โ 133 passed, 0 failed
8. PR ready: YES โ manual verification steps included
The steps:
- Skill audit review โ confirm every YES skill from the planning audit was executed; if any was missed, execute it now.
powerups:drift-audit โ invoke it; it owns the detail. It runs BEFORE /simplify so the cleanup is informed by both directions of drift.
- Steps 3โ7: the finishing sequence from
powerups:best-practices practice #9 โ /simplify, change-log, update-docs, lint, full test suite, in that order. A green full suite is a hard gate: tests and code drift independently (fixtures on old table names while code uses new ones), and a full run is the only way to catch it.
- Create the PR with manual verification steps (below), referencing the drift section so reviewers don't reverse-engineer scope creep.
PR manual verification steps โ required
Every PR includes a Manual verification section reviewers can follow. Automated tests verify code correctness โ manual steps verify feature correctness.
- Number each scenario with a descriptive title
- Steps are sequential and specific โ exact actions, with prerequisites (env vars, server, test data)
- Each behavior check gets a Verify: line stating what the reviewer should see
- Cover the golden path, at least one edge case, and a no-regressions check
## Manual verification
### 1. Creating a new widget
1. Start local dev (`npm run dev`)
2. Navigate to the dashboard โ Widgets page
3. Click "Create Widget", fill in name: "Test Widget", theme: "Dark", Save
4. **Verify:** Widget appears in the list with name "Test Widget" and dark theme badge
5. **Verify:** Toast shows "Widget created"
### 2. Edge case: duplicate name
1. Create another widget named "Test Widget"
2. **Verify:** Error "A widget with this name already exists"; no duplicate in the list
### 3. No regressions
- [ ] Existing widgets still display correctly
- [ ] Delete widget still works
Never write vague test plans ("verify it works"). Every step should be reproducible by someone who has never seen the feature.
Rolling back work
If code is reverted, the plan reverts too: uncheck the rolled-back tasks (- [x] โ - [ ]) and update the progress table. The plan must always match reality.
Completing a plan
All checkboxes checked, progress table all "Done", plan stays in plans/ as historical record.
Common Mistakes
| Mistake | Fix |
|---|
Starting to code without checking plans/ | Always check first โ you may be mid-feature |
| Vague tasks ("set up auth") | Be specific: file paths, endpoint names, model fields |
| Creating a plan file for a 10-minute fix | Use lightweight mode โ no file, but all PDD rules still apply |
| Tracking progress elsewhere (todos, comments) | The plan file is the single source of truth |
| Skipping the full suite before the PR | Tests and code drift independently (fixtures on old table names). A full run is the only way to catch it |
| Implementing differently than planned without updating the plan | Add a > **Revised:** note in the same commit as the code. The drift audit is the last chance to catch this before the PR |