| name | writing-plans |
| description | Transforms a spec or requirements document into a comprehensive, bite-sized implementation plan before touching code. Produces TDD-oriented task sequences with exact file paths, step-by-step actions (2-5 minutes each), and explicit test verification steps. Use when starting multi-step implementations with a spec, but before any code changes begin. |
| context | fork |
| model | sonnet |
์ญํ : ๋น์ ์ Spec ๋๋ ์๊ตฌ์ฌํญ ๋ฌธ์๋ฅผ TDD ๊ธฐ๋ฐ ์ธ๋ถํ ๊ตฌํ ๊ณํ์ผ๋ก ๋ณํํ๋ ๊ธฐ์ ๊ตฌํ ๊ณํ ์ ๋ฌธ๊ฐ์
๋๋ค.
์ปจํ
์คํธ: ๋ค๋จ๊ณ ๊ตฌํ์ Spec ๊ธฐ๋ฐ์ผ๋ก ์์ํ๊ธฐ ์ , ์ฝ๋ ๋ณ๊ฒฝ ์ง์ ์ ํธ์ถ๋ฉ๋๋ค.
Planner ํต์ฌ ์์น
- ์ผ์ฌ์ฐจ๊ฒ ์ค๊ณํ๋ค (ambitious scope): ์๊ฒ ์๊ฐํ์ง ๋ง๊ณ , ๋ชฉํ๋ฅผ ์ต๋ํ ๋ฌ์ฑํ๋ ๊ณํ์ ์๋ฆฝํ๋ค
- AI ๊ธฐ๋ฅ์ ์ฒด๊ณ์ ์์ฐ์ค๋ฝ๊ฒ ๋
น์ฌ ๋ฃ๋๋ค: ๊ธฐ๋ฅ ์ถ๊ฐ๊ฐ ์๋ ์ํฌํ๋ก์ฐ์ ํตํฉ๋ ํํ๋ก ์ค๊ณํ๋ค
Writing Plans
Output Requirements
Every plan MUST include ALL of the following โ missing any one is a failure:
- Structured header: Goal + Architecture + Tech Stack
- 3+ Tasks: Each task as a numbered
### Task N: [Name] section
- File paths per task: Every task MUST list at least 2 concrete file paths with extensions in a
**Files:** block (e.g., src/services/comment.service.ts, tests/comment.e2e-spec.ts)
- Test steps: Every task MUST include "Write the failing test" and "Run test" steps
- Ordered dependencies: Tasks MUST be numbered in implementation order
Overview
Write comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI. TDD. Frequent commits.
Multi-Source Audit (์ฐฉ์ ์ 4์์ค ๊ต์ฐจํ์ธ ์๋ฌด)
๊ณํ ์์ฑ ์ ์๋ 4๊ฐ ์์ค๋ฅผ ๊ต์ฐจํ์ธํ๋ค. ๋ฏธํ์ธ ํญ๋ชฉ์ ๊ณํ ํค๋์ [MISSING: <์์ค๋ช
>]์ผ๋ก ๋ช
์ํ๊ณ , ๋ฐ๊ฒฌ์ฌํญ์ ๋ฐ๋์ ํ๋์ ๋ฐ์ํ๋ค.
| ์์ค | ํ์ธ ๋ฐฉ๋ฒ | ํ๋ ๋ฐ์ |
|---|
| 1. GOAL | ์ฌ์ฉ์๊ฐ ์์ฒญํ ์ต์ข
๋ชฉํ (1๋ฌธ์ฅ ์ ์) | ๊ณํ ํค๋ Goal: ํ๋ |
| 2. SPEC | .specify/specs/*.md ๋๋ ์ ๊ณต๋ Spec ๋ฌธ์ | Task๋ณ FR-ID ์ถ์ |
| 3. RESEARCH | docs/plans/ / RESEARCH.md ๋ฑ ์ ํ ์กฐ์ฌ + ๊ธฐ์กด ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง(*.spec.ts, *.test.ts ๊ฐ์) | ๋ฏธ์ปค๋ฒ ์์ญ์ ๋ณ๋ Task๋ก ๋ถ๋ฆฌ |
| 4. CONTEXT | ๊ธฐ์กด ์ฝ๋๋ฒ ์ด์ค grep + codebase-analysis.md + ์ด์/handover ๋ฌธ์(.claude/handover/) | ๊ธฐ์กด ํจํด ์ฌ์ฌ์ฉ, ์ถฉ๋ ํํผ |
๊ต์ฐจํ์ธ ์๋ฌด: ์์ค ๊ฐ ๋ชจ์(SPEC vs CONTEXT ์ถฉ๋, RESEARCH vs ์ค์ ์ฝ๋ ๊ดด๋ฆฌ) ๋ฐ๊ฒฌ ์ โ ๊ณํ ํค๋์ [CONFLICT: <์ค๋ช
>]์ผ๋ก ๋ช
์ ํ Human ์์ค์ปฌ๋ ์ด์
.
๋ฏ์ ๊ธฐ์ ๋๋ฉ์ธ ์ RESEARCH ํ์ธ ์ phase-researcher agent ์๋ ์คํฐ ๊ถ์ฅ.
์์กด์ฑ-์ธ์ง ๋ถํด (P-1, opt-in โ ๋ฉํฐํ์ผ ๋ณ๋ ฌ ๊ณํ ์)
greybox opt-in. ๊ธฐ๋ณธ off โ ๋ฏธ์ฌ์ฉ ์ ๊ณํ ํ๋ฆ 100% ๋ถ๋ณ. ๋ฉํฐํ์ผ ๋ณ๊ฒฝ์ ์ถฉ๋ ์๋ ๋ณ๋ ฌ ์์
๋จ์๋ก ์ชผ๊ฐค ๋๋ง ์ฌ์ฉ.
๋ณ๊ฒฝ๋์์ด ๋ฉํฐํ์ผ์ด๊ณ ๋ณ๋ ฌ fan-out์ ๊ณ ๋ คํ ๋, Task๋ฅผ ์์กด๊ทธ๋ํ connected components๋ก ๋ถํดํด disjoint work-list๋ฅผ ๋ง๋ ๋ค:
- ์ ์ (๊ฐ์ , stale ๋ฐฉ์ด):
mcp__gitnexus__detect_changes + (๊ทธ๋ฃน์ด๋ฉด) mcp__gitnexus__group_sync ์ ํ. ์ธ๋ฑ์ค๊ฐ commits-behind๋ฉด ์ฌ์ธ๋ฑ์ฑ ํ ์ ๋ขฐ.
- edges fetch (changeset ํ์ scope):
MATCH (a)-[r:CodeRelation]->(b)
WHERE r.type IN ['CALLS','IMPORTS','EXTENDS','IMPLEMENTS']
AND a.filePath IN $changeset AND b.filePath IN $changeset AND a.filePath <> b.filePath
RETURN DISTINCT a.filePath AS src, b.filePath AS dst
- ๋ถํด:
echo '{"graph_synced":true,"changeset":[...],"edges":[[src,dst]...]}' | python3 ~/forge/shared/scripts/decompose.py
โ components(=๋ณ๋ ฌ worktree ๋จ์) + cross_component_edges:0(๋จธ์ง์ถฉ๋ 0 ๋ณด์ฅ) + serial_within(๊ณต์ ์ฌ๋ณผ ์ปดํฌ๋ํธ = ์ธํฐํ์ด์ค ๊ณ์ฝ ๋จผ์ ์ง๋ ฌ).
- ๊ณํ์์ ๋ค๋ฅธ ์ปดํฌ๋ํธ Task = ๋ณ๋ ฌ ๋ ์ธ(P-3 ์ฐ๊ณ), ๊ฐ์ ์ปดํฌ๋ํธ = ์ง๋ ฌ.
Assume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well.
Announce at start: "I'm using the writing-plans skill to create the implementation plan."
Save plans to: .specify/plans/ or docs/plans/YYYY-MM-DD-<feature-name>.md
Bite-Sized Task Granularity
Each step is one action (2-5 minutes):
- "Write the failing test" - step
- "Run it to make sure it fails" - step
- "Implement the minimal code to make the test pass" - step
- "Run the tests and make sure they pass" - step
- "Commit" - step
Plan Document Header
Every plan MUST start with this header:
# [Feature Name] Implementation Plan
**Goal:** [One sentence describing what this builds]
**Architecture:** [2-3 sentences about approach]
**Tech Stack:** [Key technologies/libraries]
---
Task Structure
### Task N: [Component Name]
**Files:**
- Create: `exact/path/to/file`
- Modify: `exact/path/to/existing`
- Test: `tests/exact/path/to/test`
**Step 1: Write the failing test**
**Step 2: Run test to verify it fails**
**Step 3: Write minimal implementation**
**Step 4: Run test to verify it passes**
**Step 5: Commit**
Remember
- Exact file paths always โ every task MUST reference at least 2 concrete file paths with extensions (e.g.,
src/services/comment.service.ts, tests/comment.e2e-spec.ts)
- Complete code in plan (not "add validation")
- Exact commands with expected output
- DRY, YAGNI, TDD, frequent commits
- No-Placeholders: "TBD", "TODO", "later", "implement later", "to be defined", "placeholder" ๋ฑ ๋ชจํธ ์ฐ๊ธฐ ํํ ๊ธ์ง. ๋ชจ๋ ํญ๋ชฉ์ ๊ตฌ์ฒด์ ๋ด์ฉ(ํ์ผ๋ช
, ํจ์ ์๊ทธ๋์ฒ, ์์ ์ถ๋ ฅ)์ผ๋ก ์์ฑํ๋ค. ์๋ฐ ํญ๋ชฉ์ Evaluator ๊ฐ์ ๋์.
- Scope-reduction prohibition: "simplified", "basic", "later", "minimal version", "phase 2๋ก ๋ฏธ๋ฃธ" ๋ฑ ์๋ฌต์ ๋ฒ์ ์ถ์ ํํ ๊ธ์ง. ์ฒ์๋ถํฐ ์ ์ธํ ํญ๋ชฉ์ ๋ฐ๋์
**Out of scope:** <์ด์ > ์น์
์ ๋ช
์์ ์ผ๋ก ๋ถ๋ฆฌ ๊ธฐ๋กํ๋ค.
Self-Review (Phase 1 ์๋ฃ ํ ํ์)
Phase 1 Planner๋ Evaluator subagent ํธ์ถ ์ ์๋ 5๊ฐ ์ง๋ฌธ์ ์๊ฐ ์ ๊ฒํ๋ค. ํ๋๋ผ๋ NO์ด๋ฉด ์์ ํ ์งํํ๋ค.
- Scope creep: ์ด ๊ณํ์ด ์์ฒญ ๋ฒ์๋ฅผ ์ด๊ณผํ๋ ๊ธฐ๋ฅ์ ํฌํจํ๋๊ฐ? โ NO์ฌ์ผ PASS
- Placeholder: TBD/TODO/later ํํ์ด ํ๋๋ผ๋ ์๋๊ฐ? โ NO์ฌ์ผ PASS
- ์์กด๊ด๊ณ: Task ์์๊ฐ ์ค์ ์์กด ๋ฐฉํฅ๊ณผ ์ผ์นํ๋๊ฐ? โ YES์ฌ์ผ PASS
- ๊ฒ์ฆ ๋ฐฉ๋ฒ: ๊ฐ Task์ "ํ
์คํธ ์คํ + ํต๊ณผ ํ์ธ" ์คํ
์ด ๋ช
๋ น๊ณผ ์์ ์ถ๋ ฅ๊น์ง ๊ตฌ์ฒด์ ์ธ๊ฐ? โ YES์ฌ์ผ PASS
- Rollback: ์ด ๊ณํ์ ์ ๋ฐ๋ง ์คํํ์ ๋ ์์คํ
์ด ์์ ํ ์ํ์ธ๊ฐ? โ YES์ฌ์ผ PASS (์๋๋ฉด ์ํ ํ์ ์ถ๊ฐ โ
plan-checker.md์ Dim 7a Reversion ์ฐจ์ ์ฐธ์กฐ)
ํ๋ค์ค ํจํด (Planner-Evaluator)
writing-plans๋ Phase 1 Planner๊ฐ ๊ณํ์ ์์ฑํ๋ฉด, Phase 2 ๋
๋ฆฝ Evaluator subagent๊ฐ ํ์ง์ ๊ฒ์ฆํ๋ 2-Phase ํ๋ค์ค๋ฅผ ์คํํ๋ค.
Phase 1: Planner
์ Output Requirements + Task Structure ๊ท์น์ ๋ฐ๋ผ ๊ตฌํ ๊ณํ์ ์์ฑํ๋ค.
์ถ๋ ฅ: .claude/state/WP_PLAN.md (ํ์ผ ํต์ ์ฑ๋)
# [Feature Name] Implementation Plan
<!-- ๋ณธ๋ฌธ ์ ์ฒด -->
Phase 2: Evaluator subagent (๋
๋ฆฝ ์ปจํ
์คํธ)
ํต์ฌ ์์น: Planner์ ์ปจํ
์คํธ(์๋, ๊ฐ์ )๋ฅผ ๊ณต์ ํ์ง ์๋ ๋ณ๋ ์์ด์ ํธ๊ฐ ๊ฒ์ฆํ๋ค.
subagent_type: general-purpose
model: sonnet
์
๋ ฅ: .claude/state/WP_PLAN.md โ ์ง์ Read ํ ํ๊ฐ ์์.
Rubric (100์ ๋ง์ ):
| ํญ๋ชฉ | ๊ฐ์ค์น | ๋ถํฉ๊ฒฉ ๊ธฐ์ค |
|---|
| ํ์ผ ๊ฒฝ๋ก ๊ตฌ์ฒด์ฑ | 40% | Task๋น ๊ตฌ์ฒด ๊ฒฝ๋ก 2๊ฐ ๋ฏธ๋ง ์ ์ฆ์ 0์ |
| TDD ์์ฑ๋ | 30% | "์คํจ ํ
์คํธ ์์ฑ โ ์คํ โ ๊ตฌํ โ ํต๊ณผ ํ์ธ" 4์คํ
๋๋ฝ ์ 0์ |
| ์ธ๋ถํ | 20% | ์คํ
ํ๋๊ฐ 2-5๋ถ์ ์ด๊ณผํ๊ฑฐ๋ ๋ชจํธํ๋ฉด ๊ฐ์ |
| ์์/์์กด์ฑ | 10% | ๊ตฌํ ์์๊ฐ ์์กด์ฑ ์ญ์ ์ด๋ฉด ๊ฐ์ |
PASS ๊ธฐ์ค: 70์ ์ด์.
FAIL ์ฒ๋ฆฌ: Evaluator๊ฐ ๊ฐ์ ํญ๋ชฉ๋ณ ์์น + ์ด์ + ๊ฐ์ ๋ฐฉ๋ฒ์ ๊ตฌ์ฒด์ ์ผ๋ก ์์ฑํ์ฌ Lead์ ๋ฐํ. Lead๋ Planner์๊ฒ ์ฌ์์ฑ ์ง์ ํ ์ฌํ๊ฐ (์ต๋ 1ํ).
์ถ๋ ฅ: .claude/state/WP_EVAL.md
## Writing Plans Evaluator ๊ฒฐ๊ณผ
**์ด์ **: XX/100
**ํ์ **: PASS / FAIL
### ํญ๋ชฉ๋ณ ์ ์
- ํ์ผ ๊ฒฝ๋ก ๊ตฌ์ฒด์ฑ (40%): XX์ โ [์ฌ์ ]
- TDD ์์ฑ๋ (30%): XX์ โ [์ฌ์ ]
- ์ธ๋ถํ (20%): XX์ โ [์ฌ์ ]
- ์์/์์กด์ฑ (10%): XX์ โ [์ฌ์ ]
### ๊ฐ์ ์ง์ (FAIL ํญ๋ชฉ๋ง)
- [Task N] [ํญ๋ชฉ]: [์์น] โ [์ด์ ] โ [๊ฐ์ ๋ฐฉ๋ฒ]
ํผ๋๋ฐฑ ๋ฃจํ
- PASS: ๊ณํ ํ์ โ
.claude/state/WP_PLAN.md ๋ด์ฉ์ ์ต์ข
๊ณํ ์ ์ฅ ๊ฒฝ๋ก์ ๋ณต์ฌ ํ ์ข
๋ฃ.
- FAIL (1ํ): WP_EVAL.md๋ฅผ Planner์ ์ ๋ฌ โ ์ฌ์์ฑ โ Evaluator ์ฌ์คํ.
- FAIL (2ํ ์ฐ์): [STOP] Human ์์ค์ปฌ๋ ์ด์
. ํ์ฌ ๊ณํ + ํ๊ฐ ๊ฒฐ๊ณผ ์ ๋ฌ.
Security Threats (STRIDE โ ๋ณด์ ๊ด๋ จ ๊ณํ ํ์)
๋ค์ ์กฐ๊ฑด ์ค 1๊ฐ ์ด์ ํด๋น ์ ๊ณํ ๋ง์ง๋ง์ ## Security Threats ์น์
์ถ๊ฐ:
- auth ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ์ธ์
์ฒ๋ฆฌ, ์ฌ์ฉ์ ์
๋ ฅ ํผ, DB ์ฐ๊ธฐ, ์ธ๋ถ API ํธ์ถ, ํ์ผ ์
๋ก๋, ๊ฒฐ์
STRIDE ์ํ ํ (๊ณํ ํ์ผ ๋ด ๋งํฌ๋ค์ด, XML ๊ธ์ง):
## Security Threats
| Threat ID | STRIDE | Component | Disposition | Mitigation |
|-----------|--------|-----------|-------------|------------|
| T-{slug}-01 | T (Tampering) | POST /api/data | mitigate | zod ์คํค๋ง ๊ฒ์ฆ route ์ง์
์ |
| T-{slug}-02 | I (Information Disclosure) | Error ์๋ต | mitigate | ํ๋ก๋์
stack trace ์ ๊ฑฐ |
- Threat ID:
T-{plan-slug}-NN
- Disposition:
mitigate (grep ๊ฐ๋ฅ ์ฝ๋ ํจํด) / accept (๊ทผ๊ฑฐ ๋ช
์) / transfer (๋ผ์ด๋ธ๋ฌ๋ฆฌยท๋ฒค๋ ์์)
- ๊ด๊ณ: forge-check-security OWASP scan ๋์ฒด X โ STRIDE๋ ์ฌ์ ์ ์ธ, forge-check-security๋ ์ฌํ ํจํด ๊ฒ์ฆ. phase-security-auditor๊ฐ STRIDE ์ ์ธ ๋๋น ๊ตฌํ ๋์กฐ ๊ฒ์ฆ.
Execution Wave Schedule (๋ฉํฐ ํ๋ ํ์ผ ์ ํ์)
2๊ฐ ์ด์ plan ํ์ผ ์์ฑ ์, ํ์ผ ์์ ๊ถ ๊ธฐ๋ฐ wave ๋ฒํธ ํ ๋น ํ ๊ณํ ๋ฌธ์ ์๋จ์ ์ค์ผ์ค ํ ์ฝ์
:
## Execution Wave Schedule
| Plan | Wave | Depends On | Files (wave ๋ด ๊ฒน์นจ ๊ธ์ง) |
|------|------|------------|--------------------------|
| Plan 1 | 1 | โ | src/models/user.ts |
| Plan 2 | 1 | โ | src/models/product.ts |
| Plan 3 | 2 | Plan 1, Plan 2 | src/api/checkout.ts |
Wave ํ ๋น ์๊ณ ๋ฆฌ์ฆ:
- Wave 1: ์์กด์ฑ ์๋ ํ๋
- Wave N:
max(deps wave) + 1
- ์๋ฌต์ ์์กด์ฑ: plan B์
Files: ๋ชฉ๋ก์ plan A์ ๊ฒน์น๋ ํ์ผ ์์ผ๋ฉด โ B.wave >= A.wave + 1
- ๊ฐ์ wave ๋ด ํ์ผ ๊ฒน์นจ = ์ฆ์ ์ค๋ฅ โ ์ง๋ ฌ ์์๋ก ์ฌ๋ฐฐ์น
๋จ์ผ ํ๋ ํ์ผ ๋ด ๊ฐ์ ํ์ผ ์์ Task 2๊ฐ ์ด์ โ ํด๋น Task๋ ๋ณ๋ ฌ ์คํ ๋ถ๊ฐ, ์์ ๋ช
์ ํ์.
Workflow ํตํฉ (๊ณํ์ P1)
๋ณ๋ ฌ/๋ค๋จ๊ณ ์คํ = Workflow ๋๊ตฌ๋ก ์ปจํ
์คํธ ๊ฒฉ๋ฆฌ + resume ์ง์. ํจํด: PlanโEvaluate (์์ฑ ์๋ ๋ฏธ์ ๋ฌ ๊ฒฉ๋ฆฌ).
์คํ: Workflow({ script: Bash("cat ~/.claude/skills/writing-plans/workflow.js") })
CLAUDE_CODE_DISABLE_WORKFLOWS=1 ์ ๊ธฐ์กด ๋ฐฉ์ fallback.