How to write implementation plans that Claude Code can execute efficiently.
Written by Claude Code Opus 4.5
Focus over length. The problem isn't token count — it's domain bleeding. When a primitives doc mentions rendering, Claude starts thinking about rendering, which expands context. Keep each document in its lane.
Signatures, not implementations. Type definitions and method signatures tell Claude what to build. Full implementations tell Claude what you already built. Let the agent write the code.
Clear prompts for handoff. Each task file should work as a standalone prompt. "Read 01-primitives.md and proceed" should be enough.
docs/agents/plans/{feature}/
├── README.md # Activation, tracking, architecture
├── DETAIL.md # Design rationale (read during revisions)
├── 01-first.md # Task 1
├── 02-second.md # Task 2
└── ...
| Document | Purpose | When to Read |
|---|---|---|
| README.md | Orient, track progress, see architecture | Every session |
| DETAIL.md | Understand why decisions were made | Revision sessions |
| NN-task.md | Execute one implementation task | Implementing that module |
# Feature Name
**Location:** `crates/feature`
**Status:** Design Complete | In Progress | Complete
---
## Progress Tracking
| Task | Status | Parallel Group | Notes |
|------|--------|----------------|-------|
| 01-primitives | pending | A | No dependencies |
| 02-types | pending | A | No dependencies |
| 03-core | pending | B | Depends on 01, 02 |
## Success Metrics
- [ ] All tests pass
- [ ] Feature works end-to-end
- [ ] No new warnings
## Execution Flow
\`\`\`mermaid
graph TD
subgraph A[Group A - parallel]
A1[01-primitives]
A2[02-types]
end
subgraph B[Group B]
B1[03-core]
end
A1 --> B1
A2 --> B1
\`\`\`
## Agent Dispatch
### Group A (2 agents, parallel)
\`\`\`
Agent 1: "Read 01-primitives.md and implement."
Agent 2: "Read 02-types.md and implement."
\`\`\`
### Output Format
When complete, report:
- Files modified (paths)
- Tests added/passing
- Blockers or follow-up discovered
- Key context the orchestrator should know
## Documents
| Document | Focus | Read When |
|----------|-------|-----------|
| [01-primitives.md](./01-primitives.md) | Core types | Implementing primitives |
| [02-types.md](./02-types.md) | Type definitions | Implementing types |
## Open Questions
- [ ] Unresolved design question?# Feature Design Rationale
**Purpose:** Deep context for revision sessions. Read when you need to understand *why*.
---
## Why [Key Decision 1]?
[Explanation of the decision, alternatives considered, trade-offs]
## Why [Key Decision 2]?
[...]
## Cross-Cutting Concerns
### [Concern 1]
[How this affects multiple modules]
### [Concern 2]
[...]
## Open Questions
| Question | Context | Status |
|----------|---------|--------|
| - | - | - |
## Rejected Alternatives
| Alternative | Why Rejected |
|-------------|--------------|
| X | Caused Y problem |Target: Unlimited — only read during deep revision sessions
# NN: Task Name
**File:** `src/module.rs`
**Focus:** [One domain only]
**Dependencies:** 01-other-task, 02-another-task
**Unblocks:** 04-dependent-task
---
## Task
[Clear instruction: what to create, what file(s) to write]
**Why this first?** [Explain ordering rationale — what this enables, what depends on it]
**Deliverables:**
1. [Specific file with specific contents]
2. [Specific functionality working]
3. [Specific tests passing]
**Definition of Done:**
```bash
cargo fmt --check
cargo clippy -- -D warnings
cargo check
cargo test- ❌ [Adjacent work] — that's task NN
- ❌ [Other adjacent work] — that's task MM
Focus ONLY on [this domain].
// Key API usage the agent needs to know
use external_crate::Thing;
let x = Thing::new();#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MyType {
pub field: Type,
}
pub enum MyEnum {
Variant1,
Variant2 { data: String },
}
pub trait MyTrait: Send + Sync {
fn method(&self, arg: Type) -> Result<Output>;
}Construction:
new(...) -> Selffrom_x(...) -> Self
Core:
do_thing(&self, ...) -> Result<...>other_thing(&mut self, ...)
Queries:
get_x(&self) -> &Xfind_by_y(&self, y: Y) -> Option<&Z>
- Types compile with derives as shown
- [Specific behavior] works correctly
- Tests cover [specific scenarios]
- [Edge case] handled
**Target: 100-200 lines**
---
## What Goes Where
| Content | Location | Example |
|---------|----------|---------|
| Type definitions | Task file | `pub struct Foo { ... }` |
| Trait definitions | Task file | `pub trait Bar { ... }` |
| Method signatures | Task file | `fn baz(&self) -> Result<X>` |
| Method bodies | Nowhere | Agent writes these |
| External crate patterns | Task file | `toposort(&graph, None)` |
| Design rationale | DETAIL.md | "We chose X because Y" |
| Rejected alternatives | DETAIL.md | "We didn't use Z because..." |
| Cross-cutting concerns | DETAIL.md | "Error handling affects all modules" |
| Progress tracking | README.md | Status table with parallel groups |
| Execution flow | README.md | Mermaid DAG |
---
## Focus Rules
### One Domain Per File
Each task file owns one domain. If you find yourself explaining another domain to make sense of this one, stop — you're bleeding.
**Good:** "Takes a `Graph` as input"
**Bad:** "Traverses the petgraph StableGraph using neighbors_directed..."
### Scope Boundaries
Every task file needs a "Do not" section:
```markdown
**Do not** implement buffer management — that's task 04.
**Do not** implement actual MCP calls — use dependency injection.
When task 04 depends on task 01's types:
**Dependencies:** 01-primitivesDon't re-explain the types. The agent can read the dependency's task file if needed.
Use Exa or web search to find key patterns for dependencies, then embed them in task files:
// petgraph: topological sort
use petgraph::algo::toposort;
let order: Result<Vec<NodeIndex>, _> = toposort(&graph, None);
// trustfall: adapter trait
pub trait Adapter<'vertex> {
fn resolve_starting_vertices(...) -> VertexIterator<...>;
fn resolve_property(...) -> ContextOutcomeIterator<...>;
fn resolve_neighbors(...) -> ContextOutcomeIterator<...>;
fn resolve_coercion(...) -> ContextOutcomeIterator<...>;
}This saves agents from searching and keeps them focused.
Every task file must include:
**Definition of Done:**
```bash
cargo fmt --check
cargo clippy -- -D warnings
cargo check
cargo test
For feature-gated code, add both paths:
```bash
cargo check
cargo check --features feature_name
Use checkboxes for functional requirements:
## Acceptance Criteria
- [ ] `new()` creates valid instance
- [ ] Serialization round-trips correctly
- [ ] Error case returns `Err`, not panic
- [ ] Edge case X handledThese are what must work. Definition of Done is how to verify the code is ready.
Plans should enable a coordinating agent to dispatch parallel workers and synthesize results efficiently.
Use Mermaid in README.md to visualize the execution DAG:
## Execution Flow
\`\`\`mermaid
graph TD
subgraph A[Group A]
A1[01-primitives]
A2[02-types]
A3[03-helpers]
end
subgraph B[Group B]
B1[04-core]
B2[05-io]
end
subgraph C[Group C]
C1[06-integration]
end
A1 --> B1
A2 --> B1
A2 --> B2
A3 --> B2
B1 --> C1
B2 --> C1
\`\`\`Mermaid is parseable by future agents, renders on GitHub, and makes dependencies explicit.
Each task file declares what it needs and what it unblocks:
**Dependencies:** 01-primitives, 02-types
**Unblocks:** 05-io, 06-integrationInclude ready-to-use prompts in README.md:
## Agent Dispatch
### Group A (3 agents, parallel)
\`\`\`
Agent 1: "Read 01-primitives.md and implement."
Agent 2: "Read 02-types.md and implement."
Agent 3: "Read 03-helpers.md and implement."
\`\`\`Instruct workers on efficient reporting. The orchestrator synthesizes multiple outputs — structured reports reduce overhead.
Add to agent prompts:
When complete, report:
- Files modified (paths)
- Tests added/passing
- Blockers or follow-up discovered
- Key context the orchestrator should know
Give workers everything they need to work confidently:
- Full type signatures and examples
- Links to related files
- Design rationale where helpful
Asking clarifying questions saves everyone time. Don't guess — ask.
Subagents can ask you questions directly via AskUserQuestion. Your answers go to their context, not the orchestrator's. This means:
- You can make decisions at implementation time
- Clarifications stay with the worker who needs them
- The orchestrator stays lean — just dispatching and synthesizing
Good reasons to ask:
- Multiple valid approaches — which do you prefer?
- Ambiguous requirement — what's the actual intent?
- Discovered complexity — should we simplify scope?
- Found related issues — fix now or note for later?
A 30-second question beats a 30-minute wrong implementation.
README.md:
- Progress tracking table with parallel groups
- Mermaid execution DAG
- Agent dispatch prompts
- Success metrics (checkboxes)
- Open questions (checkboxes)
DETAIL.md:
- Explains why for key decisions
- Documents rejected alternatives
Task Files:
- Dependencies and Unblocks declared
- Task section with clear prompt
- Definition of Done (fmt/clippy/check/test)
- Acceptance Criteria checkboxes
- Rich context (types, examples, rationale)
Overall:
- No full implementations anywhere
- No domain bleeding between task files