워크플로우
작업 하나가 계획에서 머지까지 가는 길 — 크기별 단계, 플랜 파일, 슬라이스마다 도는 리뷰 게이트.
코딩 에이전트에게 일을 맡길 때는 매번 같은 길로 보내요. 작업 크기가 거칠 단계를 고르고, 플랜 파일이 할 일과 검증 기준을 들고, 슬라이스마다 리뷰 게이트를 지나고, draft PR 에서 멈춰요. 머지는 제가 해요. 단계 하나하나는 에이전트 설정 레포의 스킬(슬래시 명령)이에요. 그 레포는 비공개라서 그대로 쓸 수는 없고, 크기 표와 리뷰 루프 규칙은 원문을 아래에 실었어요.
동작 원리
크기가 단계를 골라요
모든 작업에 전체 단계를 돌리지 않아요. 바뀌는 파일 수로 크기를 정하고, 크기마다 거칠 단계가 정해져 있어요.
| 크기 | 기준 | 단계 |
|---|---|---|
| S | 파일 1~2개 | 구현 → 리뷰 → ship (버그면 원인 조사부터) |
| M | 파일 3~10개 | 탐색 → 플랜 → 슬라이스 루프 → 브랜치 전체 리뷰 → ship |
| L | 파일 10개 이상 | M 앞에 스코프 리뷰, 슬라이스 루프 뒤에 코드 정리(/simplify) 한 번이 붙어요 |
| XL | 무엇을 정해야 할지부터 모름 | 질문으로 결정을 먼저 푼 뒤 플랜 → L 과 같아요 |
파일 수가 적어도 인증, 인가, 사용자 입력, DB 쿼리, 파일 경로, 외부 API, 암호, 시크릿, 공개 API·계약을 건드리면 최소 M 이에요. 플랜의 슬라이스가 3개 이상이거나 새 모듈·서비스·패키지를 만들면, 플랜 뒤에 실행 관점 리뷰(/plan-eng-review)가 한 번 더 붙어요. 슬라이스 경계와 실패 경우를 코드 전에 잡는 편이 싸기 때문이에요.
/orch 를 쓰면 이 선택을 에이전트가 해요. 첫 줄에 작업 종류(추가·변경·버그·구조 정리), 크기, 완료 기준과 그것을 재는 명령을 한 줄로 선언하고, 그 단계들을 끝까지 이어요. 선언이 틀렸으면 그 줄을 보고 제가 고쳐요.
플랜은 파일이에요
M 이상은 플랜을 레포의 .claude/<날짜>/PLAN-<시각>.md 에 써요. 이 파일이 작업의 상태 전부예요. 세션이 끊기거나 컨텍스트가 압축돼도 파일을 다시 읽고 이어 가요.
- 슬라이스 큐 — 할 일을 수직 슬라이스로 나눈 표예요. 슬라이스 하나는 한 층의 조각이 아니라 끝에서 끝까지 동작하는 좁은 경로이고, 혼자 확인할 수 있어요. 체크박스가 진행 상태예요.
- 검증 계약 — 완료 기준을 한 줄씩 적고, 각 줄에 그것을 재는 명령을 묶어요. 구현 전에 red 를 확인하고, 구현 중에는 고정하고, 모델은 판정 칸만 채워요. 이유는 원칙에서 다뤄요. ship 직전에 스크립트가 그 기록을 실제 실행 기록과 대조해요.
슬라이스마다 리뷰 게이트를 지나요
슬라이스 하나를 구현하고 검증 명령이 통과하면, 같은 턴에 리뷰어 서브에이전트를 띄워요. 리뷰어는 메인 세션의 대화나 이전 판정을 모른 채 플랜과 diff, 레포 관례를 보고 발견 사항을 돌려줘요.
Critical 이나 Important 가 있으면 고치고, 검증을 다시 돌리고, 같은 리뷰어에게 다시 보내요. 이 루프는 슬라이스마다 최대 3회예요. 같은 문제가 두 번 연달아 다시 나오거나 3회를 다 쓰면 멈추고 저에게 보고해요.
게이트를 통과하면 슬라이스를 커밋하고 큐에 체크한 뒤 다음 슬라이스로 넘어가요. 슬라이스 사이에 저에게 묻지 않아요.
마무리는 draft PR 에서 멈춰요
/orch 로 돌리면 큐가 빈 뒤 브랜치 전체를 한 번 더 리뷰해요(/review --full). 슬라이스 게이트는 슬라이스 하나씩만 보니, 슬라이스를 가로지르는 문제는 여기서 잡아요. 이 리뷰는 모델 둘로 교차해요(에이전트 설정).
그다음 /ship 이 마무리 게이트를 돌아요. 플랜의 검증 명령을 전부 다시 돌리고 계약의 PASS 기록을 대조해요. 화면을 그리는 코드가 바뀌었으면 화면 QA(웹은 브라우저)를 돌리고, 로직이 바뀌었는데 테스트가 하나도 안 바뀌었으면 빠진 테스트를 쓰게 해요. 커밋 직전에는 이번 작업에서 남길 만한 결정과 배운 점을 노트로 적어요(/harvest). 그 뒤 커밋을 push 하고 draft PR 을 열어요. PR 본문에는 계약 줄마다 판정과 근거가 실려요.
이 사이트의 홈 재설계를 /orch 한 번에 맡긴 날, 플랜 파일의 ## Outcome 에 남은 줄이에요.
- contract: frozen 455d2935
- fix-loop: 01 iteration 1/3 (closed)
- review[01]: FAIL → PASS (fix 루프 1회) — Critical 0, Important 0 2026-10-31
- fix-loop: 02 iteration 1/3 (closed)
- review[02]: FAIL → PASS (fix 루프 1회) — Critical 0, Important 0 2026-10-31
- review: --full FAIL — Critical 1 (contract audit), Important 3 (빈 /blog 링크, 출처 없는 CI 문장, en 404 lang) · cross-model: sonnet · merged 2 · only opus 1 · only sonnet 1 · 2026-10-31
- contract: audit ok (3 checked rows at ab6fdec)
- status: shipped게이트는 모두 통과했어요. 그런데 draft PR 을 열어 본 제 판단은 "이 사이트의 주제를 모르겠다"였어요. 게이트는 문장이 출처에 맞는지, 링크가 살아 있는지, 테스트가 초록인지를 잴 수 있어요. 홈이 누구에게 무슨 말을 하는 페이지인지는 재지 못해요. 그 판단 때문에 draft PR 에서 멈춰요. 그 홈은 배포하지 않았고, 방향을 바꾸는 비용은 커밋 몇 개를 다시 쓰는 것으로 끝났어요.
머지는 /land 한 길로 해요. draft 면 ready 로 바꾸고, squash 머지(개인 레포), 쌓인 PR 의 base 옮기기, worktree 정리를 한 번에 해요. 에이전트는 PR 을 열고 멈추고, 제가 PR 을 본 뒤 /land 를 불러요. 끝난 작업의 기록이 어디로 가는지는 지식 루프 가이드에서, 이 길 앞뒤에서 실제로 손이 가는 스킬은 자주 쓰는 스킬과 습관에서 다뤄요.
여러 에이전트로 굴릴 때
독립된 작업이 두 개 이상이면 /team 을 써요. 지금 Claude Code 세션이 팀장이 되고, 워커(Claude·pi·opencode, 필요하면 테스터)를 Herdr pane 에 띄워 작업을 하나씩 맡겨요. 워커도 위와 같은 길을 혼자 걸어요. Claude 워커는 S 크기 PR 을 직접 머지하고, 나머지는 팀장이 머지해요. 일이 없는 워커는 보안·로직·테스트·CI·성능 같은 렌즈로 레포를 읽어 다음 일감을 찾아요.
/night 은 그 렌즈를 한 세션에서 밤새 돌리는 판이에요. 마감 시각까지 렌즈를 하나씩 읽으며 발견 사항을 적고, S·M 크기 작업만 /orch 로 고쳐 밤 브랜치 하나에 커밋해요. 런이 끝나면 그 브랜치로 draft PR 하나를 열고, 머지는 하지 않아요.
내 설정
크기 표
# Task Sizing
Don't run the full pipeline for every task. Skip stages based on task size.
## Size Guide
`/01-plan`~`/04-fix` = 무접두 라우터 — 레포 fw 자동 감지 후 해당 언어 팩으로 실행 (`skills/_shared/lang/detect.md`). 명시 필요 시(모노레포 혼재 등) 호출 인자로 (`/02-implement react`).
**사람이 여는 본선 입구는 `/01-plan`·`/02-implement`, 마무리 `/ship` 이다** — `/03-review`·`/04-fix` 는 앞 단계와 게이트가 부른다. 갈래를 고르기 싫으면 `/orch` 하나가
종류(add·change·fix·refine)와 크기를 선언하고 그 체인을 잇는다(`skills/orch/SKILL.md`).
**크기 tie-breaker**(정본 — `/orch` 의 크기 판정과 ship 전 `/security-scan` 이 이 목록을 쓴다) — 보안 트리거(인증·인가·사용자 입력·DB 쿼리·파일 경로·외부 API·암호·시크릿)나 공개 API·계약을
건드리면 파일 수와 무관하게 최소 M 이다(출처: ECC `orch-pipeline` Step 0, MIT). 아래 체인에 `04`가
안 보이는 건 누락이 아니라 **게이트가 부르기 때문**이다:
- `04-fix` ← `03-review` 게이트 FAIL 시 자동 (verify-fix 루프 — `review-loop.md`), 또는 `/ship` 게이트 2
(로직 변경에 대응 테스트 0개일 때 — 빠진 테스트를 쓴다)
**테스트는 선택이 아니다.** `03-review` 의 결정적 테스트 동반 체크가 grep 으로 판정하고, 게이트가 FAIL 이면 루프가 돈다(심각도 표 정본 = `skills/_shared/stages/03-review.exec.md` 테스트 동반 체크, skip 판정 = `skills/_shared/tdd-first.md`).
크기가 단계를 고르되, 고른 체인 안의 게이트(`03-review`·테스트 동반 체크)는 건너뛰지 않는다.
### S (1-2 files) — One-line bug fix, small changes
```
/investigate → (고침) → /review → /ship
```
- 이 체인은 S `fix` 다. 크기별 체인은 여기가 정본이고, 종류가 바꾸는 델타(S `add`·`change`·`refine`)와 마무리 판정은 `skills/orch/SKILL.md` Phase 1 소유
- Skip explore, plan
- Small changes to code you already know
- **고치는 건 아무 경로나 된다** — `/04-fix`, `/02-implement`, 스킬 없이 "그냥 고쳐줘". 원인을
찾은 쪽이 DEBUG 리포트를 만들고 **고친 쪽이 `## Resolution`을 채운다**
(계약: `skills/investigate/SKILL.md` Phase 3.5)
- **세션 모델 하나, 전환 없음** — investigate 분석도 `/04-fix` 고침도 세션 모델(핀 정책 = `docs/DEVELOPMENT_GUIDE.md`).
### M (3-10 files) — General feature development
```
/explore → /01-plan (+ Slice Queue) → [/plan-eng-review — 슬라이스 3+·새 모듈일 때만]
→ 슬라이스 루프 ×N: [ /02-implement (한 슬라이스 — 메인이 직접 구현) → /03-review (파인더 스폰, 메인은 게이트) ⟲(04-fix(inline 직접)→verify green→재리뷰(같은 파인더 재사용), max 3) → 게이트 PASS → plan 큐 [x] → **다음 frontier 슬라이스로 자동 전진** ]
→ /ship ← 마무리 게이트가 qa·04-fix를 신호 보고 라우팅
```
- **`/plan-eng-review` 는 조건부 — eng 조건(정본) = Slice Queue 3행 이상, 또는 새 모듈·서비스·패키지를 만든다.** 그때만 plan 뒤·implement 전에
실행 렌즈(슬라이스 경계·failure mode·복잡도)로 플랜을 확정한다 — 큐가 클 때 코드 전에 잡는 게 싸다. 그 아래는 `03-review` 가 충분 —
같은 diff 를 두 번 보지 않는다. plan Next 줄(`agent-skills/01-plan/SKILL.md` § Stop after planning)과 `/orch` 가 이 조건을 쓴다.
- **호출 단위 = 기능 전체, 구현 단위 = 수직 슬라이스**. `/02-implement` 한 번 = 큐 소진까지 완주 (슬라이스마다 리뷰 게이트는 그대로, 사람만 안 낀다). plan이 Slice Queue 생성, implement가 frontier 하나씩 처리. 계약: `skills/_shared/vertical-slices.md`
- **마무리 게이트 = `/ship` Phase 0** — 신호 3개(qa·04-fix 라우팅
+ 팀 org 설계문서면 `/promote` 제안만)와 임계값의 정본 = `skills/ship/SKILL.md`.
1회 라우팅, 루프 아님. 신호 없으면 전부 스킵.
- **/simplify·/explain-diff는 게이트 밖** — 큐 소진 후 `/ship` 전에 이 순서로 직접. **`/simplify` 는 기능당 1회**(정리가 회귀를 만들 수 있고 `/review` 가 브랜치 전체를 다시 돈다. 근거: CONTRACT-EVIDENCE § task-sizing-simplify-once — `/orch` 가 어느 크기에서 자동으로 부르는지는 `skills/orch/SKILL.md` Phase 1 마무리). 슬라이스 사이에는 부르지 않는다. ship 게이트는 신호가 없어 부르지 않고, 스테이지 종료 안내가 한 줄을 제시만 한다(문구 = `output-templates.md` § 종료 안내). `/improve-architecture` 도 게이트 밖(L 전용).
- **슬라이스 간 자동 전진** (기본) — green이면 다음 슬라이스로 같은 턴에 이어감(한 줄 알림, 안 기다림). 사람은 슬라이스 사이 게이트 아님. 멈춤 사유는 `skills/_shared/review-loop.md` § Exit·§ 루프 밖 정지가 소유 — 여기서 다시 세지 않는다.
- `03-review` 이슈 발견 시 verify-fix 루프 자동 진입: `04-fix → 재리뷰` (상한·카운터 = `skills/_shared/review-loop.md`)
- 마무리는 전부 큐 소진 후 기능 레벨 1회 (슬라이스마다 아님)
- **`/review` 는 03-review 를 안 거친 diff 와 M 이상의 마무리에** — 단독 `/review` 는 큐 전 슬라이스가 게이트 PASS 로 커밋됐으면 같은 코드를
통짜로 다시 보는 것이라 건너뛴다(판정 = `skills/review/SKILL.md` § 1 "이미 게이트됨"). pi 구현·수동 커밋처럼
슬라이스 리뷰 기록이 없는 브랜치, 그리고 `/simplify` 가 게이트 뒤에 바꾼 diff 가 `/review` 의 자리다. `/orch` 는 M 이상이면 큐 소진 뒤 `/review --full` 을 한 번 돌고(슬라이스를 가로지르는 문제), S `add`·`change` 는 `hooks/s-gate.sh` PASS 기록으로 판정한다 — 정본 `skills/orch/SKILL.md` Phase 1. `/tech-debt`·`/compound` 도 ship 게이트 밖 — 주기 레인
(`docs/LANES.md` `friction.biweekly`·`compound.monday`)이 부른다. plan Outcome 의 `fix-loop:` 행이 compound 의 입력.
- TDD skip 조건 = `skills/_shared/tdd-first.md` § Skip 조건 — 주장이 아니라 확인된 것만
- **결정은 AI 가, 사용자에겐 못 정하는 것만** — `/01-plan` Phase 2.5 가 열린 결정을 스스로 닫고(`Decisions` 에 근거),
선호·비가역·스코프·상충 선례만 grilling 형식으로 묻는다(보통 0~3개). 굳은 용어·결정은 CONTEXT.md/ADR inline.
- **/prototype 선택** (plan 전, 설계 질문이 미해결일 때만): 말로 안 끝나는 질문 —
"이 상태 모델 맞나" / "어떻게 보여야 하나" — 을 버리는 코드로 끝낸다. 답만 plan에 접고
코드는 throwaway 브랜치. 질문이 없으면 스킵 (프로토타입은 만들 게 정해졌을 때 쓰는 게 아니다)
### L (10+ files) — Large-scale features, refactoring
```
/explore → /plan-ceo-review → /01-plan (+ Slice Queue) → [/plan-eng-review — 슬라이스 3+·새 모듈일 때만]
→ 슬라이스 루프 ×N: [ /02-implement → /03-review ⟲(04-fix→verify green→재리뷰, max 3) → 게이트 PASS → plan 큐 [x] → **다음 frontier 슬라이스로 자동 전진** ]
→ /improve-architecture(권장) → /ship ← 게이트가 qa·04-fix 라우팅
```
- 큐 분해·자동 전진·verify-fix 루프 = **M과 동일** (위 M 절). L의 델타만 아래:
- **전 구간 세션 모델, 전환·clear 없이 진행** — 구현도 메인이 직접 하고 파인더만 스폰하므로 모델을 바꿀 이유가 없다(핀 정책 = `docs/DEVELOPMENT_GUIDE.md`).
- **pi 가 구현자면** `/01-plan` 까지 여기서, 슬라이스 소진은 pi `/skill:02-implement`(계약 = `pi/GUIDE.md` § 2.3, 기동 = 사람이 `/pi-implement`), 이 세션은 `/review`·`/ship` 과 게이트 판정만 — 슬라이스 결과는 `_shared/slice-results.md`. 세션 오픈 고정 비용 때문에 플랜 한 번에 슬라이스 여러 개를 싣는다(근거: CONTRACT-EVIDENCE § task-sizing-pi-session-cost).
- **/prototype 선택** (M과 동일 — plan 전, 설계 질문 미해결 시). L에서는 특히 슬라이스 분해
**전에** 쓴다: 상태 모델/화면 구조가 안 정해진 채 큐를 짜면 슬라이스 경계가 틀린다
- 렌즈 위치: `/plan-ceo-review` 는 plan **전**(스코프 잠금), `/plan-design-review` 는 설계 결정이
미해결일 때 ceo 뒤·plan 전, `/plan-eng-review` 는 plan **뒤**(M 절의 eng 조건)
### XL (경로가 안 보임) — 크기가 아니라 **안개**가 기준
```
/explore → /grilling (+ /prototype) 로 결정 해소 → 안개 소진
→ /01-plan (+ Slice Queue) → 이후 L과 동일
```
- **진입 조건은 파일 수가 아니다.** 한 세션에 안 들어가고 **뭘 결정해야 할지부터 모를 때**만.
안 들어가지만 만들 게 정해졌으면 그건 L → 바로 `/01-plan`.
- 첫 grilling에서 **안개가 안 나오면 즉시 중단** → `/01-plan`.
- 결정은 **답할 질문**, Slice Queue 는 **만들 슬라이스** — 순차지 대체 아님, 안개가 걷혀야 큐를 짤 수 있다.
여러 세션에 걸치면 같은 세션을 resume 한다. **여기는 사람이 루프 안에 있다.**
## 외부 의존 (footnote)
- `/simplify` = 내장 `/simplify` 의 로컬 오버라이드(`skills/simplify/SKILL.md`). `/simplify` = 리뷰+적용 · `code-simplicity-reviewer` = 리포트 전용.
리뷰 루프
루프 규칙의 정본은 세 하네스가 같이 읽는 공용 스킬 파일이라 영어로 써요.
# Review verify-fix loop
When `03-review` finds issues, this loop runs on its own — no fresh instruction from the user. **The stop conditions'
canonical home is § Exit + § Stops outside the loop below** — other files only point at these two sections.
## Loop
1. Review done → Fix Checklist (the Review Output in `SKILL.md`).
2. Any [Critical] or [Important] → straight to `04-fix` with the Fix Checklist.
- Exception — **Axis-B Important (scope-creep)**: not a code fix. A user gate — revert, or record acceptance in the
plan's `## Decisions`.
### Loop 3 — Re-verify
- **Deterministic checks first** (the repo's verification commands) — failing → back to fix without a re-review (a new
fix round — § Loop 4).
- Passing → **reuse the same finder** (`SKILL.md` § After findings **Fail**: re-send with `- mode: re-review` +
`- delta:`). Earlier verdicts and finding lists are not sent again. Fallback (no agent id, an error, a harness that
cannot re-address a subagent) = a fresh spawn + an Outcome observation row.
- **Same-issue recurrence** is judged by the main session comparing Fix Checklists across iterations.
### Loop 4 — Iterations and the counter
**Max 3 iterations — independently per slice.** One iteration = one fix round + that round's re-review — the third fix
gets its re-review too. The count lives in the plan's `## Outcome` as one line `- fix-loop: <slice> iteration N/3`,
**updated in place** (survives compaction). On exit this row stays (`compound` reads it) and only the review row is
updated to the final Review Output form.
**The counter is read and raised only where a fix round opens — in every mode.** Three places open one: an
implementation verify-red retry · entering `04-fix` · respawning a re-review that died without a return (a dead round
counts once too). There, read N first: `N` ≥ 3 → **neither fix nor spawn**, go to Exit "3 exhausted"; otherwise rewrite
the row to `iteration N+1/3` (open it when absent) and start the round. A normal re-review neither reads nor raises the
counter — it belongs to the round just opened. With a plan:
```bash
S=$(printf '%s' "$SLICE" | sed 's/[][\.*^$+?(){}|]/\\&/g') # escape metacharacters of merged ids such as `04+05`
N=$(grep -E "fix-loop: (slice )?${S}([^0-9]|$)" "$PLAN" | grep -oiE 'iteration +[0-9]+' \
| grep -oE '[0-9]+' | sort -n | tail -1)
echo "fix-loop N=${N:-0}"
```
A standalone `- plan: none` call counts in the Output report, within the same turn only.
## Exit
| Condition | Action |
|------|------|
| [Critical] 0 + [Important] 0 (Nice-to-have only left included) | Slice passes → queue rows left: **advance to the next frontier automatically** (`02-implement`); drained: the loop ends — the finish is the user's call (in autonomous mode, continue to the chain's finish in the same turn) |
| Axis-B Important (scope-creep) left | Stop the auto-loop → **user gate** (revert, or accept in `## Decisions`). Re-review after it is resolved. In autonomous mode, do not stop — record it as accepted |
| The same issue recurs twice in a row | Stop now — change approach, or report |
| 3 exhausted (review FAIL and verify red counted together) | Stop + report — every remaining issue and every fix tried. The user decides |
Autonomous mode (a chain `orch` drives — with a plan, its header `Orch:` line): the exceptions' canonical home is
`../orch/SKILL.md` (its autonomous-mode rules).
## Stops outside the loop
The Exit table stops on review results. Below are the places this session cannot judge, whatever the review said — it
neither stops nor asks outside these two sections. Autonomous mode stops here too (except where a row says otherwise).
| Place | Condition | Action |
|---|---|---|
| `02-implement` pre-implementation (plan lookup) | the session has no plan path and there is not exactly one unfinished plan candidate | ask the user |
| `02-implement` pre-implementation (tree check) | a tracked change outside the plan's Files table | stop and report — a change of unknown ownership does not ride a slice commit |
| `02-implement` frontier loop | the slice is blocked on permission outside the code (credentials, an external console, a human approval) | stop and report — a human marks `[b]` (below) |
| `SKILL.md` § Finder spawn 3 | the respawned finder's return is invalid too | stop and report |
| TDD seam confirmation | the plan has no `## Seams`, or there is no plan | confirm the seam once. Autonomous mode: no question, the recommended seam |
| language pack detection | ambiguous (ask) | one question. Autonomous mode: no question, `none` |
`[b]` is not an exit of the Exit table — it is an implementation-time boundary (permission outside the code), not a
review result. Escaping a FAIL through `[b]` is forbidden. A human-marked `[b]` row leaves the frontier and its criteria
are skipped as BLOCKED — nothing more.
Source: `claude/skills/_shared/review-loop.md`.
계약 한 줄의 모양
- AC-1 · s01 · WHEN `pnpm build` 가 끝나면 THE <파일> SHALL <기대 결과> · check: s01-ac1 · status: FAIL · evidence: —check: 는 플랜의 검증 명령 절에 있는 명령 이름이에요. 구현 중에는 status·evidence 두 칸만 바뀌어요. evidence 에는 실제로 돌린 명령과, 판정을 떠받치는 출력 한 줄을 적어요.