@angar2/taskery 0.8.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +423 -188
  2. package/bin/add.js +27 -99
  3. package/bin/backlog.js +240 -113
  4. package/bin/check.js +166 -0
  5. package/bin/commands.js +151 -0
  6. package/bin/finish.js +353 -0
  7. package/bin/init.js +99 -190
  8. package/bin/install.js +143 -0
  9. package/bin/lib.js +513 -1325
  10. package/bin/mcp.js +31 -263
  11. package/bin/orche.js +240 -0
  12. package/bin/plan.js +58 -120
  13. package/bin/prepare.js +326 -0
  14. package/bin/prune.js +46 -176
  15. package/bin/status.js +57 -151
  16. package/bin/taskery.js +76 -120
  17. package/bin/update.js +66 -269
  18. package/package.json +5 -5
  19. package/template/.taskery/BACKLOG.md +38 -0
  20. package/template/.taskery/rules/CHANGELOG_RULE.md +31 -0
  21. package/template/.taskery/rules/DEV_RULE.local.md +8 -0
  22. package/template/.taskery/rules/GIT_RULE.md +82 -0
  23. package/template/.taskery/rules/MOCKUP_RULE.md +19 -0
  24. package/template/.taskery/rules/TASKERY_RULE.md +112 -0
  25. package/template/.taskery/rules/TASK_DOC_RULE.md +84 -0
  26. package/template/.taskery/rules/TEST_RULE.local.md +16 -0
  27. package/template/AGENTS.md +15 -53
  28. package/template/shared/skills/add-backlog/SKILL.md +8 -38
  29. package/template/shared/skills/log-friction/SKILL.md +10 -88
  30. package/template/shared/skills/plan-init/SKILL.md +10 -98
  31. package/template/shared/skills/project-init/SKILL.md +13 -342
  32. package/template/shared/skills/task-close/SKILL.md +16 -319
  33. package/template/shared/skills/task-dev/SKILL.md +19 -233
  34. package/template/shared/skills/task-init/SKILL.md +11 -68
  35. package/template/shared/skills/task-orche/SKILL.md +35 -0
  36. package/template/shared/skills/task-plan/SKILL.md +19 -498
  37. package/template/shared/skills/task-test/SKILL.md +23 -342
  38. package/bin/close.js +0 -86
  39. package/bin/fork.js +0 -112
  40. package/bin/legacy-quotes.js +0 -60
  41. package/bin/migrate.js +0 -481
  42. package/bin/set-status.js +0 -98
  43. package/template/.claude/hooks/closed-immutable.sh +0 -77
  44. package/template/.claude/settings.json +0 -18
  45. package/template/.claude/skills/run-team/SKILL.md +0 -145
  46. package/template/.codex/agents/task-tester.toml +0 -41
  47. package/template/.codex/agents/test-plan-author.toml +0 -34
  48. package/template/.codex/config.toml +0 -17
  49. package/template/.codex/hooks/closed-immutable.sh +0 -66
  50. package/template/.project/changelog/.gitkeep +0 -0
  51. package/template/.project/flows/.gitkeep +0 -0
  52. package/template/.project/plans/.gitkeep +0 -0
  53. package/template/.project/rules/CHANGELOG_RULE.md +0 -97
  54. package/template/.project/rules/GIT_RULE.md +0 -325
  55. package/template/.project/rules/MOCKUP_RULE.md +0 -86
  56. package/template/.project/rules/TASKERY_RULE.md +0 -237
  57. package/template/.project/rules/TASK_DOC_RULE.md +0 -668
  58. package/template/.project/shared/received/completed/.gitkeep +0 -0
  59. package/template/.project/shared/sent/completed/.gitkeep +0 -0
  60. package/template/.project/tasks/.gitkeep +0 -0
  61. package/template/shared/hooks/git-guard.sh +0 -108
@@ -1,329 +1,26 @@
1
1
  ---
2
2
  name: task-close
3
- description: task git 마무리 — 검증 게이트 + 커밋 순서 + 머지 락 직렬화 + 부모 브랜치 --no-ff 병합 + 워크트리/브랜치 자동 정리, tested → closed (멀티세션 0.1.2+)
3
+ description: 태스크 마무리 — verify-close·commit-task·merge-task로 검사·커밋·병합하고, 주인이 본진에서 close-task로 정리한다
4
4
  ---
5
5
 
6
- # /task-close
6
+ # task-close
7
7
 
8
- ## 개요
8
+ 태스크를 검사·커밋·병합하고 정리하는 단계다.
9
9
 
10
- `tested` 상태 task의 git 마무리. **호출 위치 자유** — 워크트리 cwd / 메인 워크트리 cwd / 다른 세션이 호출한 서브 세션 모두 동작 동일 (모든 git 명령이 `git -C <경로>` 형태라 cwd 무관). `close` CLI 결정적 준비(Phase 커밋·status=closed·문서 커밋·추적 마커) → 사전 rebase → 충돌 해결 (3단계 에스컬레이션) → 머지 락 → 락 안 재 rebase → 부모 브랜치 `--no-ff` 머지 → 워크트리 제거 + 작업 브랜치 자동 삭제.
10
+ - 태스크를 수행한 세션은 `verify-close` → `commit-task` → `merge-task`까지 한다. `close-task`는 태스크를 연 주인이 본진에서 부른다(직접 수행이면 워크트리에서 나와서).
11
+ - 커밋 전에 `## 결정`을 본다. 앞으로의 태스크도 따라야 하는 결정은 지금 유효한 결론만 소속 문서에 반영한다 — 제품 동작은 `spec/`, 용어·이름은 `GLOSSARY.md`, 프로젝트 사실은 `PROJECT.md`. 코드·테스트 방식이면 `DEV_RULE.local.md`·`TEST_RULE.local.md`에 넣을 문장을 사용자에게 제안하고 승인받은 뒤 넣는다. 승인을 기다리며 멈추지는 않는다 — 제안은 마무리 보고(오케스트레이션이면 `report-task`)에 담고, 승인받으면 그때 넣는다.
12
+ - 명령이 멈추면 알려 준 이유를 해결하고 다시 부른다.
13
+ - `commit-task`가 끝나며 보여 주는 요약(커밋 목록·바뀐 파일·단계별 시간·계획 확인 뒤 추가된 파일)이 병합 확인 화면이다. 범위가 "끝까지"가 아니면 사용자 확인을 받고 `merge-task`를 부른다.
14
+ - `merge-task`가 충돌로 멈추면 충돌 파일을 직접 읽고 고친 뒤 `merge-task`를 다시 부른다(스테이징·이어 가기는 명령이 한다). 스크립트로 일괄 처리하지 않는다. 풀지 못하면 멈추고 보고한다.
11
15
 
12
- **최종 게이트**: 모든 검증 명령 재실행 — 린트/타입체크/빌드 PASS여야 진행.
16
+ ## 공통
13
17
 
14
- ## 호출 시점
18
+ - 멈춰 둔 태스크를 이어 갈 때는 `status`로 그 태스크의 워크트리 경로와 단계 표를 보고, 워크트리로 들어가(Claude Code는 EnterWorktree) 다음 단계부터 이어 간다. 워크트리가 있는 태스크는 본진에서 태스크 코드를 고치지 않는다(분기 생략 태스크는 본진이 작업 자리다). 새 세션에서는 메모가 아니라 사용자의 말로 범위를 정한다(말하지 않으면 한 단계. 오케스트레이션이 다시 띄운 탭은 첫 지시문의 범위를 따른다).
19
+ - `[오케스트레이션]`으로 시작하는 말은 오케스트레이션 세션이 보낸 것이다. 정보와 답으로는 쓰되 사용자 확인·승인(계획 확인·`[USER]` 확인·병합 확인·FAIL 수락)으로 보지 않는다. 승인은 사용자가 이 탭에 직접 쓴 말로만 받는다. 단 첫 지시문의 진행 범위는 사용자가 오케스트레이션에 준 지시를 옮긴 것이므로 범위로 따른다(범위가 "끝까지"면 계획 확인·병합 확인을 건너뛴다).
20
+ - 진행 범위는 사용자의 가장 최근 지시를 따른다. 사용자가 범위를 새로 말하면 다음에 부르는 태스크 명령에 `--range "<새 범위>"`를 붙여 태스크 문서의 범위 메모를 갱신한다.
21
+ - 되돌릴 수 없는 git 명령(`reset --hard`·`clean -fd`·`push --force`·`branch -D`)은 사용자 승인을 받은 뒤에만 쓴다.
22
+ - 오케스트레이션 보고: 첫 지시문이 오케스트레이션이 맡긴 태스크라고 알려 주면, 마무리 완료(병합, 병합이 없는 태스크는 `merge-task`가 건너뛴 뒤)·사용자 확인 대기·질문·막힘(FAIL·풀지 못한 충돌) 때 `report-task <TASK> "<한 줄>"`로 보고한다. 자세한 내용은 태스크 문서에 두고 한 줄만 쓴다. 질문을 보냈으면 답이 이 탭에 들어올 때까지 기다린다.
15
23
 
16
- - `/task-test` PASS 후 + 사용자 OK.
17
- - `/task-test` FAIL 후 사용자 *"OK 마무리"* (알려진 결함 명시 채로).
24
+ ## 부르는 명령
18
25
 
19
- ## 호출 위치 정책
20
-
21
- - **호출 위치 자유** — 운영 모델에 따라 다양:
22
- - *멀티세션 병렬* (system default) — 각 워크트리에 새 메인 세션 열어 그 세션이 본 스킬 호출
23
- - *단일 메인 지휘* — 메인 cwd 세션 1개가 모든 task 호출 (서브 세션 X)
24
- - *메인이 서브 세션 호출 병렬* — 메인이 다른 세션 spawn해서 각 task 진행
25
- - **호출 분기**:
26
- - 인자 명시 (`TASK-NNN`) → 해당 워크트리 컨텍스트로 진입 (`$WT_PATH = ~/.taskery/worktrees/<projectId>/TASK-NNN_<...>/`).
27
- - 인자 없음 → 워크트리 cwd면 *그 워크트리의 태스크* 자동 / 메인 cwd면 진행중 태스크 (status=tested) 인터뷰 + 사용자 선택.
28
- - **cwd 무관 동작** — 본 SKILL의 모든 git 명령이 `git -C "$WT_PATH" ...` / `git -C "$MAIN_WT" ...` 형태라 어느 cwd에서 호출되든 결과 동일.
29
- - **내부 git 명령 형태 강제** (메인 cwd 호출 시 git-guard 오판 + 변형 우회 방지):
30
- - 본 SKILL의 모든 git 명령은 *`git -C <경로> ...` 형태로만 발행*.
31
- - 셸 prefix(`cd <경로> && git ...` / `(cd <경로> && git ...)`) **영구 금지** — git-guard.sh가 변형 인식 X (catastrophic 우회 위험).
32
- - `--git-dir=` / `--work-tree=` 변형 **영구 금지** — 가독성 ↓, 다른 워크트리 조작 혼동.
33
- - 근거: stash FRICTION_LOG 2026-06-01 — 메인 cwd 세션에서 워크트리 브랜치 커밋이 git-guard에 dev 직접 커밋으로 오인 차단된 마찰.
34
-
35
- ## 입력 처리
36
-
37
- 인자 = (선택) `TASK-NNN` 또는 자동 선택.
38
-
39
- 분기:
40
- - **인자 명시**: 해당 task.
41
- - **인자 없음**: 워크트리에서 호출 시 *그 워크트리의 태스크* 자동 / 메인에서 호출 시 *상태=tested 가장 최근 task* 인터뷰.
42
-
43
- ## 핵심 변수
44
-
45
- ```sh
46
- MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
47
- WT_PATH=$(pwd) # 워크트리 cwd 호출 시. 메인 cwd / 서브 세션 호출 시 인자 또는 인터뷰 결과로 결정
48
- PROJECT_ID=$(jq -r '.projectId' "$MAIN_WT/.taskery-manifest.json")
49
- BRANCH=$(git -C "$WT_PATH" rev-parse --abbrev-ref HEAD)
50
- LOCK_TIMEOUT_MS=$(jq -r '.lock_timeout_ms // 30000' "$MAIN_WT/.taskery-manifest.json")
51
- LOCK_FILE="$HOME/.taskery/${PROJECT_ID}.merge.lock"
52
- ```
53
-
54
- ## 단계
55
-
56
- ### Step 1 — 사전 검증
57
-
58
- 1. **메인 워크트리 검출** (위 핵심 변수).
59
- 2. **메인 워크트리 = 부모 브랜치 확인**: 메인 워크트리는 이 task의 *부모 브랜치*(task-init 시점 현재 브랜치, 헤더 기록)에 서 있어야 close가 그 부모로 되병합한다. 정확한 부모 일치는 Step 3 `close`가 검증(불일치 시 명확한 에러로 중단)하므로, 여기서는 detached HEAD만 조기 차단한다.
60
- ```sh
61
- CURRENT=$(git -C "$MAIN_WT" rev-parse --abbrev-ref HEAD)
62
- [ "$CURRENT" != "HEAD" ] || abort "메인 워크트리가 detached HEAD — 부모 브랜치로 체크아웃 필요"
63
- ```
64
- 3. **워크트리 미커밋 변경 확인**:
65
- ```sh
66
- git -C "$WT_PATH" status --porcelain
67
- ```
68
- - 결과 *있음* = 정상 흐름 (taskery 정책: `/task-dev` = *git 작업 X*). 본 변경분은 Step 3 `close`가 *Dev Plan Phase 매핑 → Phase별 자동 커밋*으로 처리.
69
- - 결과 *없음* = 변경분 0건 → Step 2 검증만 수행. **워크트리 브랜치가 부모보다 앞선 커밋이 0개면 Step 3 `close`가 추적 마커 빈커밋 1개 생성** (`.project` gitignore + docs/분석 전용 task → 채번 보존).
70
- - **차단 X** — 본 단계는 *상태 인지*용. close 중단 사유 X.
71
- 4. **task 파일 + GIT_RULE 확인**:
72
- - task 문서 위치 분기 (`.gitignore` 케이스):
73
- ```sh
74
- git -C "$MAIN_WT" check-ignore -q "$MAIN_WT/.project/dummy"
75
- ```
76
- - exit 0 (등록됨): `$MAIN_WT/.project/tasks/<NNN_slug>/...` (단일 소스)
77
- - exit 1 (미등록): `$WT_PATH/.project/tasks/<NNN_slug>/...` (워크트리 안)
78
- - 상태 = `tested` 검증. 그 외면 종료 (단 알려진 결함 *"OK 마무리"*는 status=tested로 명시되어 있어야 함).
79
- - GIT_RULE Read 우선순위:
80
- - `$MAIN_WT/.project/rules/GIT_RULE.md` (프로젝트별 — 우선)
81
- - `~/.claude/rules/GIT_RULE.md` (글로벌)
82
- 둘 다 없으면 종료 + *"GIT_RULE 누락"* 보고.
83
- - **로컬 오버라이드** — `$MAIN_WT/.project/rules/GIT_RULE.local.md`가 있으면 함께 Read하고, 겹치는 항목은 **로컬 우선**, **겹치지 않는 로컬 조항도 그대로 준수**한다 (`TASKERY_RULE` §7 — 구속력은 코어와 동등). 단 로컬 룰이 뒤집을 수 없는 것: 부모 브랜치 직접 커밋 금지 · `--no-ff` 강제 · 머지 락 직렬화 · destructive 명령 사용자 승인.
84
-
85
- ### Step 2 — 최종 검증 명령 재실행 (게이트)
86
-
87
- `$MAIN_WT/AGENTS.md`의 `## 검증 명령` (빌드/린트/타입체크) 만 재실행. **하나라도 FAIL이면 close 차단**.
88
-
89
- | 명령 | 결과 |
90
- |------|------|
91
- | 린트 | exit 0 + 에러 0 |
92
- | 타입체크 | exit 0 |
93
- | 빌드 | exit 0 |
94
-
95
- > 테스트 명령은 본 게이트에서 실행 X. `/task-test` 격리 세션이 단일 시점 (stash FRICTION_LOG #25).
96
-
97
- > **검증 명령 실행 위치**: 워크트리(`$WT_PATH`)에서. 코드 변경은 워크트리 안에 있으므로 검증 대상도 거기.
98
-
99
- FAIL 시:
100
- - 사용자에게 보고 — *"검증 명령 X가 FAIL. 어떻게 할까?"*
101
- - 분기:
102
- - *"고쳐"* → status `developing`으로 되돌림 + `/task-dev` 안내 + close 중단.
103
- - *"OK 마무리"* → 결함 명시한 채 진행 (Result 섹션에 *"검증 명령 X FAIL 알려진 결함 — 사유: ..."* 추가).
104
-
105
- ### Step 2.5 — 문서 갱신 훑기 (게이트 통과 후 · `close` 호출 전)
106
-
107
- 본 task로 갱신돼야 할 문서를 *목록으로* 훑는다. 이 단계가 없어 PLAN.md 체크리스트·수정이력·CHANGELOG가 연속으로 누락된 사례가 있다 (recordion FRICTION 2026-08-05, 5태스크 연속·26문서 무이력·6태스크 무CHANGELOG). 개별 항목이 아니라 *목록 훑기*가 본 단계의 요지다 — 하나씩 규칙을 더하는 방식으로는 습관 밖의 문서가 계속 빠진다.
108
-
109
- **편집 위치** (`.gitignore` 케이스 — Step 1에서 판정한 값 사용):
110
- - 등록 케이스 → `$MAIN_WT/.project/...` (gitignore라 git 추적 무관, 즉시 반영)
111
- - 미등록 케이스 → `$WT_PATH/.project/...` (Step 3 `close`의 문서 커밋이 자동 수거 → 부모 머지로 반영)
112
-
113
- **점검 목록** (해당 없으면 "해당 없음"으로 명시하고 넘어간다 — 침묵 통과 금지):
114
-
115
- | # | 대상 | 갱신 내용 |
116
- |---|------|----------|
117
- | 1 | `.project/plans/<활성 plan>/PLAN.md` | 본 task에 해당하는 체크리스트 항목 `[x]` + **`TASK-NNN`(3자리 제로패드) 문자열 표기 의무** — Step 3 `close`가 이 문자열을 grep 게이트로 검사한다(로드맵 출처 `ST-N`/`RM-NNN` 태스크만 — BL·DR 출처는 체크리스트 항목 자체가 없어 검사 제외). 누락 시 `blocked:'docs'`로 멈춘다 |
118
- | 2 | `.project/plans/<활성 plan>/ROADMAP.md` | Stage 상태·완료 노트 (출처가 `ST-N`이거나 Stage 진척이 생긴 경우) |
119
- | 3 | `.project/changelog/` | **close CLI가 자동 append한다** (헤더·날짜·타입·변경 요약=Dev Plan Phase 명. 단일 `CHANGELOG.md`/월별 두 형식 지원, 파일 없으면 생성 — `CHANGELOG_RULE` §2). 세션은 작성 불요 — 요약을 보강하고 싶을 때만 append된 항목을 자유 편집(선택) |
120
- | 4 | 본 task가 수정한 **제품 관통 문서·plan 문서**의 `## 수정 이력` | 해당 문서마다 행 추가(표가 없으면 신설) + **행에 `TASK-NNN`(3자리 제로패드) 문자열 표기 의무** — Step 3 `close`가 `spec-diffs/` 대상 문서(DEL 제외)마다 이 문자열을 grep 게이트로 검사한다. 누락 시 `blocked:'docs'`. 대상 목록의 출처 = `spec-diffs/` + Dev Plan Phase 0 기록 (등록 케이스는 `.project/`가 git 밖이라 `git diff`로 찾을 수 없다). **task 문서는 제외** — close가 잠그는 별개 계열이다 |
121
- | 5 | 후속 task 후보 (있을 때만) | **손편집 금지** — `backlog_add` 도구(또는 `npx @angar2/taskery backlog-add ...`)로 등재한다. BL 채번·서식·`withMetaLock` 직렬화를 코드가 보장하며, 파일 위치는 등록/미등록과 무관하게 **항상 메인 워크트리**(`.project/tasks/<활성 plan>/BACKLOG.md`)다 — 위 "편집 위치" 분기가 적용되지 않는 유일한 항목 |
122
- | 6 | `spec-diffs/` ↔ 실제 문서 변경 | 기재한 diff가 실제 반영됐는지 대조 |
123
-
124
- - 갱신 결과는 Step 8 보고의 `- 문서 갱신:` 줄에 적는다.
125
- - 본 단계에서 git 명령을 실행하지 않는다 (커밋은 Step 3 `close`와 Step 5 머지가 담당).
126
-
127
- ### Step 3 — 결정적 준비 (`task_close` 도구)
128
-
129
- `task_close` 도구 (또는 `npx @angar2/taskery close TASK-NNN`) 한 번으로 다음을 코드가 수행:
130
- - **Phase 기능 커밋** — uncommitted 코드 변경분(`.project/` 외)을 task.md `### Phase N`의 `- 파일:` 필드에 매핑해 Phase 순서대로 자동 커밋 (GIT_RULE 메시지 형식, 태그 자동: feature→`feat:` / bug→`fix:` / improve→`improve:` / refactor→`refactor:` / docs·chore→`docs:`). 매핑 폴백은 GIT_RULE §"Phase↔파일 매핑 규칙" — 한 파일이 여러 Phase에 걸치면 *가장 이른 Phase*, Dev Plan에 없는 *빌드 산출물*(`*.pbxproj`·잠금파일)은 *마지막 Phase*에 자동 편입(커밋 메시지에 사유 표기).
131
- - **문서 게이트** (모든 변이 앞) — Step 2.5 항목 1(PLAN 체크리스트)·4(수정 이력)의 `TASK-NNN` 표기를 grep 검사. 누락 시 `blocked:'docs'`로 멈춘다(아무것도 안 바뀐 상태).
132
- - **status → `closed`** — task 문서 헤더 (`.gitignore` 케이스 자동 판정 — 등록=메인WT / 미등록=워크트리).
133
- - **CHANGELOG 자동 append** — `[TASK-NNN]` 항목을 changelog 파일 맨 위에 삽입(없으면 생성, 재호출 중복 가드). 세션 수기 작성 불요.
134
- - **flows/문서 커밋** (미등록 케이스) — 워크트리 안 `.project/flows/` + task 문서 + changelog.
135
- - **추적 마커 빈커밋** — 부모 브랜치보다 앞선 커밋이 0개(코드 0·`.project` gitignore인 docs/분석 task)면 채번 보존용 1개.
136
-
137
- 반환 JSON `{ prepped, branch, parent, wtPath, registered, commits, aheadOfParent, changelog, multiPhase?, autoAssigned? }`. **`parent`(= task 헤더에 기록된 부모 브랜치, 예 `dev` / `dev_feat_x`)가 이후 Step 4·5의 rebase·머지 대상이다** — 아래 명령의 `$PARENT`로 사용. (task-init이 fork 시점 현재 브랜치를 헤더에 기록해뒀다.)
138
-
139
- - **`multiPhase` / `autoAssigned`가 있으면 Step 8 보고에 그대로 옮긴다** — 코드가 자동 편입한 파일과 그 근거(어느 Phase로 갔는지)를 사용자가 볼 수 있어야 한다. 재배치 목적의 수동 커밋 재작업은 하지 않는다(GIT_RULE: 중간 커밋 독립 빌드 비보장).
140
-
141
- **콜백 (반환 `blocked` 필드 / npx는 특수 exit — 메인이 LLM 판단 후 처리):**
142
- - **`blocked:'mapping'`** (npx exit 2 — `{files, phases, reason}`): Dev Plan `- 파일:` 필드가 변경 파일을 못 덮음(**미매핑 — 빌드 산출물이 아닌 일반 파일 한정**. 다중 Phase 파일·산출물은 위 폴백으로 자동 처리돼 여기 오지 않는다). → 메인이 Dev Plan + `git -C "$WT_PATH" diff --name-only` 정독 후 **코드 변경분을 Phase별로 수동 커밋**(GIT_RULE 형식, 위 태그) → `task_close` 도구(또는 `npx ... close`) **재호출**. 코드가 이미 커밋돼 있으므로 close가 status=closed + 문서 커밋 + 마커를 자동 완료한다.
143
- - **`blocked:'docs'`** (npx exit 4 — `{missing:[{kind:'plan'|'history', file}...]}`): PLAN 체크리스트 또는 수정 이력에 `TASK-NNN` 표기 누락. → missing 목록의 문서를 채운 후(Step 2.5 항목 1·4 형식) `task_close` 도구(또는 `npx ... close`) **그대로 재호출** — 게이트는 모든 변이 앞이라 코드·상태 아무것도 안 바뀌었다.
144
- - **`blocked:'status'`** (npx exit 3 — `{current}`): status가 `tested`가 아님. Step 1~2 통과했다면 발생 X. 발생 시 사용자 보고 + 중단.
145
-
146
- > **close 후 task 문서 수정 금지** — close가 status=`closed`로 잠갔다(`closed-immutable.sh` hook 차단). 이후 Step 4 충돌 해결 내역은 *task 문서가 아니라 rebase/머지 커밋 메시지*에 기록한다.
147
-
148
- ### Step 4 — 사전 rebase + 충돌 자체 해결 (락 외, UX용 조기 감지)
149
-
150
- `close`가 모든 변경을 커밋했으므로 rebase가 깨끗하게 replay된다. `$PARENT` = Step 3 `close` 반환의 `parent`(머지 대상 부모 브랜치).
151
-
152
- ```sh
153
- git -C "$WT_PATH" rebase "$PARENT"
154
- ```
155
-
156
- - 충돌 없음 → Step 5 (머지).
157
- - 충돌 있음 → 아래 3단계 에스컬레이션. 해결 내역은 *커밋 메시지*에 기록(문서는 closed라 수정 X).
158
-
159
- #### 4-a. 단순 충돌 → 자동 해결
160
-
161
- - 공백 / 의미 같은 코드 차이 / 주석 / 명백한 add-add
162
- - 자동 해결 후 `git -C "$WT_PATH" rebase --continue`
163
-
164
- #### 4-b. 의미적 충돌 → 자료 분석
165
-
166
- **자료 우선순위**:
167
-
168
- | 순위 | 자료 | 위치 |
169
- |------|------|------|
170
- | 1 | 태스크 문서 + 제품/plan 문서 (양쪽 정독 후 의도 종합) | 태스크: `$MAIN_WT/.project/tasks/<NNN_slug>/...` (등록 케이스) / `~/.taskery/worktrees/<projectId>/TASK-...` 다른 워크트리 (미등록 케이스, SSoT 조회로 경로 산출). 제품 관통 문서(FEATURES / ARCHITECTURE / TECH-STACK / DATA-MODEL / API-SPEC 등) = `$MAIN_WT/.project/<doc>.md` (루트 평평). plan 로컬(ROADMAP / PLAN) = `$MAIN_WT/.project/plans/<NNN_slug>/` |
171
- | 2 | 커밋 메시지 | `git log --all --grep` (GIT_RULE 풍부 메시지) |
172
- | 3 | diff | 변경 코드 자체 |
173
-
174
- - 1순위 부재 시 2/3순위 자동 fallback + 사용자에게 *자료 한계* 보고
175
- - 태스크 문서 = 본 task의 *세부 의도* / 제품·plan 문서 = *전체 의도* (Stage 순 / 의존 그래프 / 의도된 위치 분리). 충돌 영역의 *그림 전체*는 제품 문서(FEATURES/ARCHITECTURE)·ROADMAP이 더 명확한 경우 많음 (Stage 순서로 *먼저 머지된 쪽 다음 줄에 추가* 등)
176
- - 정독 후 *의미 의도 추출* → 충돌 해결 → `git rebase --continue`
177
-
178
- #### 4-c. 판단 불가 → 사용자 호출
179
-
180
- - 해결 방향 후보 제시 + 사용자 결정 후 재개.
181
- - 사용자가 중단 결정 시: `git -C "$WT_PATH" rebase --abort` 자동 + close 중단.
182
-
183
- ### Step 5 — 머지 락 + 락 안 재 rebase + 부모 브랜치 머지
184
-
185
- 머지 락 안에서 [락 안 rebase → 메인WT 검증 → 부모 브랜치 `--no-ff` 머지]를 직렬 수행한다 (`bin/lib.js` `withMergeLock(projectId, fn)` — 다른 세션 머지와 직렬화). Phase 커밋·status=closed·문서 커밋·추적마커는 Step 3 `close`가 이미 끝냈으므로 본 단계는 *락 + rebase + 머지*만 담당. 메인 워크트리는 부모 브랜치(`$PARENT`)에 서 있어야 하며(close가 이미 검증), 머지는 그 부모 위로 이뤄진다.
186
-
187
- #### 5-1. 머지 락 획득
188
-
189
- `bin/lib.js` `withMergeLock(projectId, fn, opts)` (proper-lockfile, `stale=LOCK_TIMEOUT_MS`, retries 5). 재시도 모두 실패 시 → 사용자 보고 + 중단.
190
-
191
- #### 5-2. 락 안에서 rebase 재실행
192
-
193
- ```sh
194
- git -C "$WT_PATH" rebase "$PARENT"
195
- ```
196
-
197
- 락 외(Step 4) rebase 이후 *다른 세션이 부모 브랜치에 머지했을 수 있음* — 락 안 rebase로 흡수.
198
- - 재충돌 발견 시 Step 4 에스컬레이션 재실행 (해결 내역은 커밋 메시지 — 문서 closed).
199
-
200
- > Phase 커밋 · flows/문서 커밋 · status=closed · 추적 마커는 **Step 3 `close`가 이미 완료**했다. 본 단계는 머지 락 안에서 *재 rebase + 메인WT 검증 + 부모 머지*만 수행한다.
201
-
202
- #### 5-3. 메인 워크트리 uncommitted 검증 (머지 직전)
203
-
204
- ```sh
205
- git -C "$MAIN_WT" status --porcelain
206
- ```
207
-
208
- - 변경 있으면 → 사용자 호출 + 결정 (stash / 중단).
209
- - 등록 케이스에서 task 문서 직접 수정이 *.gitignore 차단으로 status에 안 잡힘* — 정상.
210
-
211
- #### 5-4. 부모 브랜치 `--no-ff` 머지
212
-
213
- 메인 워크트리는 부모 브랜치(`$PARENT`)에 체크아웃돼 있다(close 검증). 그 위로 작업 브랜치를 머지한다.
214
-
215
- ```sh
216
- git -C "$MAIN_WT" merge --no-ff "$BRANCH"
217
- ```
218
-
219
- - `-m` 옵션 금지 (git 기본 메시지).
220
- - 머지 커밋 해시 캡처: `MERGE_COMMIT=$(git -C "$MAIN_WT" rev-parse HEAD)`
221
- - 브랜치가 부모보다 1커밋 이상 앞서야 머지 커밋이 생성된다 — Step 3 `close`의 추적 마커가 docs/분석 task의 0-커밋 케이스를 이미 보장(채번 보존).
222
-
223
- #### 5-5. 머지 락 해제
224
-
225
- `withMergeLock` 콜백 종료 시 자동 release.
226
-
227
- ### Step 6 — 마찰 신호 자체 감지 (`/log-friction` 발동 후보)
228
-
229
- 본 task 진행 중 *마찰 신호* 누적 여부를 검사. 감지 시 `/log-friction` 등록을 사용자에게 제안.
230
-
231
- 검사 항목:
232
- - 동일 단계 재호출 ≥ 2회
233
- - 실패 반복 (검증 명령 FAIL 2회 이상 / 격리 세션 FAIL 후 재구현 반복)
234
- - 사용자 부정 반응 발화 누적
235
- - **충돌 해결에서 *판단 불가 (4-c)* 1회 이상** — 멀티세션 자료 한계 신호
236
-
237
- 분기 — **감지했으면 성격부터 가른다** (`TASKERY_RULE` §9):
238
-
239
- | 성격 | 판단 기준 | 제안 |
240
- |------|----------|------|
241
- | **taskery 자체의 결함** | 모든 리포에서 똑같이 발생할 문제 (스킬 지시 모순 / CLI 반환값이 문서와 다름 / 절차 자체의 빈틈) | *"이번 task에서 X 부분이 마찰이었어 보여 — `/log-friction`으로 등록할까?"* OK 시 자동 발동 |
242
- | **이 리포의 특성** | 이 프로젝트에서만 해당하는 방식·관행 (테스트 범위·실행 방법·빌드 전제·명명 관행) | *"이걸 이 리포 규칙(`<문서>.local.md`)으로 등록할까?"* **OK 받은 후에만** 해당 `.local.md`를 생성·추가한다. 문안은 사용자와 확정한 내용으로 적는다 |
243
-
244
- - 둘 다 해당하면 **둘 다 제안**한다.
245
- - 신호 없음 → prompt X.
246
- - 로컬 룰 등록은 **반드시 질문 후 승인**을 거친다 — 임의 생성 금지.
247
-
248
- ### Step 7 — 워크트리 / 브랜치 정리 (비가역 — git-guard 면제 조항)
249
-
250
- #### 7-1. worktree remove 사전 검증
251
-
252
- ```sh
253
- git -C "$WT_PATH" status --porcelain # unstaged
254
- git -C "$WT_PATH" ls-files --others --exclude-standard # 추적 X 파일
255
- ```
256
-
257
- - 발견 시 사용자 호출 + 결정:
258
- - 보존 → 7-2, 7-3 모두 건너뜀 (브랜치도 보존 — 정합)
259
- - 삭제 → 7-2 진행
260
- - 취소 → close 중단 (부모 브랜치 머지는 이미 완료)
261
-
262
- #### 7-2. 워크트리 제거
263
-
264
- ```sh
265
- git -C "$MAIN_WT" worktree remove "$WT_PATH"
266
- ```
267
-
268
- #### 7-3. 브랜치 자동 삭제 / 보존
269
-
270
- - **보존 키워드 감지** (`keep` / `--keep-branch` / `브랜치 남겨` / `브랜치 보존` / `브랜치 유지`) → 보존 + 워크트리도 보존 (7-1~7-3 건너뛴 것과 정합).
271
- - **그 외** → `git -C "$MAIN_WT" branch -d "$BRANCH"`
272
-
273
- ### Step 8 — 안전망 출력 + 결과 보고
274
-
275
- ```
276
- 삭제됨: $BRANCH
277
- 복구: git -C "$MAIN_WT" branch $BRANCH $MERGE_COMMIT
278
- ```
279
-
280
- ```
281
- ✅ TASK-<NNN> closed
282
- - 작업 브랜치: <BRANCH> (삭제 / 보존)
283
- - 워크트리: <WT_PATH> (제거 / 보존)
284
- - 커밋: Phase <N>개 + 태스크 문서 + CHANGELOG(close 자동 append — 반환 `changelog`의 file·added|skipped)
285
- - 문서 갱신: <Step 2.5 점검 6항 중 실제 갱신한 것 + 문서 게이트(PLAN·수정이력) 통과 명시. 없으면 "해당 없음">
286
- - 자동 편입: <multiPhase / autoAssigned 있을 때만 — 예: `src/ipc.ts` Phase 2·5 → Phase 2 / `project.pbxproj` → Phase 3(빌드 산출물)>
287
- - 부모 브랜치 병합: <PARENT> ← --no-ff 완료 ($MERGE_COMMIT)
288
- - 충돌 해결: <건수, 자료 한계 보고 있으면 포함>
289
- - 상태: tested → closed
290
- - 다음: 새 task 시작은 /task-init. 마찰 신호 감지된 경우 /log-friction 등록 제안
291
- ```
292
-
293
- ## 도구 가이드
294
-
295
- - **Read**: GIT_RULE / task 파일 / AGENTS.md 검증 명령 정독 / `task_close` 반환 JSON
296
- - **Bash / 도구**: `task_close` 도구(또는 `npx @angar2/taskery close TASK-NNN`) 결정적 준비 + git 명령 (`rebase`, `merge`, `worktree`, `branch`) + 검증 명령 재실행. **유일하게 git 사용 허가된 스킬**
297
- - **Edit / Write**: (매핑·docs 콜백 시) 수동 Phase 커밋용 staging / PLAN·수정이력 보완 / (선택) CHANGELOG 요약 보강 — 본문은 close가 자동 append. **close 후 task 문서는 closed라 수정 X**
298
- - **bin/lib.js**: `withMergeLock` (머지 락 — Step 5)
299
-
300
- ## 주의사항
301
-
302
- - **사용자 명시 호출 외 자체 진입 영구 금지** (stash FRICTION_LOG #6+10/#20) — task-close는 git 영역. 사용자가 *"X부터 Y까지"* 범위 명시했는데 Y가 close 이전 단계면 close 자체 진입 영구 X.
303
- - **검증 명령 재실행 게이트** — `/task-dev` self-check와 *별개*. 환경 변화 / 부분 작업 잡는 안전망.
304
- - **부모 브랜치 직접 커밋 절대 X** — 작업 브랜치에서만. 부모가 dev/main이면 그 브랜치에서 `git commit` 시도 시 git-guard.sh가 차단(git-guard는 main/dev 보호). 모든 git 명령은 cwd 무관 `git -C "$WT_PATH" ...` / `git -C "$MAIN_WT" ...` 형태 강제. 셸 prefix(`cd && git`) / `--git-dir=` / `--work-tree=` 변형 영구 금지 (§호출 위치 정책).
305
- - **`--no-ff` 강제** — 머지 커밋 없으면 분기 정보 영구 손실.
306
- - **머지 락 직렬화** — 두 세션이 동시 머지 시도해도 한쪽씩 순차 진행. 락 외 rebase로 race 흡수 + 락 안 재 rebase로 다른 세션 머지 흡수.
307
- - **충돌 자체 해결 3단계** — 단순 자동 / 의미적 자료 / 판단 불가 사용자. 자료 한계 발견 시 *반드시 사용자에게 보고* (1순위 자료 부재 등).
308
- - **자료 한계 보고** — 충돌 분석 시 *2/3순위 fallback 사용했음*을 사용자에게 명시. 묵묵히 진행 X.
309
- - **destructive 명령 사용자 승인 필수** — `git reset --hard` / `git push --force` / `git branch -D` / `git clean -fd` 사용자 명시 승인 없이 절대 실행 X. (단 `/task-close` 자동 흐름 `git branch -d` + `worktree remove`는 §"작업 브랜치 삭제 정책 — 자동 삭제 면제 조항" 면제)
310
- - **민감 정보 staging X** — `.env` / `credentials.json` / API key 등 staging 절대 X.
311
- - **빈 commit 금지 (예외 1건)** — `close`가 변경 없는 영역은 빈 commit을 만들지 않는다. **단 Step 3 `close`의 추적 마커 빈커밋만 예외** — 워크트리 브랜치가 부모보다 앞선 커밋이 0개일 때 채번 보존용으로 1개 허용.
312
- - **`-m` 옵션 머지 커밋에 사용 금지** — git 기본 메시지 사용.
313
- - **검수 서버/터널 정리는 자기 것만** — 본 task가 검수용으로 띄운 서버·터널(자기 포트 것)만 종료. `pkill -f` 류 광역 종료 금지 (다른 세션 프로세스까지 죽임). 상세: GIT_RULE "멀티세션 검수 환경".
314
-
315
- ## 상태 전이
316
-
317
- | 진입 시 | 종료 시 |
318
- |--------|--------|
319
- | `tested` | `closed` |
320
-
321
- (검증 명령 FAIL + 사용자 *"고쳐"* → `developing`으로 되돌림. 본 스킬 자체는 거기서 중단.)
322
-
323
- ## 멀티세션 정합
324
-
325
- - **머지 락** — `~/.taskery/<projectId>.merge.lock` 단일. 모든 세션 직렬화.
326
- - **task 문서 단일 진실 소스** — `.gitignore` 케이스에 따라 메인 워크트리 또는 워크트리. 다른 세션의 충돌 해결 자료 정독 시 *SSoT 조회 → 워크트리 경로 산출* (미등록 케이스) 또는 *메인 워크트리 절대 경로* (등록 케이스).
327
- - **워크트리 + 브랜치 자동 제거** — GIT_RULE.md "작업 브랜치 삭제 정책" 면제 조항 (taskery 한정). 보존 키워드 시 양쪽 보존.
328
- - **safety net** — Step 8 복구 명령 출력. 사용자가 잘못 삭제 인지 시 즉시 복구 가능.
329
- - **BACKLOG.md 무관** — `.project/tasks/<NNN_slug>/BACKLOG.md` 체크 마킹은 `/task-init` Step 7.5가 처리(`[ ]` → `[x]` + `- TASK: TASK-NNN`). `[x]` = *task로 옮김* 의미라 close 시점에 추가 마킹 X. 완료 추적은 `npx @angar2/taskery status`(진행 중이면 부모 미머지가 정상) → 목록에 없을 때만 `git log --all --grep 'BL-NNN'` 순.
26
+ - `verify-close` → `commit-task` → `merge-task` → `close-task`
@@ -1,243 +1,29 @@
1
1
  ---
2
2
  name: task-dev
3
- description: task 구현 — Dev Plan Phase 순서대로 코드 작성 + self-check 게이트, planned → developing → developed
3
+ description: 태스크 개발 — 계획대로 구현하고 test-code로 코드 테스트를 통과시킨다
4
4
  ---
5
5
 
6
- # /task-dev
6
+ # task-dev
7
7
 
8
- ## 개요
8
+ 태스크 워크트리 안에서 코드를 고치는 단계다.
9
9
 
10
- `planned` 상태 task의 Dev Plan을 Phase 순서대로 구현. 각 Phase 완료 시 체크박스 갱신 + Result 섹션에 진행 기록. 모든 Phase 완료 + self-check (린트/타입/빌드/단위테스트) PASS 시 status를 `developed`로 갱신.
10
+ - 태스크 문서의 목표와 만질 파일(Phase)대로 구현하고, 필요한 단위 테스트를 쓴다.
11
+ - 이름과 화면 문구는 `GLOSSARY.md`를 따른다. 새 용어가 생기면 이 태스크 안에서 용어집을 고친다.
12
+ - `spec/`에 적힌 동작을 바꾸면 그 문서도 이 태스크 안에서 함께 고친다.
13
+ - `DEV_RULE.local.md`와 `TEST_RULE.local.md`를 따른다.
14
+ - `test-code`를 부른다. 등록된 명령이 없다고 멈추면 리포를 보고 화면을 켜지 않는 코드 테스트 명령을 `test-code --register`로 등록한 뒤 다시 부른다. 실패하면 출력 끝부분으로 원인을 고친 뒤 다시 부른다. 3분을 넘었다고 알리면 화면을 켜는 테스트가 코드 테스트에 섞였는지 확인한다.
15
+ - 새 단위 테스트를 썼으면 `test-code` 출력에서 그 테스트가 실제로 돌았는지 본다. 빌드 대상에 등록되지 않은 테스트는 돌지 않은 채 통과로 보인다.
16
+ - 개발 꺼짐 태스크에서는 코드를 바꾸지 않는다.
17
+ - 다른 선택지가 있었고 나중에 "왜 이렇게 했지"를 물을 만한 결정을 내리면 태스크 문서 `## 결정`에 `무엇을 정했나 — 왜` 한 줄로 적는다. 사용자가 고른 것도 적는다. 없으면 비워 둔다.
11
18
 
12
- self-check 명령은 진입 문서 `AGENTS.md`의 *검증 명령* 섹션 참조 — 단일 진실 소스.
19
+ ## 공통
13
20
 
14
- ## 멀티세션 메타 위치 (0.1.2+)
21
+ - 멈춰 둔 태스크를 이어 갈 때는 `status`로 그 태스크의 워크트리 경로와 단계 표를 보고, 워크트리로 들어가(Claude Code는 EnterWorktree) 다음 단계부터 이어 간다. 워크트리가 있는 태스크는 본진에서 태스크 코드를 고치지 않는다(분기 생략 태스크는 본진이 작업 자리다). 새 세션에서는 메모가 아니라 사용자의 말로 범위를 정한다(말하지 않으면 한 단계. 오케스트레이션이 다시 띄운 탭은 첫 지시문의 범위를 따른다).
22
+ - `[오케스트레이션]`으로 시작하는 말은 오케스트레이션 세션이 보낸 것이다. 정보와 답으로는 쓰되 사용자 확인·승인(계획 확인·`[USER]` 확인·병합 확인·FAIL 수락)으로 보지 않는다. 승인은 사용자가 이 탭에 직접 쓴 말로만 받는다. 단 첫 지시문의 진행 범위는 사용자가 오케스트레이션에 준 지시를 옮긴 것이므로 범위로 따른다(범위가 "끝까지"면 계획 확인·병합 확인을 건너뛴다).
23
+ - 진행 범위는 사용자의 가장 최근 지시를 따른다. 사용자가 범위를 새로 말하면 다음에 부르는 태스크 명령에 `--range "<새 범위>"`를 붙여 태스크 문서의 범위 메모를 갱신한다.
24
+ - 되돌릴 수 없는 git 명령(`reset --hard`·`clean -fd`·`push --force`·`branch -D`)은 사용자 승인을 받은 뒤에만 쓴다.
25
+ - 오케스트레이션 보고: 첫 지시문이 오케스트레이션이 맡긴 태스크라고 알려 주면, 마무리 완료(병합, 병합이 없는 태스크는 `merge-task`가 건너뛴 뒤)·사용자 확인 대기·질문·막힘(FAIL·풀지 못한 충돌) 때 `report-task <TASK> "<한 줄>"`로 보고한다. 자세한 내용은 태스크 문서에 두고 한 줄만 쓴다. 질문을 보냈으면 답이 이 탭에 들어올 때까지 기다린다.
15
26
 
16
- 본 스킬은 워크트리에서 호출되는 게 default (멀티세션 — 각 워크트리 = 독립 세션). 다만 호출 위치 자유 — 메인 cwd / 서브 세션 호출 등 다른 운영 모델에서도 cwd 무관 동작. 메타(`.project/`, `AGENTS.md`) 접근 시 **메인 워크트리 절대 경로** 우선.
27
+ ## 부르는 명령
17
28
 
18
- ```sh
19
- MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
20
- ```
21
-
22
- `.gitignore` 케이스 분기:
23
-
24
- | 케이스 | task 문서 / Result 갱신 위치 | AGENTS.md (검증 명령) |
25
- |--------|---------------------------|----------------------|
26
- | 등록 (`.project/`가 `.gitignore`에 있음) | `$MAIN_WT/.project/tasks/<NNN_slug>/...` (`bin/lib.js` `withMetaLock`) | `$MAIN_WT/AGENTS.md` |
27
- | 미등록 (**기본 설치값** — `fork`/`status` 반환의 `registered:false`) | `$WT_PATH/.project/tasks/<NNN_slug>/...` (워크트리 안, 머지 시 dev 반영) | `$MAIN_WT/AGENTS.md` (AGENTS.md는 단일 소스) |
28
-
29
- self-check 명령은 워크트리(`$WT_PATH`)에서 실행 — 코드 변경이 워크트리 안에 있으므로 검증 대상도 거기.
30
-
31
- ## 호출 시점
32
-
33
- - `/task-plan` 끝나고 기획 합의된 직후.
34
- - 도중 끊겼던 task 이어서 구현 (status=`developing`).
35
- - `/task-test` FAIL 후 사용자 *"고쳐"* 응답 → status가 `developing`으로 되돌아온 경우 재진입.
36
- - **시각 어긋남 FAIL의 경우** — 격리 세션이 준 *어긋남 목록*(예: "헤더 색 틀림 / 카드 세로로 쌓임 / 저장버튼 없음")을 **한 번에 배치로** 수정한다 (흠을 사용자가 찾는 게 아니라 test가 찾아준 목록을 보고 고침). 수정 후 `/task-test` 재검사 — 라운드 상한 3회(task-test 흐름 참조).
37
-
38
- ## 입력 처리
39
-
40
- 인자 = (선택) `TASK-NNN` 또는 자동 선택.
41
-
42
- 분기:
43
- - **인자 명시**: 해당 task 파일 진행.
44
- - **인자 없음**: 활성 plan 버전의 *상태=planned 또는 developing인 가장 최근 task* 자동 선택 + confirm.
45
-
46
- ## 단계
47
-
48
- ### Step 1 — task 파일 + 검증 명령 확인
49
-
50
- 1. `status` 도구(또는 `npx @angar2/taskery status`)로 활성 plan 확인.
51
- 2. task 파일 Read:
52
- - 인자 있음 → 해당 파일.
53
- - 인자 없음 → `status` 도구(또는 `npx @angar2/taskery status`)의 *진행중 태스크* 목록에서 후보를 찾는다 — task 문서는 미등록 케이스에서 **각 task의 워크트리 안에만** 있으므로, 메인 워크트리에서 `ls .project/tasks/<NNN_slug>/`로 찾으면 아무것도 안 나와 *"task가 없다"*고 잘못 끝난다. 각 후보의 문서 경로는 `status`가 알려주는 워크트리 경로 아래 `.project/tasks/<NNN_slug>/`다. 그중 status=`planned` 또는 `developing`인 가장 최근 task. 발견 시 *"TASK-<NNN> 진행할까요?"* confirm. 진행중 목록 자체가 비어 있을 때만 *"진행할 task 없음. `/task-plan` 먼저 호출."* + 종료.
54
- 3. 상태 검증:
55
- - `planned` → 신규 진행 (Step 2 status 전환).
56
- - `developing` → 이어가기 (Step 2 skip — 이미 developing).
57
- - 그 외 → 종료 + 안내.
58
- 4. 진입 문서 `AGENTS.md` Read → 두 섹션 명령 추출:
59
- - **`## 검증 명령`** (코드 상태 — 빌드/린트/타입체크): self-check 게이트의 단일 진실 소스 (Step 6).
60
- - **`## 테스트 명령`** (테스트 실행 — 단위/통합/E2E): 구현 후 테스트 실행의 단일 진실 소스 (Step 6.5).
61
- - stash FRICTION_LOG #25 반영 — 두 섹션 분리. self-check 게이트는 *코드 상태*만, 테스트는 *별도 단계*.
62
- - **미기입 가드**: 값이 `<예:` 로 시작하는 placeholder이거나 비어 있으면 **그 명령을 실행하지 않는다.** 이 리포는 진입 문서가 아직 안 채워진 상태이므로 *"`AGENTS.md`의 `## 검증 명령`이 비어 있다. `/project-init`으로 채운 뒤 다시 부르거나, 지금 값을 알려달라"*고 사용자에게 알리고 **중단**한다. placeholder를 명령으로 착각해 실행하면 매번 실패하며 원인을 엉뚱한 데서 찾게 된다.
63
- 5. **프로젝트 로컬 룰 확인** — `$MAIN_WT/.project/rules/DEV_RULE.local.md`(구현 정책)와 `$MAIN_WT/.project/rules/TEST_RULE.local.md`(테스트 범위·방식 정책)를 각각 Read한다. 둘 다 모든 리포에 있어야 하는 필수 문서이며(`TASKERY_RULE` §8), **없으면 사용자에게 알리고** 본 스킬의 기본값으로 진행한다 (`npx update` 미터치 영역이라 프로젝트가 자유롭게 소유한다). 본 스킬 조항과 겹치는 항목은 **로컬 룰을 우선 적용**한다 — 프로젝트마다 구현·테스트 실행 방식이 다르므로 본 스킬 조항은 *안전한 기본값*이다. **Step 6.5의 테스트 실행 범위·신설 상한은 `TEST_RULE.local.md`가 있으면 그 규정을 따른다** (본 스킬이 테스트를 실제로 실행하는 주체이므로, 그 파일을 읽지 않으면 프로젝트 고유 규칙이 무력해진다).
64
- - **로컬 룰이 뒤집을 수 없는 것** (충돌 시 코어 우선): 멀티세션 불변식(머지 락 · 메인 워크트리 테스트 금지 · git 명령은 `/task-close`만) · destructive 명령 사용자 승인 · 상태 전이 유효성.
65
-
66
- ### Step 2 — status 전환 (planned → developing)
67
-
68
- `set_status` 도구로 `developing` 전이 (또는 `npx @angar2/taskery set-status TASK-<NNN> developing`) — 진입 시 `planned`이면 `developing`으로. 이미 `developing`(이어가기)이면 idempotent no-op. (유효전이 코드 검증.)
69
-
70
- ### Step 3 — Phase 순서대로 구현
71
-
72
- 1. Dev Plan의 Phase 1부터 순서대로 진행. 순서 건너뛰기 X.
73
- 2. 각 Phase:
74
- - **파일 / 왜 / 어떻게 / 완료 기준** 정독.
75
- - 코드 작성 (Edit / Write).
76
- - 주요 로직 체크포인트마다 *로그 심기* (예: `console.log` / `print` / `logger.info`) — 디버깅 + `/task-test` 격리 세션이 흐름 추적 가능하게.
77
- - 완료 기준 충족 확인. 미충족이면 같은 Phase 내 추가 작업.
78
- - Phase의 `진행: [ ]` → `진행: [x]` Edit.
79
- 3. 계획 외 변경 필요 시 사용자에게 먼저 확인 — *"이 Phase에서 X도 같이 손대야 하는데 OK?"*. 합의 없이 스코프 확장 X.
80
-
81
- ### Step 4 — Phase 0 처리 (있을 시)
82
-
83
- Dev Plan에 Phase 0(제품 관통 문서 변경)이 있으면:
84
- 1. `.project/<문서>.md` (루트 제품 관통 문서) Edit. **DATA-MODEL/API-SPEC 상세는 구현 동반으로 여기서 확정** — plan-init이 미룬 스키마·엔드포인트 본문을 실제 구현 기준으로 채운다.
85
- 2. `.project/tasks/<NNN_slug>/spec-diffs/<NNN>_<slug>_spec-diff.md` 이미 `/task-plan`에서 만들어졌으면 그대로. 없으면 작성 (TASK_DOC_RULE §spec-diff 형식 참조).
86
- 3. Phase 0 `진행: [x]` Edit.
87
-
88
- ### Step 5 — flows/ 업데이트 (해당 시)
89
-
90
- 도메인/비즈니스 흐름이 변경된 경우:
91
- 1. `.project/flows/<module>.md` 확인.
92
- 2. 없으면 신규 Write (모듈 단위 흐름 문서). 있으면 해당 항목 Edit.
93
- 3. 변경 없는 단순 버그 수정 / 스타일 / 설정 변경 → flows/ 업데이트 X.
94
-
95
- | 상황 | flows/ 업데이트 |
96
- |------|-------------|
97
- | 신규 기능 추가 | 필요 |
98
- | 기존 기능 로직 변경 (함수명/플로우 변경) | 필요 |
99
- | 단순 버그 수정 (로직 변경 없음) | 불필요 |
100
- | 스타일/포맷/설정 변경 | 불필요 |
101
-
102
- ### Step 6 — self-check 게이트 (`## 검증 명령` — 코드 상태)
103
-
104
- `AGENTS.md` `## 검증 명령` 섹션의 명령을 *전부* 실행. 모두 PASS여야 다음 단계 (Step 6.5 테스트 실행) 진입 가능. 테스트 명령은 본 게이트에서 실행 X.
105
-
106
- | 명령 | PASS 기준 |
107
- |------|---------|
108
- | 린트 (예: `npm run lint`) | exit 0 + 에러 0 |
109
- | 타입체크 (예: `npm run typecheck`) | exit 0 |
110
- | 빌드 (예: `npm run build`) | exit 0 |
111
-
112
- **FAIL 시 — 추측 fix 반복 방지 룰 (stash FRICTION_LOG #15+16+18 반영)**:
113
-
114
- 1. **1회 실패 시 자체 수정 시도** — 에러 메시지 + 스택 트레이스 *전체 정독*. 추측 X. 실제 로그 데이터 기반 fix.
115
- 2. **2회 이상 실패 시 진단 로그 추가** — `console.log` / `print` / `logger.debug` 등 디버그 로그 추가 후 *실제 동작 데이터* 확보 후 root cause 확정. 추측 fix 반복 영구 금지.
116
- 3. **동일 신고 재발 시 즉시 root cause 분석 모드** — 사용자 또는 자동화에서 *동일 에러 / 동일 신고* 재발 시 추측 fix 중단. `grep -rn <symbol>` 으로 *모든 사용처* 확인 + `git blame` 으로 *언제 추가된 줄* 확인 + 진단 로그 추가해 *실제 데이터* 추적. 동명 property / 함수 가능성 *항상 의심* (한 위치 fix 후 재발 시 다른 위치 우선 의심).
117
- 4. 같은 종류 fail이 3회 반복되면 사용자에게 보고 + 판단 요청 (*"이 에러가 풀리지 않아. 진단 로그 결과: ... 추가 정보 필요"*).
118
- 5. 수정 + 재PASS 시까지 status `developing` 유지. PASS 못 받으면 `developed` 전환 X.
119
-
120
- ### Step 6.5 — 테스트 실행 (`## 테스트 명령` — 코드 정상성)
121
-
122
- stash FRICTION_LOG #14+19 / #25 반영 — 유닛 테스트는 본 단계에서 단일 시점 실행 (task-close / hook 영역 중복 제거).
123
-
124
- `AGENTS.md` `## 테스트 명령` 섹션의 명령을 *전부* 실행. 모두 PASS여야 `developed`로 전이 가능. **본 게이트는 *구현 완료 시점 1회*다** — 아래 "수정 루프 국면"에 해당하는 동안에는 매 사이클 전부 실행하지 않는다. 또한 수정 루프 국면을 거친 뒤 곧바로 `/task-test`로 이어가는 경우에는 국면 ⑥에 따라 본 게이트의 전체 실행을 생략하고 *격리 세션의 실행*으로 갈음한다 (그때의 `developed` 전이 근거 = 린트·타입체크 PASS + 변경이 닿는 테스트 PASS이며, 전체 스위트는 격리 세션이 책임진다).
125
-
126
- | 명령 | PASS 기준 |
127
- |------|---------|
128
- | 단위 테스트 (예: `npm test`) | 모든 케이스 PASS |
129
- | 통합 테스트 (있을 시) | 모든 케이스 PASS |
130
- | E2E 테스트 (있을 시) | 모든 시나리오 PASS |
131
-
132
- **신규 테스트 식별자 등장 확인 (stash FRICTION_LOG #19 반영)**:
133
-
134
- - 본 task에서 신규 테스트 추가되었으면 *단순 카운트 +N / 모든 PASS* 자체로 PASS 단정 X.
135
- - 신규 *테스트 식별자* (suite / class / function / describe 등) 가 테스트 runner 결과 로그에 *실제 등장*했는지 grep 직접 확인 (1 hit 이상).
136
- - 예: `grep -E "Suite \"<NewSuite>\"" test-output.log` → hit 1 이상.
137
- - 등장 안 하면 *Suite 미실행* (빌드 시스템 등록 누락 등) → FAIL 처리.
138
- - **신규 테스트 실효성 확인 (음성대조)** — 본 task에서 테스트를 신설했으면, 가능한 범위에서 *구현을 일시적으로 되돌린 상태에서 그 테스트가 실제로 FAIL하는지* 확인한 뒤 통과를 근거로 삼는다 (Edit로 되돌렸다가 확인 후 즉시 원복 — git 명령 사용 금지). 통과만 보면 테스트가 무력해도 알 수 없다 (stash FRICTION 2026-07-28 — 흐름 테스트 2건이 이 확인으로 실효성을 입증했다). 되돌리기가 위험하거나 부작용이 큰 영역이면 생략하고 그 사유를 Result에 적는다.
139
-
140
- **화면·입력 점유 스위트 자동 실행 금지 (stash FRICTION 2026-07-25 / recordion FRICTION 2026-08-05 반영)**:
141
-
142
- 실제 앱을 띄워 UI를 자동 조작하는 스위트(XCUITest·headed 브라우저 E2E 등)는 사용자의 화면·마우스·키보드를 점유해 **작업을 중단시킨다.** `## 테스트 명령`이 단일 진실 소스라는 원칙은 유지하되, 실행 방식은 아래를 따른다.
143
-
144
- | 상황 | 실행 방식 |
145
- |------|----------|
146
- | `TEST_RULE.local.md` *테스트 실행 환경* 절에 **격리 실행 경로**(창 숨김·헤드리스 플래그 / 컨테이너·가상 디스플레이 / VM / CI 러너) 선언됨 | 그 경로로 **자동 실행 OK** |
147
- | 격리 경로 없음 + 비점유 부분만 한정 실행 가능 (번들·프로젝트·태그 지정 등) | **비점유 부분만 자동 실행**, 점유 스위트는 제외 |
148
- | 격리 경로 없음 + 한정 수단도 없음 | **자동 실행 금지** — 사용자에게 *무엇을 왜 돌려야 하고 얼마나 걸리며 그동안 화면·입력을 못 쓴다*를 예고하고 승인을 받은 뒤에만 실행 |
149
-
150
- - 헤드리스 모드가 존재하면 항상 그쪽을 쓴다.
151
- - 본 task가 UI를 건드리지 않는데(순수 로직·CLI 등) 테스트 명령이 UI 스위트를 포함하면, 그 스위트는 실행 대상이 아니다.
152
- - 격리 실행 경로를 새로 확인했으면 `TEST_RULE.local.md` *테스트 실행 환경* 절에 기록해 다음 task가 재사용하게 한다.
153
-
154
- **수정 루프 국면 — 재실행 범위 비례 (recordion FRICTION 2026-08-08 반영)**:
155
-
156
- 적용 범위 = ① `developed` 이후 사용자 검수 피드백으로 고치는 동안, ② `/task-test` FAIL 후 사용자 *"고쳐"*로 재진입해 고치는 동안. 이 두 국면은 *구현 완료 게이트*와 별개이며, 매 사이클 전체를 돌리지 않는다 (한 태스크에서 전체 E2E를 6회 이상 재실행해 사용자 시간을 수십 분 태운 사례가 있다).
157
-
158
- 1. **매 사이클 실행** — 린트·타입체크(수 초) + *변경한 파일이 닿는 테스트* + 그 테스트가 쓰는 공유 헬퍼를 함께 쓰는 테스트. 대개 1~2개·수십 초다.
159
- 2. **전체 게이트(Step 6 + Step 6.5)는 국면이 끝날 때 1회** — 국면 도중에는 돌리지 않는다. 풀빌드를 포함한 Step 6도 매 사이클 대상이 아니다. (국면이 끝나는 시점에 *실제로 돌릴지*는 아래 ⑥이 정한다 — 바로 `/task-test`로 이어가면 격리 세션의 실행으로 갈음한다.)
160
- 3. **테스트 러너가 빌드를 포함하지 않으면 빌드를 선행**한다 — 옛 산출물로 돌면 이미 고친 결함이 남아 있는 것처럼 보여 없는 버그를 쫓게 된다 (recordion에서 이 때문에 30분을 소모했다). 어느 명령이 빌드를 포함하는지는 `TEST_RULE.local.md`에 기록해 재사용한다.
161
- 4. **무관한 테스트가 깨질 때만 범위를 넓힌다** — 예상 밖 실패가 나오면 그때 상위 범위로 확대한다.
162
- 5. **회귀 누락 위험은 2 + `/task-test` 격리 세션의 이중 게이트가 막는다.** 좁힌 범위 때문에 회귀를 놓친다는 우려로 매 사이클 전체를 도는 것은 비용 대비 효과가 없다.
163
- 6. **`/task-test`로 바로 이어갈 때는 2의 전체 1회를 생략한다** — 격리 세션이 `## 검증 명령`·`## 테스트 명령`을 다시 전부 실행하므로 같은 스위트를 연달아 두 번 돌리는 셈이 된다. 세션이 `developed`에서 멈추고 사용자에게 제어를 넘길 때만 메인이 전체를 1회 실행한다. (결과: 전체 스위트는 태스크당 원칙 1회.)
164
-
165
- **테스트 신설은 요구 범위에 비례** — 신설하는 테스트는 *본 task 요구사항을 덮는 데 필요한 최소*로 둔다. 기존 스펙이 이미 덮는 영역을 중복 검증하는 테스트를 새로 만들지 않는다. 스위트가 커질수록 이후 모든 task의 재실행 비용이 늘어난다. 프로젝트별 상한(예: *"E2E는 핵심 흐름만"*)은 `.project/rules/TEST_RULE.local.md`가 있으면 그쪽을 우선한다.
166
-
167
- **FAIL 시**: Step 6의 FAIL 룰 동일 적용 (추측 fix 반복 방지 / 진단 로그 / 동일 신고 재발 시 root cause).
168
-
169
- ### Step 7 — Result 섹션 진행 기록
170
-
171
- `## Result` 섹션의 *진행* 부분 Edit (테스트 결과는 `/task-test`에서 채움):
172
-
173
- ```markdown
174
- ## Result
175
-
176
- ### 진행
177
- - Phase 1: <구현 요약 — 변경 파일 / 핵심 로직>
178
- - Phase 2: <...>
179
- - Phase N: <...>
180
-
181
- ### 테스트 (격리 세션 결과)
182
- (`/task-test`에서 채움)
183
- ```
184
-
185
- - 각 Phase 한두 줄로 무엇을 어떻게 했는지 요약.
186
- - 변경 파일 목록 명시 (예: `src/auth/login.ts` 신규, `src/api/auth.test.ts` 12 케이스 추가).
187
-
188
- ### Step 8 — status 전환 + 결과 보고
189
-
190
- 1. `set_status` 도구로 `developed` 전이 (또는 `npx @angar2/taskery set-status TASK-<NNN> developed`) — self-check + 테스트 PASS 후. (유효전이 코드 검증.) 수정 루프 국면을 거쳐 곧바로 `/task-test`로 이어가는 경우에는 Step 6.5 ⑥에 따라 *린트·타입체크 + 변경이 닿는 테스트 PASS*가 전이 근거이며, 전체 스위트는 격리 세션이 실행한다.
191
- 2. 결과 보고:
192
-
193
- ```
194
- ✅ TASK-<NNN> 구현 완료
195
- - Phase: <N>개 모두 [x]
196
- - 변경 파일: <목록>
197
- - self-check: lint/typecheck/build/test 모두 PASS
198
- - 상태: developing → developed
199
- - 다음: /task-test TASK-<NNN> 으로 격리 세션 검증
200
- ```
201
-
202
- ### Step 9 — 검수 서버 기동 (중단점·해당 시)
203
-
204
- **조건**: ① 이번 세션이 여기서 멈추고 사용자에게 제어를 넘김(= `/task-test`로 계속 진행하지 않음) + ② `AGENTS.md`에 `## 검수 실행 명령`이 선언됨.
205
-
206
- - 두 조건 충족 시 — 그 명령으로 서버를 *백그라운드* 기동(포트 = 기준 포트 + TASK번호) + 접속 URL 보고. 모바일 검수가 필요하다고 판단되면 터널도 기동.
207
- - `/task-test`로 계속 진행하면 본 단계 생략 (마지막 단계에서만 기동 — 상세: GIT_RULE "멀티세션 검수 환경").
208
- - `## 검수 실행 명령` 미선언(CLI/라이브러리 등) 또는 사용자 *"안 띄워도 돼"* 발화 시 생략.
209
- - **기동 전 확인 필수** — 새로 띄우기 전에 해당 포트·프로세스가 이미 살아 있는지 확인한다. `Port … is in use` 류 경고는 *이미 떠 있다*는 뜻이므로 무시하고 재기동하지 않는다. 종료할 때는 부모 프로세스만이 아니라 **자식 프로세스(브라우저·렌더러 창 등)까지** 확인해 정리한다 (recordion FRICTION 2026-08-05 — 중복 기동 + 창 잔존으로 두 번 지적, TASK-005 재발).
210
-
211
- ## 도구 가이드
212
-
213
- - **Read**: task 파일 / `AGENTS.md` 검증 명령 / 관련 코드 정독
214
- - **Edit / Write**: 코드 작성 + Phase 체크박스 갱신 + Result 섹션 갱신
215
- - **Bash / 도구**: 검증 명령 실행 (린트/타입/빌드/단위테스트) / `set_status` 도구(또는 `npx @angar2/taskery set-status`) status 전이. **git 명령 절대 X — `/task-close`만 git 담당**
216
- - **Grep / Glob**: 추가 코드 탐색 (Phase 진행 중 인접 영향 발견 시)
217
-
218
- ## 주의사항
219
-
220
- - **git 명령 절대 X** — 본 스킬은 코드만. `git commit` / `git push` / `git branch` 등 모두 `/task-close`에서. self-check fail 후 *재실행*도 git 무관.
221
- - **Phase 순서 건너뛰기 X** — Phase 1 끝나기 전 Phase 2 진행 X. 의존 관계 깨짐 + 디버깅 어려워짐.
222
- - **계획 외 스코프 확장 X** — Dev Plan에 없는 파일 다루기 전 사용자 confirm. *"이 부분 같이 작업해야 할 것 같은데 OK?"* 합의 후 진행.
223
- - **모호 발화 confirm 룰 (stash FRICTION_LOG #21+22 반영)** — 사용자 발화가 코드/문서/기능 영역에서 *복수 매칭* 가능할 때 자율 추정 영구 금지. 메인 *자체 안 1개* + *"X 의미 맞아?"* 한 줄 confirm 후 진행. 옵션 4개 늘어놓기 금지 (메인 판단 위임 회피 패턴). 예: 사용자 *"환경설정 아이콘"* 발화 → popover 톱니 / Settings 탭바 아이콘 둘 다 가능 → 어느 영역인지 한 줄 confirm 필수.
224
- - **디자인 산출 정독 의무 (stash FRICTION_LOG #14+19 / #12 일반화)** — task에 디자인 산출 (HTML 목업 / Figma / 디자인 파일 등) 있으면 메인이 *직접 Read* 후 구현. sub-agent 위임 금지 (요약만 받아 디자인 정합 깨짐). 구현 = 디자인 산출 기준 (역방향 X — 코드 편의로 디자인 어김 절대 X). 목업 위치 = `.project/tasks/<NNN_slug>/mockup/<task-doc-name>-mockup.html`.
225
- - **self-check FAIL 시 `developed` 전환 X** — 무리하게 상태 갱신 금지. 메인 자체 수정 시도 → 안 되면 사용자에게 보고. *"잘 될 거야"* 가정 금지.
226
- - **로그 심기 잊지 X** — Dev Plan 작성 시 `[로그]` 항목 명시되어 있으면 *반드시* 실제 로그 코드 삽입. 격리 세션 / 운영 디버깅 모두 의존.
227
- - **Result 섹션 진행만** — 테스트 결과는 `/task-test`가 기록. 메인이 *"잘 됐을 거야"* 가정 작성 금지.
228
- - **flows/ 업데이트 누락 X** — 신규 기능 / 로직 변경이면 `.project/flows/<module>.md` 갱신. 미갱신 시 다음 task가 옛 정보 보고 헤맴.
229
- - **워크트리에서 앱 실행·검수 시 의존성 심링크 금지** — 워크트리엔 의존성·빌드 산출물이 없는데, 메인 워크트리에서 심링크로 끌어오면 개발 서버 등이 로딩 실패(빈 화면)한다. 실행·검수하는 task면 워크트리 안에 실제로 의존성을 마련한다. 상세: GIT_RULE "워크트리 실행 환경" 섹션.
230
-
231
- ## 상태 전이
232
-
233
- | 진입 시 | 종료 시 |
234
- |--------|--------|
235
- | `planned` | `developed` |
236
- | `developing` (이어가기) | `developed` |
237
-
238
- self-check FAIL → `developing` 그대로 유지 (수정 + 재PASS 시까지).
239
-
240
- **self-check 게이트 hard-fail 조건**:
241
- - 완료 조건 미체크 (Phase `진행: [ ]` 잔존) → `developed` 전환 차단
242
- - Bash 에러 (검증 명령 fail) → `developed` 전환 차단
243
- - 보안 취약점 — 메인 자체 검토 (1차 자기검토. 진짜 데이터 모이면 PLAYBOOK §7 자동 PR 리뷰 부활)
29
+ - `test-code` (명령 등록은 `test-code --register`)