Overview
Break work down into small, verifiable tasks, and write acceptance criteria for each task. Good task decomposition is the difference between an agent that reliably completes work and an agent that produces a tangled, chaotic result. Each task should be small enough to be implemented, tested, and verified in a single focused session.
When to use
- You already have a spec and need to break it into implementable units
- A task feels too large or too vague to start
- The work needs to be parallelized across multiple agents or sessions
- You need to communicate scope to humans
- The implementation order is not obvious
When not to use: A single-file change with obvious scope, or a spec that already contains well-defined tasks.
Planning process
Step 1: Enter Plan Mode
Before writing any code, run in read-only mode:
- Read the spec and relevant areas of the codebase
- Identify existing patterns and conventions
- Map dependencies between components
- Record risks and unknowns
Do not write code during planning. The output is a plan document saved to tasks/plan.md , plus a task list recorded in the task list target (see the "Output Files" section; default tasks/todo.md), not an implementation.
Step 2: Identify the dependency graph
Map what depends on what:
Database schema
│
├── API models/types
│ │
│ ├── API endpoints
│ │ │
│ │ └── Frontend API client
│ │ │
│ │ └── UI components
│ │
│ └── Validation logic
│
└── Seed data / migrations
Implementation order follows the dependency graph bottom-up: build the foundations first.
Step 3: Vertical slices
Do not build all the database first, then all the API, then all the UI. Build one complete functional path at a time:
Bad example (horizontal slices):
Task 1: Build entire database schema
Task 2: Build all API endpoints
Task 3: Build all UI components
Task 4: Connect everything
Good example (vertical slices):
Task 1: User can create an account (schema + API + UI for registration)
Task 2: User can log in (auth schema + API + UI for login)
Task 3: User can create a task (task schema + API + UI for creation)
Task 4: User can view task list (query + API + UI for list view)
Each vertical slice delivers working, testable functionality.
Step 4: Write the tasks
Each task follows this structure, whether it lives in a markdown task list or as an entry in an external tracker (see Output Files):
## Task [N]: [Short descriptive title]
**Description:** One paragraph explaining what this task accomplishes.
**Acceptance criteria:**
- [ ] [Specific, testable condition]
- [ ] [Specific, testable condition]
**Verification:**
- [ ] Tests pass: [the repository's focused-test command]
- [ ] Build succeeds: [the repository's build command]
- [ ] Manual check: [description of what to verify]
**Dependencies:** [Task numbers this depends on, or "None"]
**Files likely touched:**
- `src/path/to/file.ts`
- `tests/path/to/test.ts`
**Estimated scope:** [Small: 1-2 files | Medium: 3-5 files | Large: 5+ files]
Step 5: Order and set checkpoints
When arranging tasks, ensure that:
- Dependencies are satisfied (build the foundations first)
- The system is still in a working state at the end of each task
- Verification checkpoints appear after every 2-3 tasks
- High-risk tasks come first (fail fast)
Add explicit checkpoints in the task list target:
## Checkpoint: After Tasks 1-3
- [ ] All tests pass
- [ ] Application builds without errors
- [ ] Core user flow works end-to-end
- [ ] Review with human before proceeding
Task size guidelines
| Size | Number of files | Scope | Example |
|---|---|---|---|
| XS | 1 | A single function or configuration change | Add a validation rule |
| S | 1-2 | One component or endpoint | Add a new API endpoint |
| M | 3-5 | One feature slice | User registration flow |
| L | 5-8 | Multi-component feature | Search with filtering and pagination |
| XL | 8+ | Too large, needs further decomposition | — |
If a task is L or larger, it should be split into smaller tasks. Agents perform best on S and M tasks.
When to split a task further:
- It will exceed one focus session (about 2+ hours of agent work)
- You cannot describe the acceptance criteria in 3 bullets or fewer
- It touches two or more independent subsystems (e.g., auth and billing)
- You find yourself writing “and” in the task title (this usually means it is two tasks)
Output files
- Plan document: Save the implementation plan to
tasks/plan.md. This is always a markdown file—design decisions, risks, and open questions cannot map cleanly onto a single tracker issue. - Task list: Record each task in task list target(defined below).
If tasks/ directory does not exist, create it.
Never overwrite an unfinished plan. Before writing tasks/plan.md or tasks/todo.md , check whether they already exist and still contain unchecked tasks:
- Replanning the same work (the user asks to revise or extend this plan) → update the existing file in place.
- Different work → stop and ask. Unchecked tasks may be being built in another session. Do not delete, overwrite, or rename existing files on your own; present the conflict and let the user decide (finish the old plan first, explicitly discard it, or tell you where the new plan should go).
The same rules apply to an external task list target: never bulk-close or delete unclosed tracker items from other plans just to make room for new tasks.
Task list storage location (task list target)
The Task list target is the location where tasks and checkpoints are recorded. Its definition appears only once, here; all other references in this skill are based on this.
- Default: a checklist-style markdown file located at
tasks/todo.md. This is the/buildconvention expected by the command and other downstream tools. Use it unless the project says otherwise. - External tracker: If the project's agent rules (
CLAUDE.md、AGENTS.mdetc.) or the user specifies an issue tracker (e.g., GitHub Issues, Jira, Linear,bd/beads), create a tracker item for each task instead of writingtasks/todo.md. Map the structure from step 4 to the tracker's fields: put acceptance criteria and verification steps in the item body, and express dependencies through the tracker's linking mechanism (bd dep add, “blocked by”, etc.). The checkpoints from step 5 are also recorded as tracker items; if the tracker has no natural counterpart, record them as a checklist in the plan document.
When using an external tracker, note it in tasks/plan.md (e.g., “Tasks tracked in Linear project FOO”), so that downstream steps and future sessions know where to look; and keep the Task List section of the plan document as an ordered index of tracker item IDs or links, rather than a duplicate checklist.
Plan document template
# Implementation Plan: [Feature/Project Name]
## Overview
[One paragraph summary of what we're building]
## Architecture Decisions
- [Key decision 1 and rationale]
- [Key decision 2 and rationale]
## Task List
### Phase 1: Foundation
- [ ] Task 1: ...
- [ ] Task 2: ...
### Checkpoint: Foundation
- [ ] Tests pass, builds clean
### Phase 2: Core Features
- [ ] Task 3: ...
- [ ] Task 4: ...
### Checkpoint: Core Features
- [ ] End-to-end flow works
### Phase 3: Polish
- [ ] Task 5: ...
- [ ] Task 6: ...
### Checkpoint: Complete
- [ ] All acceptance criteria met
- [ ] Ready for review
## Risks and Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| [Risk] | [High/Med/Low] | [Strategy] |
## Open Questions
- [Question needing human input]
When tasks are stored in an external tracker, keep the Task List section above as an ordered index of tracker item IDs or links, rather than a duplicate checklist.
Parallelization opportunities
When multiple agents or sessions are available:
- Can safely run in parallel: independent feature slices, tests for already-implemented features, documentation
- Must run sequentially: Database migrations, shared state changes, dependency chains
- Needs coordination: Features of a shared API contract (define the contract first, then parallelize)
Common rationalization excuses
| Rationalization excuse | Reality |
|---|---|
| "I'll figure it out as I go" | This gets you tangled messes and rework. 10 minutes of planning saves hours. |
| "The task is obvious" | Write it down anyway. Explicit tasks expose hidden dependencies and forgotten edge cases. |
| "Planning is extra overhead" | Planning is the task. Implementation without a plan is just typing. |
| "I can keep it all in my head" | The context window is limited. A written plan survives session boundaries and compaction. |
"The old tasks/plan.md is outdated, I'll just replace it" |
Unchecked tasks may be being built in another session. Overwriting them destroys state that exists only there. Stop and ask. |
Red flags
- Starting implementation without a written task list
- Overwriting a
tasks/plan.mdortasks/todo.md - that still contains unchecked tasks for different work without asking
tasks/todo.md(or scattering tasks in two places) when the project has already designated an external tracker - Tasks that only say "implement the feature" with no acceptance criteria
- No verification steps in the plan
- All tasks are XL-sized
- No checkpoints between tasks
- Dependency order not considered
Verification
Before starting implementation, confirm:
- Every task has acceptance criteria
- Every task has verification steps
- Task dependencies are identified and correctly ordered
- Tasks are recorded in the task list target (default
tasks/todo.md) - No existing unfinished plan was overwritten without explicit user confirmation
- No task touches more than about 5 files
- There are checkpoints between major phases
- A human has reviewed and approved the plan
See also
Acceptance criteria are one per task and answer "are we building the right thing?". They layer on top of the project-level Definition of Done—the standing standard every task must cross before it counts as complete. See ../../references/definition-of-done.md。