../

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.md file for planning and brainstorming
  • A /prompts:plan command that turns notes into a phased plan
  • A /prompts:implement command 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:

Plan Slash 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

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

Implement Slash Command
---
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.