2024-10-07
Structured Plans for Agents
-
AI coding tools are great at one-off edits, but they fall apart on multi-step work: they forget context, skip steps, or refactor half your codebase when you asked for a small change.
Here's how I fix that using three pieces:
- A
notes.mdfile for planning and brainstorming - A
/prompts:plancommand that turns notes into a phased plan - A
/prompts:implementcommand that executes one phase at a time
§ Step 1: Write a notes.md
Before the agent touches code, I create a notes.md at the project root with:
- Goals: what I'm changing and why
- Scope: files, modules, routes, or features that will be touched
- Constraints: performance, security, UX, refactor boundaries, tech debt I'm not touching
- Edge cases: weird inputs, migrations, rollout concerns
- References: links to docs, tickets, or design specs
- Sketches: rough API shapes, data structures, code skeletons
I'll have the agent scan the repo and propose options, but I make the decisions. notes.md is my single source of truth.
§ Step 2: Turn notes into plan.md
Once notes.md is complete enough to build from, I run:
/prompts:plan notes.md
This reads the notes and writes a structured ./plan.md with:
- A summary at the top
- A phased checklist in the middle
- A final verification section at the bottom
Here's the prompt:
---
description: Notes → phased plan. Writes ./plan.md
argument-hint: <notes_file>
---
# Behavior
- Read notes from the provided source (for example: first CLI argument, selected file, or pasted content).
- Write a single file: ./plan.md. Overwrite if it exists. Touch nothing else.
- Output must follow the exact structure below.
- Keep language terse but complete: name concrete file paths, functions, commands, data structures, and acceptance criteria.
- Every actionable step is a checkbox.
# Output (exact)
Create plan.md with these sections, in order:
## 1) Notes / Summary / Context
Create a compressed, top-of-file digest of the input notes so a new agent or developer can act without opening the original source.
Rules:
- Keep all unique facts, decisions, and constraints.
- Remove repetition and filler. Do not invent new content.
- Preserve original identifiers: file paths, classes, functions, endpoints, commands, config keys, env vars.
- Follow the source order of major headings where possible. Group related points.
- Use bullets or short paragraphs. Prefer concrete nouns over prose.
Content to include:
- What is being built and why.
- Modes, flags, configs, data structures.
- Constraints, decisions, dependencies.
- Touch points: files, modules, endpoints, SDK calls, scripts.
- Risks, edge cases, open questions.
- Next steps at a glance.
Length:
- Compress aggressively but retain meaning.
- If the source is short, keep this short.
- If the source is long and dense, keep all critical detail.
Placement:
- Put this digest at the top of plan.md under this heading. The phases follow.
## 2) Phased Step Plan
Create up to 8 phases. Each phase must be independently testable and shippable.
For each phase use this template:
### Phase N — <short title>
Context & Assumptions
- Summarize decisions, constraints, and dependencies unique to this phase (1–3 bullets).
- Name impacted files/modules and external touchpoints (APIs, SDKs, queues, jobs, scripts).
Design / Skeletons
- Provide minimal code or config skeletons (new or changed files) as fenced blocks with signatures and TODOs.
- Include example payloads or config fragments where relevant.
Example:
```language
# path/to/module.ext
function do_something(input):
# TODO: describe core behavior
pass
```
```json
{
"exampleKey": "value",
"anotherKey": 123
}
```
Implementation
* [ ] Concrete steps only (files, modules, functions, scripts, commands)
* [ ] Small, safe, reversible changes
* [ ] No deletions unless explicitly required and migrated
Test Creation
* [ ] Add or extend tests for this phase only (name files and test cases)
* [ ] Cover at least one happy path and one failure path
* [ ] Note fixtures, mocks, and test data needed
Checks / Validation
* [ ] Run the project's standard checks relevant to this phase (formatters, linters, type checks, tests, or equivalent)
* [ ] Fix any issues reported by these checks
* [ ] Re-run the checks and confirm they pass for this phase's changes
Exit Criteria
* [ ] All Implementation items completed
* [ ] New or updated tests exist and pass
* [ ] Project checks clean for this phase's changes
## 3) Final Verification
* [ ] Run the project's full check suite (for example: all tests, linters, type checks, CI-equivalent commands)
* [ ] Confirm no regressions in previously working areas
* [ ] List any residual risks, follow-ups, or future improvements
# Rules
* Be specific. Name files, functions, endpoints, scripts, and commands.
* Use checkboxes for every actionable item.
* Keep language terse. No filler.
* Do not modify code or systems beyond creating ./plan.md.
* Each checkbox must name:
* The exact file path (or component)
* The symbol or concern (function, class, endpoint, config, or test)
* The action to perform
* An acceptance condition (what "done" means)
Format checkboxes like:
* [ ] path/to/file.ext:SymbolOrConcern — action — acceptance
Example:
* [ ] src/api/users.ts:createUserHandler — add validation for required fields — requests missing email return a 400-style error with a clear message § Step 3: Implement one phase at a time
To change code, I use a second command that focuses on one phase only:
/prompts:implement 1 # Phase 1 from ./plan.md
if your plan.md is located somewhere else you do
/prompts:implement 2 docs/plan.md # Phase 2 from custom path
This reads the plan, locates the phase heading, and executes only that phase's tasks implementation, tests, checks, exit criteria. Everything else stays untouched.
Here's the prompt:
---
description: Implement a single phase from plan.md, then verify and record
argument-hint: <phase_number> [plan_path]
---
# Behavior
- Phase number = $1 (required). Plan path = ${2:-plan.md}.
- Read the plan file. Locate the heading: ### Phase $1 —.
- Scope = items under that phase only:
- Implementation checkboxes
- Test Creation checkboxes
- Checks / Validation tasks
- Exit Criteria
- Do not edit other phases or sections. Do not invent new tasks.
# Steps
1) Parse the phase block (from ### Phase $1 — until the next ### heading or section end).
2) Execute all Implementation items exactly as written, making small, reversible changes.
3) Create or extend tests named in Test Creation, covering at least:
- One main happy path
- One representative failure or edge case
4) Run the Checks / Validation commands defined in the phase (for example: test runner, linters, type-checker, build step).
- Fix issues reported by these checks.
- Re-run checks until they are clean, or until a clear blocker is reached.
5) Confirm Exit Criteria is met for Phase $1 only.
# Verification Write-back
Append to the end of the plan file:
## Phase $1 Verification
- Changes made: key files, components, functions, endpoints, commands.
- Tests touched: files and individual test cases.
- Results: check and validation status plus test outcomes.
- Risks and mitigations.
- Follow-ups and next steps.
Then, inside Phase $1:
- Tick completed Implementation, Test Creation, Checks / Validation, and Exit Criteria checkboxes for this phase only.
- Do not tick boxes from other phases.
# Rules
- No out-of-scope edits: do not modify other phases or unrelated files.
- Avoid large refactors unless explicitly requested in the phase.
- No deletions unless explicitly required and safely migrated.
- Keep diffs minimal and focused on the described tasks.
- Avoid adding new TODO or FIXME items unless the plan explicitly calls for tracking follow-ups.
- If something is ambiguous, ask up to 2 concise clarification questions, then proceed with best reasonable assumptions.
- If checks cannot go green, stop and record blockers clearly under "Phase $1 Verification" (including error messages, suspected root causes, and proposed next steps).
# Output
- Code and artifact changes required by Phase $1 tasks.
- Updated ${2:-plan.md} with:
- Phase $1 Verification appended at the end
- Ticked checkboxes for Phase $1 only (Implementation, Test Creation, Checks / Validation, Exit Criteria). When this finishes, you get:
- Code and tests for that phase
- A "Phase N Verification" block appended to
plan.md - Checkboxes ticked only for that phase
Repeat for Phase 2, Phase 3, and so on.