Back to posts

Superpowers - planning & execution

설계서에서 동작하는 코드까지 — 계획 수립, worktree 격리, 서브에이전트 실행의 내부 구조를 추적한다.


들어가며: 승인된 설계서, 그 다음은?

brainstorming 스킬이 이중 승인 게이트를 통과해 설계서를 만들어냈다. "검색 기능 만들자"라는 한 마디가 요구사항 정리, 접근법 비교, 설계 문서화를 거쳐 docs/superpowers/specs/2026-04-11-search-design.md로 확정되었다. digraph의 터미널 노드 "Invoke writing-plans skill"이 발동된다.

이제부터 다섯 개의 스킬이 연쇄적으로 관여한다. writing-plans가 계획서를 쓰고, using-git-worktrees가 격리된 작업 공간을 만들고, executing-plans 또는 subagent-driven-development가 실행을 담당하며, dispatching-parallel-agents가 독립된 작업을 동시에 처리한다. 이 글은 설계서에서 동작하는 코드가 나오기까지의 전체 실행 파이프라인을 추적한다.


1. writing-plans의 No Placeholders 철학

실행자에게 판단을 요구하지 않는 계획서

writing-plans 스킬의 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.

"zero context", "questionable taste" — 계획서를 읽는 사람(또는 서브에이전트)이 코드베이스를 전혀 모르고, 좋은 설계 감각도 없다고 가정한다. 이 가정은 과장이 아니라 안전 장치다. 서브에이전트는 실제로 fresh context로 디스패치되기 때문에 프로젝트 이력을 모른다. 계획서가 맥락을 완전히 제공하지 않으면, 서브에이전트는 추측하거나 질문을 던져야 하고, 둘 다 실행 속도를 떨어뜨린다.

No Placeholders: 금지된 패턴 목록

이 가정에서 직접 도출되는 규칙이 No Placeholders다.

Every step must contain the actual content an engineer needs. These are plan
failures — never write them:
- "TBD", "TODO", "implement later", "fill in details"
- "Add appropriate error handling" / "add validation" / "handle edge cases"
- "Write tests for the above" (without actual test code)
- "Similar to Task N" (repeat the code — the engineer may be reading tasks
  out of order)
- Steps that describe what to do without showing how (code blocks required
  for code steps)
- References to types, functions, or methods not defined in any task

각 금지 패턴의 설계 의도를 분석한다.

"TBD", "TODO", "implement later" — 계획서에 빈 칸이 있으면 실행자가 그 빈 칸을 채우기 위해 추가 판단을 해야 한다. 판단을 하려면 맥락이 필요하고, 맥락이 없으면 틀린 판단을 한다.

"Add appropriate error handling" — "appropriate"가 문제다. 무엇이 적절한지는 계획서를 쓴 시점에 이미 결정되어야 한다. 실행자에게 "적절한"을 판단하라고 넘기는 것은 설계 결정을 실행 단계로 미루는 것이다.

"Similar to Task N" — 실행자가 Task를 순서대로 읽는다는 보장이 없다. 서브에이전트는 자신에게 할당된 Task만 받는다. Task 5에서 "Similar to Task 2"라고 쓰면, Task 5를 담당하는 서브에이전트는 Task 2를 볼 수 없다.

"Steps that describe what to do without showing how" — 코드 단계에는 코드 블록이 필수다. "검색 API 엔드포인트를 작성한다" 대신, 실제 함수 시그니처와 구현 코드가 있어야 한다.

Bite-Sized Task Granularity: 2-5분 단위의 이유

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

왜 2-5분인가? 두 가지 이유가 있다.

첫째, 실패 시 롤백 범위 축소. 30분짜리 작업이 실패하면 30분을 잃는다. 3분짜리 작업이 실패하면 3분을 잃는다. 각 step이 독립된 검증 포인트를 가지므로("Run it to make sure it fails", "Run the tests and make sure they pass"), 실패 지점을 정확히 특정할 수 있다.

둘째, 진행 추적. 체크박스 문법(- [ ])으로 각 step의 완료 여부를 추적한다. 계획서의 Task 구조가 이를 보여준다:

### Task N: [Component Name]
 
**Files:**
- Create: `exact/path/to/file.py`
- Modify: `exact/path/to/existing.py:123-145`
- Test: `tests/exact/path/to/test.py`
 
- [ ] **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**

파일 경로가 정확하고, 수정할 기존 파일의 줄 번호까지 명시된다. 실행자가 "어디를 고쳐야 하지?"라고 고민할 여지가 없다.


2. 실행 갈림길 — inline vs subagent-driven

Execution Handoff

writing-plans가 계획서를 완성하면, 실행 방식을 선택하는 분기가 온다. 원문의 Execution Handoff 섹션:

After saving the plan, offer execution choice:

"Plan complete and saved to docs/superpowers/plans/<filename>.md.
Two execution options:

1. Subagent-Driven (recommended) - I dispatch a fresh subagent per task,
   review between tasks, fast iteration

2. Inline Execution - Execute tasks in this session using executing-plans,
   batch execution with checkpoints

Which approach?"

두 경로의 차이를 분석한다.

경로 1: executing-plans (inline execution)

executing-plans는 별도 세션(주로 worktree)에서 계획서를 로드하고 순차적으로 Task를 실행한다. 하나의 세션에서 모든 Task를 처리하므로 컨텍스트가 누적된다. 핵심 규칙은 계획서를 비판적으로 리뷰하고, 문제가 있으면 실행 전에 제기하는 것이다.

1. Read plan file
2. Review critically - identify any questions or concerns about the plan
3. If concerns: Raise them with your human partner before starting
4. If no concerns: Create TodoWrite and proceed

"Review critically" — 실행자가 계획서를 맹목적으로 따르지 않는다. 계획서에 빈틈이 있으면 실행 전에 질문한다. 이것은 writing-plans의 Self-Review와 다른 관점에서의 검토다. writing-plans는 작성자가 자신의 계획을 검토하고, executing-plans는 실행자가 다른 사람의 계획을 검토한다.

executing-plans의 블로킹 규칙도 있다:

STOP executing immediately when:
- Hit a blocker (missing dependency, test fails, instruction unclear)
- Plan has critical gaps preventing starting
- You don't understand an instruction
- Verification fails repeatedly

Ask for clarification rather than guessing.

"Ask for clarification rather than guessing" — 추측하지 않는다. 불명확한 지시를 만나면 멈추고 질문한다. 이것이 No Placeholders 규칙과 짝을 이룬다. 계획서에 placeholder가 없어야 실행자가 멈출 일이 줄어들고, 그래도 멈춰야 할 때는 반드시 멈춘다.

경로 2: subagent-driven-development

subagent-driven-development는 Task마다 새로운 서브에이전트를 디스패치한다. 원문이 핵심 원칙을 한 문장으로 정의한다:

Fresh subagent per task + two-stage review (spec then quality)
= high quality, fast iteration

executing-plans와의 차이를 정리하면:

항목executing-planssubagent-driven
세션별도 세션같은 세션
컨텍스트세션 전체 컨텍스트 누적Task마다 fresh context
리뷰체크포인트 기반2-stage review (자동)
진행사용자 개입 필요연속 진행

subagent-driven이 recommended인 이유는 컨텍스트 오염 방지에 있다. executing-plans에서 10개의 Task를 순차 실행하면, Task 10을 실행할 때 Task 1-9의 컨텍스트가 누적되어 있다. 이 누적된 컨텍스트가 Task 10의 실행에 간섭할 수 있다. subagent-driven에서는 각 서브에이전트가 자기 Task에 필요한 정보만 받으므로 이 문제가 없다.

원문의 "Why subagents" 섹션:

You delegate tasks to specialized agents with isolated context. By precisely
crafting their instructions and context, you ensure they stay focused and
succeed at their task. They should never inherit your session's context or
history — you construct exactly what they need.

"They should never inherit your session's context or history" — 서브에이전트는 세션 이력을 상속하지 않는다. 컨트롤러가 필요한 맥락을 직접 구성해서 전달한다. 이것이 No Placeholders 규칙과 다시 연결된다. 계획서에 placeholder가 없으므로, 컨트롤러가 Task의 전체 텍스트를 그대로 전달하면 서브에이전트가 추가 정보 없이 실행할 수 있다.


3. subagent-driven-development의 2-stage review

프로세스 전체 흐름

subagent-driven-development의 per-task 프로세스를 요약하면:

  1. 컨트롤러가 implementer 서브에이전트를 디스패치한다
  2. implementer가 질문이 있으면 질문하고, 없으면 구현한다
  3. implementer가 완료되면 spec reviewer 서브에이전트를 디스패치한다
  4. spec reviewer가 통과하면 code quality reviewer 서브에이전트를 디스패치한다
  5. 두 리뷰 모두 통과하면 Task 완료

Spec Reviewer: 신뢰하지 않는 리뷰어

spec reviewer의 프롬프트 템플릿에 있는 지시가 인상적이다:

CRITICAL: Do Not Trust the Report

The implementer finished suspiciously quickly. Their report may be incomplete,
inaccurate, or optimistic. You MUST verify everything independently.

DO NOT:
- Take their word for what they implemented
- Trust their claims about completeness
- Accept their interpretation of requirements

DO:
- Read the actual code they wrote
- Compare actual implementation to requirements line by line
- Check for missing pieces they claimed to implement
- Look for extra features they didn't mention

"The implementer finished suspiciously quickly" — 리뷰어에게 implementer를 불신하도록 프라이밍한다. 이것은 인격적 불신이 아니라 구조적 장치다. 리뷰어가 implementer의 보고서를 신뢰하면, 보고서만 읽고 코드를 안 읽는 지름길을 택할 수 있다. "Verify by reading code, not by trusting report" — 코드를 직접 읽고, 요구사항과 한 줄씩 대조한다.

spec reviewer가 확인하는 세 가지 축:

  • Missing requirements — 빠진 요구사항이 있는가
  • Extra/unneeded work — 요청하지 않은 것을 만들었는가
  • Misunderstandings — 요구사항을 잘못 해석했는가

이 세 축은 스펙 준수의 정의를 완전히 덮는다. 부족하면 안 되고, 과하면 안 되고, 방향이 틀리면 안 된다.

왜 2단계로 분리했는가

spec compliance와 code quality는 독립적인 관심사다.

  • 스펙에 맞게 만들었지만 코드가 지저분할 수 있다 (spec pass, quality fail)
  • 코드가 깨끗하지만 요구사항을 빠뜨렸을 수 있다 (spec fail, quality pass)

이 두 가지를 하나의 리뷰에서 동시에 보면, 리뷰어가 한쪽에 치우칠 수 있다. 코드 품질이 좋아 보이면 스펙 누락을 놓치거나, 스펙이 맞는 것을 확인하고 나면 코드 품질 검토를 대충 할 수 있다. 2단계로 분리하면 각 리뷰어가 자기 관심사에만 집중한다.

순서도 중요하다. 원문의 Red Flags 섹션:

Start code quality review before spec compliance is ✅ (wrong order)

spec compliance가 먼저 통과해야 한다. 스펙에 안 맞는 코드의 품질을 리뷰하는 것은 무의미하다. 잘못 만든 코드가 아무리 깨끗해도 다시 써야 한다.

Implementer Status: 네 가지 상태

implementer 서브에이전트는 네 가지 상태 중 하나를 보고한다.

DONE: Proceed to spec compliance review.

DONE_WITH_CONCERNS: The implementer completed the work but flagged doubts.
Read the concerns before proceeding. If the concerns are about correctness
or scope, address them before review. If they're observations (e.g.,
"this file is getting large"), note them and proceed to review.

NEEDS_CONTEXT: The implementer needs information that wasn't provided.
Provide the missing context and re-dispatch.

BLOCKED: The implementer cannot complete the task. Assess the blocker:
1. If it's a context problem, provide more context and re-dispatch
   with the same model
2. If the task requires more reasoning, re-dispatch with a more
   capable model
3. If the task is too large, break it into smaller pieces
4. If the plan itself is wrong, escalate to the human

DONE — 정상 완료. spec review로 진행한다.

DONE_WITH_CONCERNS — 완료했지만 의구심이 있다. 이 상태가 존재하는 이유는 implementer에게 "완벽하지 않아도 보고해도 된다"는 안전망을 주기 위해서다. DONE만 있으면 implementer는 의구심이 있어도 DONE으로 보고하고, 문제가 리뷰 단계에서 발견된다. DONE_WITH_CONCERNS가 있으면 우려 사항이 리뷰 전에 표면화된다.

NEEDS_CONTEXT — 정보가 부족하다. 컨트롤러가 추가 맥락을 제공하고 다시 디스패치한다.

BLOCKED — 완료할 수 없다. 원문의 대응 전략이 단계적이다. 맥락 문제면 맥락을 더 주고, 추론 능력 문제면 더 강력한 모델로 바꾸고, 크기 문제면 쪼개고, 계획 자체의 문제면 사용자에게 올린다. 특히 마지막 규칙이 중요하다:

Never ignore an escalation or force the same model to retry without changes.
If the implementer said it's stuck, something needs to change.

같은 모델에게 같은 조건으로 재시도시키지 않는다. 막혔다고 보고했으면 무언가를 바꿔야 한다. 조건 변경 없는 재시도는 같은 실패를 반복할 뿐이다.

Model Selection: 비용 최적화

subagent-driven-development는 모델 선택에 대한 가이드라인도 제공한다:

Use the least powerful model that can handle each role to conserve cost
and increase speed.

Mechanical implementation tasks (isolated functions, clear specs, 1-2 files):
use a fast, cheap model.

Integration and judgment tasks (multi-file coordination, pattern matching,
debugging): use a standard model.

Architecture, design, and review tasks: use the most capable available model.

모든 Task에 가장 강력한 모델을 쓰지 않는다. 스펙이 명확하고 파일 1-2개만 건드리는 기계적 구현은 저렴한 모델로 충분하다. 판단이 필요한 통합 작업은 표준 모델, 설계와 리뷰는 가장 강력한 모델을 쓴다. 이것은 비용만의 문제가 아니라 속도의 문제이기도 하다. 저렴한 모델은 빠르다.


4. 보조 스킬 — worktrees와 parallel agents

using-git-worktrees: 격리의 기반

실행이 시작되기 전에 worktree가 필요하다. executing-plans와 subagent-driven-development 모두 원문에서 이를 REQUIRED로 명시한다:

superpowers:using-git-worktrees - REQUIRED: Set up isolated workspace
before starting

worktree는 같은 저장소를 공유하면서 별도의 working directory를 만든다. main 브랜치를 건드리지 않고 feature 브랜치에서 작업할 수 있다.

디렉토리 선택에는 우선순위가 있다:

# Check in priority order
ls -d .worktrees 2>/dev/null     # Preferred (hidden)
ls -d worktrees 2>/dev/null      # Alternative
  1. .worktrees/ 디렉토리가 있으면 사용 (숨겨진 디렉토리 선호)
  2. worktrees/ 디렉토리가 있으면 사용
  3. 둘 다 있으면 .worktrees/가 우선
  4. 둘 다 없으면 CLAUDE.md를 확인
  5. CLAUDE.md에도 없으면 사용자에게 질문

이 우선순위의 설계 의도는 일관성이다. 프로젝트마다 worktree 위치가 다르면 혼란이 생긴다. 기존 관례를 먼저 따르고, 없을 때만 새로 정한다.

안전 검사도 중요하다. 프로젝트 로컬 디렉토리(.worktrees나 worktrees)를 사용할 때는 반드시 .gitignore에 포함되어 있는지 확인한다:

# Check if directory is ignored
git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null

ignore되지 않으면 즉시 .gitignore에 추가하고 커밋한다. worktree 내용이 실수로 커밋되는 것을 방지하기 위해서다.

worktree 생성 후에는 프로젝트 설정을 자동 감지해서 실행한다 (package.json이 있으면 npm install, Cargo.toml이 있으면 cargo build 등). 그리고 테스트를 돌려서 clean baseline을 확인한다:

If tests fail: Report failures, ask whether to proceed or investigate.
If tests pass: Report ready.

테스트가 실패하면 진행하지 않고 보고한다. worktree가 깨끗한 상태에서 시작해야, 이후 발생하는 실패가 새로 작성한 코드 때문이라고 확신할 수 있다.

dispatching-parallel-agents: 독립 도메인 식별

dispatching-parallel-agents는 독립적인 작업을 동시에 실행하는 스킬이다. 원문의 핵심 원칙:

Dispatch one agent per independent problem domain.
Let them work concurrently.

사용 조건은 명확하다:

Use when:
- 3+ test files failing with different root causes
- Multiple subsystems broken independently
- Each problem can be understood without context from others
- No shared state between investigations

Don't use when:
- Failures are related (fix one might fix others)
- Need to understand full system state
- Agents would interfere with each other

핵심 판단은 "독립적인가?"다. 세 개의 테스트 파일이 실패해도 원인이 하나면 병렬화할 수 없다. 하나를 고치면 나머지도 고쳐지기 때문이다. 반대로 세 파일의 실패 원인이 각각 다르면 세 에이전트가 동시에 작업할 수 있다.

패턴은 네 단계로 진행된다:

1. 독립 도메인 식별 — 실패를 원인별로 그룹화한다.

2. 에이전트 태스크 구성 — 각 에이전트에게 구체적인 범위, 명확한 목표, 제약 조건, 기대 출력 형식을 부여한다.

3. 병렬 디스패치 — 모든 에이전트를 동시에 실행한다.

4. 통합 — 에이전트들이 돌아오면 결과를 검토하고, 충돌이 없는지 확인하고, 전체 테스트를 돌린다.

원문이 에이전트 프롬프트의 좋은 예와 나쁜 예를 대비한다:

Too broad: "Fix all the tests" - agent gets lost
Specific: "Fix agent-tool-abort.test.ts" - focused scope

No context: "Fix the race condition" - agent doesn't know where
Context: Paste the error messages and test names

No constraints: Agent might refactor everything
Constraints: "Do NOT change production code" or "Fix tests only"

범위가 넓으면 에이전트가 길을 잃는다. 맥락이 없으면 어디서부터 시작할지 모른다. 제약이 없으면 필요 이상으로 코드를 바꾼다. 이 세 가지 실패 패턴은 모두 에이전트에게 "너무 많은 자유"를 준 결과다.

통합 단계에서의 검증도 중요하다:

After agents return:
1. Review each summary - Understand what changed
2. Check for conflicts - Did agents edit same code?
3. Run full suite - Verify all fixes work together
4. Spot check - Agents can make systematic errors

"Spot check — Agents can make systematic errors" — 에이전트가 체계적 오류를 범할 수 있으므로 spot check가 필요하다. 세 에이전트가 모두 같은 잘못된 패턴을 적용했을 수 있다.


마무리: 실행 중 테스트가 실패하면?

다섯 개의 스킬이 형성하는 실행 파이프라인을 정리하면:

  1. writing-plans — No Placeholders 원칙으로 실행자가 추가 판단 없이 따를 수 있는 계획서를 만든다
  2. using-git-worktrees — 격리된 작업 공간을 만들어 main 브랜치를 보호한다
  3. executing-plans 또는 subagent-driven-development — 계획서를 Task 단위로 실행한다
  4. dispatching-parallel-agents — 독립된 작업을 동시에 처리한다

이 파이프라인이 정상 작동하는 한 코드는 계획서대로 만들어진다. 하지만 현실에서는 테스트가 실패한다. writing-plans가 아무리 촘촘하게 계획서를 써도, 구현 과정에서 예상치 못한 실패가 발생한다. 테스트가 실패했을 때 에이전트는 어떻게 대응하는가?

다음 편에서는 test-driven-development, systematic-debugging, verification-before-completion 스킬을 해부한다. 실패를 전제로 설계된 개발 방법론, 실패 원인을 체계적으로 추적하는 디버깅 프로세스, 그리고 완료 선언 전 증거를 요구하는 검증 게이트를 분석한다.