Skill v1.0.1
currentAutomated scan100/100+2 new
version: "1.0.1" name: draft-plan description: Use when you have a spec or requirements for a multi-step task, before touching code
Subagent dispatch: Usesubagent_type: "claude-caliper:plan-drafter". The agent definition contains the full planning methodology. The invocation prompt needs only the design doc path, working directory, and plan directory.
Writing Plans
A plan is plan.json — a structured manifest of phases and tasks. Each task carries intent, not code: enough for a fresh Claude, reading the codebase directly at full context, to execute it unambiguously. Plans never paste implementation code and never spawn per-task .md files. plan.md is rendered from plan.json; you don't write it by hand.
Save to: the absolute $PLAN_DIR injected by the dispatcher (resolves to $MAIN_ROOT/.claude/claude-caliper/YYYY-MM-DD-<topic>/ in the main repo, not the worktree). Plans are gitignored but persist across worktree cleanup.
Workflow
- Initialize —
TaskListto check for prior session context - Entry gate —
validate-plan --check-entry $PLAN_DIR/plan.json --stage draft-plan(exits early if design-review hasn't passed; plan.json need not exist yet — only reviews.json is read) - Explore codebase — Understand patterns, find exact file paths. You know the codebase so the implementer's
intentcan be terse and precise. - Decide phasing — Single vs multi-phase (see Phasing below)
- Write plan.json — All task metadata, including
intentandavoid(see Task Structure) - Run validate-plan --schema — Fix any structural errors
- Run validate-plan --render — Generates plan.md deterministically
- Self-review — Re-read every task entry against the Self-Review Gate below. Fix findings before handoff.
- Skip commit — plan artifacts live under
$MAIN_ROOT/.claude/claude-caliper/(gitignored) - Hand off — Report plan path to caller. Plan-review is dispatched by the design skill after draft-plan returns.
Plan Structure
Directory layout:
.claude/claude-caliper/YYYY-MM-DD-topic/├── plan.json # Structured manifest (source of truth)└── plan.md # Generated outline (DO NOT edit)
plan.json is the only artifact you write. plan.md is rendered. Per-phase completion.md files are created later by the orchestrate lead as the reviewer's aggregation point — not by draft-plan.
plan.json shape:
{"schema": 2,"status": "Not Yet Started","workflow": "pr-create","goal": "One sentence","architecture": "2-3 sentences","tech_stack": "Key technologies","phases": [{"letter": "A","name": "Core API","status": "Not Started","depends_on": [],"rationale": "Foundation layer needed first","tasks": [{"id": "A1","name": "Setup route handlers","status": "pending","intent": "Add the HTTP route handlers exposing health and auth endpoints so downstream consumers have a stable surface. Foundation task — nothing else in the phase wires up until these routes return well-formed responses.","depends_on": [],"complexity": "medium","files": { "create": ["src/routes.ts"], "modify": [], "test": ["tests/routes.test.ts"] },"verification": "npx jest tests/routes.test.ts","done_when": "Handler returns 200, 2/2 tests pass","avoid": [{ "rule": "Don't use express", "why": "we're on Hono for edge-runtime compatibility" }]}]}]}
workflow (pr-create | pr-merge | orchestrate | plan-only) is set by the design skill, not chosen here. success_criteria is optional at plan/phase/task levels.
See: schema-reference.md for the full field reference, status lifecycle, and validate-plan modes.
Phasing
Multi-phase when: dependency layers, verification gates, or independent shipping. Single-phase when: tasks are independent. Use A-prefix (A1, A2...).
Gates: 8+ tasks single-phase → look for hidden boundary. 7+ tasks per phase → examine cut points.
Phase boundaries = meaningful "run full suite" points. depends_on (phase level) declares phase ordering. Tasks within a phase execute in parallel — file sets must be disjoint (validate-plan --schema enforces this).
Inherit phases from design doc if approved.
Task Consolidation
Each task carries fixed overhead: worktree creation, subagent dispatch, and its share of the phase review. Trivial tasks (single-line changes, import additions, config updates) don't justify that cost individually. Before finalizing, scan for consolidation:
- Bundle mechanical changes: If multiple files each need small, mechanical edits (renaming an export, adding an import, updating a config value), combine them into one task. A single task can span many files as long as the changes are cohesive and the verification is straightforward.
- Keep substantive tasks separate: Changes requiring design decisions, new logic, or non-trivial testing stay their own task — consolidation is for rote work, not for collapsing genuinely independent features.
- Rule of thumb: If a task's
intentwould be shorter than the rest of its metadata, it's too small — look for neighbors to merge with. - Discipline for consolidated tasks: Mechanical changes don't need per-file red/green cycles. State a single verification pass in
intent(e.g., "run the full test suite and confirm no regressions") rather than step-by-step TDD. The implementer follows whatever the task prescribes.
Task Structure
Every task is a single plan.json entry — no split prose file. The two fields that carry direction:
| Field | Requirement | Good | |
|---|---|---|---|
| intent | 2–4 sentences: what to build and why. Names the component and its behavior; states how it fits the phase. No pasted code. | "Add JWT validation middleware that rejects expired/invalid tokens before the handler runs, so protected routes can trust req.user. Consumed by every task in Phase B." | |
| avoid | Array of {rule, why} — each pitfall with its reason | {"rule": "Use jose not jsonwebtoken", "why": "jsonwebtoken has CJS/Edge issues on the target runtime"} | |
| files | Exact paths (create/modify/test) | {"create": ["src/auth/login.ts"], "test": ["tests/auth/login.test.ts"]} | |
| verification | Runnable command, <60s | pytest tests/auth/ -v | |
| done_when | Measurable end state | login returns JWT, 4/4 tests pass | |
| depends_on | Task IDs this consumes | ["A1"] (same phase for ordering, prior phase for cross-phase deps) | |
| complexity | Enum: low, medium, high | "medium" |
The implementer reads the codebase directly, so intent states the outcome and seams — not line-by-line code.
Interface-first ordering: Define contracts first, implement in middle tasks, wire consumers last.
Integration tests for cross-task seams: When the design's ## Test Strategy section names a seam (producer module → consumer module), the plan must include at least one task whose done_when exercises that seam end-to-end with no mock at the seam under test. The Test Strategy section is the trigger — the seams it names map 1:1 to integration tasks. Multi-phase plans and plans with cross-task depends_on are where seams typically exist, but the design doc, not the plan structure, is the source of truth.
Placement rules — same-phase vs cross-phase seams:
- Same-phase seam (producer and consumer in the same phase, or single-phase plan): place as the phase's A1 task using double-loop TDD (broad tests stay RED until the last piece lands).
- Cross-phase seam (Phase A producer → Phase B consumer): place as the final task of the consumer's phase (B-last), not A1. The A1 placement would make Phase A's impl-review fail because the consumer code doesn't exist yet when Phase A wraps up.
Either placement works as long as the seam is exercised without mocking the producer. Each integration task's done_when should name the seam explicitly: "kv_launcher → kv_fetch seam runs end-to-end with real subprocess spawn, 1/1 test passes" — not just "integration tests pass". The named seam links the task back to design's Test Strategy and lets plan-review verify the contract.
Handoff notes: When a task depends on a prior phase's task, the orchestrate lead records the shipped-interface note into plan.json via validate-plan --add-handoff at the source phase's wrap-up (post-review, so it reflects the real interface). Draft-plan doesn't write these — just declare the depends_on.
Self-Review Gate
Before handoff, re-read every task entry and the plan.json. The plan-reviewer downstream applies a checklist; catch these items here so review is pass/fail, not an editing pass. Goal at handoff: zero or one remaining issues.
Per task:
- Different Claude Test — Could a fresh Claude with only this entry and codebase access execute it unambiguously? No "the handler" or "the config" without a file path;
intentnames the component and its behavior. - Measurable `done_when` — "4/4 tests pass" or "endpoint returns 200", not "auth works" or "feature complete".
- Intent is outcome, not code — Describes what and why and the seams; no pasted implementation.
- Avoid + WHY — Every
avoidentry gives the reason, not just the prohibition. - Artifact consistency — Same file/function names across
intent,files,avoid, anddone_when. Every path referenced exists infiles. - Verification is runnable — The command matches this codebase's tooling (npm vs yarn vs pnpm, pytest vs unittest).
Across the plan:
- Design criteria map to tasks — Each success criterion from the design doc is covered by at least one task's
done_when. Missing criterion → add a task. - Test Strategy seams map to integration tasks — Every seam in the design's
## Test Strategymaps to a task whosedone_whennames the seam and the non-mocking constraint. - Consolidation sweep — Any task whose
intentis shorter than the rest of its metadata should merge with a neighbor. - Complexity gates — 8+ tasks single-phase or 7+ per phase → split.
- Interface-first ordering — Tasks defining contracts precede tasks consuming them.