Structured Plans for Agents
-
Most 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 only asked for a small change.
This post walks through how I structure that work using three pieces:
- A detailed
notes.mdfile for thinking and design. - A /prompts:plan command that turns those notes into a phased plan.
- A /prompts:implement command that implements one phase at a time.
Everything here is designed so you can copy the prompts, drop them into your own setup, and start using the same workflow.
Step 1: Write a high-signal notes.md
Before I ever ask the agent to change code, I create a highly detailed notes.md at the root of the project.
What goes into notes.md:
- 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 you are not touching.
- Edge cases: weird inputs, migrations, rollout concerns.
- References: links to docs, tickets, or design specs.
- Sketches: rough API shapes, data structures, and tiny code skeletons.
I’ll often have the agent scan the repo, answer questions, and propose options, but I stay in control of the decisions. notes.md is my single source of truth for what we’re about to build.
The plan command in the next step treats these notes as input and converts them into something an agent can execute safely.
Step 2: Turn notes into a phased plan.md
Once notes.md feels complete enough to build from, I run a slash command that converts it into a structured plan:
— /prompts:plan notes.md
This command:
- Reads the notes file (or other source you point it at).
- Writes a single
./plan.mdfile at the project root. - Overwrites any existing
plan.mdbut touches nothing else. - Produces a summary on top, a phased checklist in the middle, and a final verification section at the bottom.
I use the following prompt for the /prompts:plan command.
---
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 Once this command runs, you have a plan.md with:
- A compressed summary of the notes at the top.
- A phased step plan with checkboxes the agent can tick.
- A final verification section for end-to-end checks.
At this point, you should be able to hand the plan to an agent and ask it to implement one phase at a time.
Step 3: Implement a single phase with /prompts:implement
To actually change code, I use a second command that reads plan.md, focuses on one phase, and does everything required for that phase only.
Usage:
- /prompts:implement 1 → Phase 1 in ./plan.md
- /prompts:implement 2 docs/plan.md → Phase 2 from a custom plan path
Behavior:
- Reads the plan file you point it at.
- Locates the heading for that phase (for example:
### Phase 1 —). - Executes only the tasks in:
- Implementation
- Test Creation
- Checks / Validation
- Exit Criteria
- Leaves all other phases untouched.
Here is the full prompt I use for /prompts:implement:
---
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 command finishes, you get:
- The code and tests required for that phase.
- A “Phase N Verification” block appended to
plan.md. - Checkboxes ticked only for that phase, so you can see progress at a glance.
From here, you can repeat /prompts:implement for Phase 2, Phase 3, and so on, always staying inside the boundaries defined in plan.md.
Why this works (for beginners and pros)
This workflow works well whether you’re just getting started with AI coding tools or you’ve been using them for a while:
- Beginners get a concrete template for thinking through a change before touching code.
- Experienced developers get a repeatable, low-surprise way to delegate precise work to an agent.
- Every change is grounded in a written plan with clear exit criteria.
- Each phase is small and shippable, which keeps diffs readable and rollbacks easy.
You can drop these prompts into your own environment, tweak them for your stack and tooling, and start using structured plans to keep your agents on track.
2024-10-07