@angar2/taskery 0.1.0 → 0.1.2

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 (30) hide show
  1. package/README.md +207 -65
  2. package/bin/init.js +45 -2
  3. package/bin/lib.js +397 -3
  4. package/bin/prune.js +189 -0
  5. package/bin/status.js +148 -0
  6. package/bin/taskery.js +25 -0
  7. package/bin/update.js +26 -2
  8. package/package.json +7 -3
  9. package/template/.claude/hooks/closed-immutable.sh +5 -4
  10. package/template/.claude/hooks/git-guard.sh +1 -1
  11. package/template/.claude/settings.json +1 -2
  12. package/template/.claude/skills/add-backlog/SKILL.md +117 -0
  13. package/template/.claude/skills/log-friction/SKILL.md +76 -0
  14. package/template/.claude/skills/{plan-init.md → plan-init/SKILL.md} +28 -4
  15. package/template/.claude/skills/{project-init.md → project-init/SKILL.md} +60 -7
  16. package/template/.claude/skills/task-close/SKILL.md +351 -0
  17. package/template/.claude/skills/{task-dev.md → task-dev/SKILL.md} +54 -8
  18. package/template/.claude/skills/task-init/SKILL.md +283 -0
  19. package/template/.claude/skills/{task-plan.md → task-plan/SKILL.md} +115 -18
  20. package/template/.claude/skills/{task-test.md → task-test/SKILL.md} +60 -18
  21. package/template/.project/FRICTION_LOG.md +6 -13
  22. package/template/.project/rules/CHANGELOG_RULE.md +91 -0
  23. package/template/.project/rules/GIT_RULE.md +119 -8
  24. package/template/.project/rules/MOCKUP_RULE.md +85 -0
  25. package/template/.project/rules/TASK_DOC_RULE.md +78 -76
  26. package/template/CLAUDE.md +77 -12
  27. package/template/.claude/hooks/pre-commit-verify.sh +0 -97
  28. package/template/.claude/skills/refine.md +0 -177
  29. package/template/.claude/skills/task-close.md +0 -178
  30. package/template/.claude/skills/task-init.md +0 -142
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: project-init
2
3
  description: taskery 도입 직후 1회성 — PROJECT.md / AGENT-GUIDE.md / LINKED-REPOS.md / .env 빈 골격 생성
3
4
  ---
4
5
 
@@ -91,29 +92,56 @@ taskery 도입 직후 **1회성**으로 호출. 사용자 또는 동료가 새
91
92
  1. `CLAUDE.md` — 프로젝트 메타 + 검증 명령 + 룰 참조
92
93
  2. `.project/PROJECT.md` — 프로젝트 개요
93
94
  3. `.project/plans/<활성버전>/PLAN.md` — 활성 plan 진입 (이게 9 기획 문서 인덱스)
94
- 4. `.project/AGENT-GUIDE.md` — 본 파일 (그대로)
95
+ 4. `.project/GLOSSARY.md` — 도메인 용어집 (영문/한글 표기 일관성 단일 진실 소스)
96
+ 5. `.project/tasks/<활성버전>/BACKLOG.md` — 현재 plan 진행 중 누적된 후속 task 후보 (사용자 발화 *"이건 다음 task로"* / task-close 직후 메인 감지로 추가)
97
+ 6. `.project/AGENT-GUIDE.md` — 본 파일 (그대로)
95
98
 
96
99
  ## 작업 흐름
97
100
  - task 시작: `/task-init` 또는 `/task-plan`
98
101
  - task 진행: `/task-dev` → `/task-test` → `/task-close`
99
- - 회고: `/refine` (5 task마다 또는 사용자 호출)
102
+ - 불편 등록: `/log-friction` (사용자 호출 / 발화 캐치 / task-close 자체 감지)
100
103
 
101
104
  ## 폴더 구조
102
- - `.project/rules/` — 코어 룰 (TASK_DOC_RULE / GIT_RULE)
105
+ - `.project/rules/` — 코어 룰 (TASK_DOC_RULE / GIT_RULE / CHANGELOG_RULE / MOCKUP_RULE)
103
106
  - `.project/plans/<vX.X>/` — 9 기획 문서
104
107
  - `.project/tasks/<vX.X>/` — task 문서
105
108
  - `.project/flows/` — 도메인 흐름
106
109
  - `.project/shared/` — 멀티리포 메시지
107
110
  - `.project/changelog/` — 월별 변경 이력
108
- - `.project/FRICTION_LOG.md` — 짜증 데이터
111
+ - `.project/FRICTION_LOG.md` — 불편 데이터
109
112
 
110
113
  ## 멀티리포
111
114
  <단일 리포면 "단일 리포. LINKED-REPOS.md 빈 템플릿."
112
115
  멀티 리포면 "LINKED-REPOS.md 참조">
113
116
  ```
114
117
 
118
+ ### Step 4.5 — `.project/GLOSSARY.md` 작성 (도메인 용어집)
119
+
120
+ stash FRICTION_LOG #3 반영 — 프로젝트 도메인 용어를 *영문/한글 표기 일관성* 단일 진실 소스로 모음. 코드 메서드명·변수명 / 대화·문서 한글 표기 통일.
121
+
122
+ ```markdown
123
+ # GLOSSARY — <프로젝트명>
124
+
125
+ > 본 프로젝트에서 사용하는 도메인 용어집. 코드 식별자 / 문서 / 대화 모두 본 표 기준.
126
+ > 새 용어 추가 시 영문 알파벳 순 정렬 유지.
127
+
128
+ | 영문 | 한글 | 정의 | 출처 |
129
+ |------|------|------|------|
130
+ | | | | |
131
+
132
+ ## 운용 룰
133
+
134
+ - 영문 알파벳 순 정렬
135
+ - 출처: 본 용어가 도입된 task/plan 문서 경로 (예: `plans/v1.0/FEATURES.md`)
136
+ - 동의어 / 변형 표기 발견 시 본 표 기준으로 정합
137
+ ```
138
+
139
+ 빈 표만 작성. 본문은 plan/task 진행하면서 사용자가 채움.
140
+
115
141
  ### Step 5 — `.project/LINKED-REPOS.md` 작성
116
142
 
143
+ 멀티리포 구성 명세. 단일 리포면 빈 템플릿만, 멀티 리포면 연결 리포 목록까지.
144
+
117
145
  ```markdown
118
146
  # LINKED-REPOS.md
119
147
 
@@ -152,7 +180,7 @@ taskery 도입 직후 **1회성**으로 호출. 사용자 또는 동료가 새
152
180
  - `.project/tasks/` (`.gitkeep` — `/task-init`이 `vX.X/<NNN>_<slug>.md` 작성)
153
181
  - `.project/shared/{sent,received}/completed/` (`.gitkeep`)
154
182
  - `.project/FRICTION_LOG.md` (빈 템플릿)
155
- - `.project/rules/{TASK_DOC_RULE,GIT_RULE}.md` (코어 룰)
183
+ - `.project/rules/{TASK_DOC_RULE,GIT_RULE,CHANGELOG_RULE,MOCKUP_RULE}.md` (코어 룰)
156
184
 
157
185
  → `/project-init`은 폴더 생성 X. 누락 시(`init` 안 거치고 수동 셋업한 경우)에만 `mkdir -p` 실행.
158
186
 
@@ -164,15 +192,40 @@ mkdir -p .project/shared/sent/completed .project/shared/received/completed
164
192
 
165
193
  `.project/FRICTION_LOG.md`도 `init`이 카피한 빈 템플릿 그대로 사용. **이미 있으면 덮어쓰기 X** — 사용자 데이터 보호.
166
194
 
195
+ ### Step 7.5 — git 초기화 + 첫 ref 분기 (빈 폴더 케이스)
196
+
197
+ `git status`가 *fatal: not a git repository* 에러면 빈 폴더 진입 케이스. 다음 4단계 실행:
198
+
199
+ ```bash
200
+ git status 2>&1 | head -1
201
+ # "fatal: not a git repository" 면 미초기화
202
+ ```
203
+
204
+ 미초기화 시:
205
+
206
+ ```bash
207
+ git init
208
+ git commit --allow-empty -m "chore: root commit" # ref 생성용 (commit 0 상태에선 branch 만들어도 ref 안 박힘)
209
+ git symbolic-ref --short HEAD # 현재 default branch 확인 (예: main 또는 master)
210
+ git branch dev # 같은 sha에 dev 분기
211
+ git branch -a # main(또는 master) + dev 둘 다 떠야 함
212
+ ```
213
+
214
+ 이렇게 하지 않으면 첫 task `git checkout -b feature/...`까지는 동작하지만 **dev 브랜치 ref 자체가 없어서** `--no-ff` 머지 시점에 막힘. 사용자가 수동 `git branch dev <root-sha>` 매핑 필요.
215
+
216
+ 이미 git 초기화된 리포면 (status 정상) 이 step 건너뜀.
217
+
218
+ > root commit이 빈 commit으로 박히는 게 싫으면 생략 가능. 단 그러면 첫 task chore commit이 박히기 *전엔* dev/main ref 못 만듦 → 첫 머지 직전에 사용자/메인이 명시 매핑 필요.
219
+
167
220
  ### Step 8 — 결과 보고
168
221
 
169
222
  작성된 파일 목록 + 다음 단계 안내:
170
- - *"PROJECT.md / AGENT-GUIDE.md / LINKED-REPOS.md / .env 생성. (FRICTION_LOG.md / 빈 골격 폴더는 npx init이 이미 카피한 것 그대로). 다음은 `/plan-init <버전명>`으로 9 기획 문서 작성."*
223
+ - *"PROJECT.md / AGENT-GUIDE.md / LINKED-REPOS.md / GLOSSARY.md / .env 생성. (FRICTION_LOG.md / 빈 골격 폴더는 npx init이 이미 카피한 것 그대로). **빈 폴더 케이스라 git init + dev 분기까지 완료** (이미 git 리포면 건너뜀). 다음은 `/plan-init <버전명>`으로 9 기획 문서 작성."*
171
224
 
172
225
  **결과 commit 흐름** (GIT_RULE 정합):
173
226
  - dev 직접 commit *금지* (git-guard.sh 차단). 두 가지 default 흐름:
174
227
  1. **첫 task에 묶기 (권장)**: `/plan-init` 끝나고 첫 `/task-init` (보통 TASK-001 부트스트랩 chore)으로 만든 작업 브랜치에서 init 산출물(PROJECT/AGENT-GUIDE/LINKED-REPOS/.env)도 함께 commit. task-close 단계의 "태스크 문서 커밋"에 자연스럽게 묶임.
175
- 2. **임시 docs 브랜치**: `git checkout -b docs/{개발자}_init-bootstrap` 후 commit → dev에 `--no-ff` 머지. 첫 task 생성 *전*에 init 결과를 깔끔히 박고 싶을 때.
228
+ 2. **임시 docs 브랜치**: `git checkout -b docs/{개발자}_init-bootstrap` 후 commit → dev에 `--no-ff` 머지. 첫 task 생성 *전*에 init 결과를 깔끔히 기록하고 싶을 때.
176
229
 
177
230
  ## 도구 가이드
178
231
 
@@ -0,0 +1,351 @@
1
+ ---
2
+ name: task-close
3
+ description: task git 마무리 — 검증 게이트 + 커밋 순서 + 머지 락 직렬화 + dev --no-ff 병합 + 워크트리/브랜치 자동 정리, tested → closed (멀티세션 0.1.2+)
4
+ ---
5
+
6
+ # /task-close
7
+
8
+ ## 개요
9
+
10
+ `tested` 상태 task의 git 마무리. **워크트리에서 호출** 권장. 사전 rebase → 충돌 해결 (3단계 에스컬레이션) → 머지 락 → 락 안 재 rebase → dev `--no-ff` 머지 → 워크트리 제거 + 작업 브랜치 자동 삭제.
11
+
12
+ **최종 게이트**: 모든 검증 명령 재실행 — 린트/타입체크/빌드 PASS여야 진행.
13
+
14
+ ## 호출 시점
15
+
16
+ - `/task-test` PASS 후 + 사용자 OK.
17
+ - `/task-test` FAIL 후 사용자 *"OK 마무리"* (알려진 결함 명시 채로).
18
+
19
+ ## 호출 위치 정책
20
+
21
+ - **워크트리에서 호출 권장** (CWD = 워크트리 폴더).
22
+ - **메인 워크트리에서 호출 시** → 진행중 태스크 목록 인터뷰 + 사용자 선택 → 해당 워크트리 컨텍스트로 진행.
23
+
24
+ ## 입력 처리
25
+
26
+ 인자 = (선택) `TASK-NNN` 또는 자동 선택.
27
+
28
+ 분기:
29
+ - **인자 명시**: 해당 task.
30
+ - **인자 없음**: 워크트리에서 호출 시 *그 워크트리의 태스크* 자동 / 메인에서 호출 시 *상태=tested 가장 최근 task* 인터뷰.
31
+
32
+ ## 핵심 변수
33
+
34
+ ```sh
35
+ MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
36
+ WT_PATH=$(pwd) # 워크트리에서 호출됐다고 가정 (메인 호출 시 사용자 선택 결과)
37
+ PROJECT_ID=$(jq -r '.projectId' "$MAIN_WT/.taskery-manifest.json")
38
+ BRANCH=$(git -C "$WT_PATH" rev-parse --abbrev-ref HEAD)
39
+ LOCK_TIMEOUT_MS=$(jq -r '.lock_timeout_ms // 30000' "$MAIN_WT/.taskery-manifest.json")
40
+ LOCK_FILE="$HOME/.taskery/${PROJECT_ID}.merge.lock"
41
+ ```
42
+
43
+ ## 단계
44
+
45
+ ### Step 1 — 사전 검증
46
+
47
+ 1. **메인 워크트리 검출** (위 핵심 변수).
48
+ 2. **메인 워크트리 = dev 검증**:
49
+ ```sh
50
+ CURRENT=$(git -C "$MAIN_WT" rev-parse --abbrev-ref HEAD)
51
+ [ "$CURRENT" = "dev" ] || abort "메인 워크트리가 dev 아님 (현재: $CURRENT). taskery 정책 위배"
52
+ ```
53
+ 3. **워크트리 미커밋 변경 확인**:
54
+ ```sh
55
+ git -C "$WT_PATH" status --porcelain
56
+ ```
57
+ - 결과 *있음* = 정상 흐름 (taskery 정책: `/task-dev` = *git 작업 X*). 본 변경분은 Step 6-3에서 *task-close가 자동 Phase 커밋 생성*으로 처리.
58
+ - 결과 *없음* = 변경분 0건 → Step 2 검증만 수행 후 Step 6-3 자동 커밋 단계 자연 스킵 (빈 커밋 X).
59
+ - **차단 X** — 본 단계는 *상태 인지*용. close 중단 사유 X.
60
+ 4. **task 파일 + GIT_RULE 확인**:
61
+ - task 문서 위치 분기 (`.gitignore` 케이스):
62
+ ```sh
63
+ git -C "$MAIN_WT" check-ignore -q "$MAIN_WT/.project/dummy"
64
+ ```
65
+ - exit 0 (등록됨): `$MAIN_WT/.project/tasks/<vX.X>/...` (단일 소스)
66
+ - exit 1 (미등록): `$WT_PATH/.project/tasks/<vX.X>/...` (워크트리 안)
67
+ - 상태 = `tested` 검증. 그 외면 종료 (단 알려진 결함 *"OK 마무리"*는 status=tested로 명시되어 있어야 함).
68
+ - GIT_RULE Read 우선순위:
69
+ - `$MAIN_WT/.project/rules/GIT_RULE.md` (프로젝트별 — 우선)
70
+ - `~/.claude/rules/GIT_RULE.md` (글로벌)
71
+ 둘 다 없으면 종료 + *"GIT_RULE 누락"* 보고.
72
+
73
+ ### Step 2 — 최종 검증 명령 재실행 (게이트)
74
+
75
+ `$MAIN_WT/CLAUDE.md`의 `## 검증 명령` (빌드/린트/타입체크) 만 재실행. **하나라도 FAIL이면 close 차단**.
76
+
77
+ | 명령 | 결과 |
78
+ |------|------|
79
+ | 린트 | exit 0 + 에러 0 |
80
+ | 타입체크 | exit 0 |
81
+ | 빌드 | exit 0 |
82
+
83
+ > 테스트 명령은 본 게이트에서 실행 X. `/task-test` 격리 세션이 단일 시점 (stash FRICTION_LOG #25).
84
+
85
+ > **검증 명령 실행 위치**: 워크트리(`$WT_PATH`)에서. 코드 변경은 워크트리 안에 있으므로 검증 대상도 거기.
86
+
87
+ FAIL 시:
88
+ - 사용자에게 보고 — *"검증 명령 X가 FAIL. 어떻게 할까?"*
89
+ - 분기:
90
+ - *"고쳐"* → status `developing`으로 되돌림 + `/task-dev` 안내 + close 중단.
91
+ - *"OK 마무리"* → 결함 명시한 채 진행 (Result 섹션에 *"검증 명령 X FAIL 알려진 결함 — 사유: ..."* 추가).
92
+
93
+ ### Step 3 — 사전 rebase (락 외, UX용 조기 충돌 감지)
94
+
95
+ ```sh
96
+ git -C "$WT_PATH" rebase dev
97
+ ```
98
+
99
+ - 충돌 없음 → Step 6으로 (커밋 순서).
100
+ - 충돌 있음 → Step 4 (3단계 에스컬레이션).
101
+
102
+ ### Step 4 — 충돌 자체 해결 (3단계 에스컬레이션)
103
+
104
+ #### 4-a. 단순 충돌 → 자동 해결
105
+
106
+ - 공백 / 의미 같은 코드 차이 / 주석 / 명백한 add-add
107
+ - 자동 해결 후 `git -C "$WT_PATH" rebase --continue`
108
+
109
+ #### 4-b. 의미적 충돌 → 자료 분석
110
+
111
+ **자료 우선순위**:
112
+
113
+ | 순위 | 자료 | 위치 |
114
+ |------|------|------|
115
+ | 1 | 태스크 문서 + plan 문서 (양쪽 정독 후 의도 종합) | 태스크: `$MAIN_WT/.project/tasks/<vX.X>/...` (등록 케이스) / `~/.taskery/worktrees/<projectId>/TASK-...` 다른 워크트리 (미등록 케이스, SSoT 조회로 경로 산출). plan: `$MAIN_WT/.project/plans/<vX.X>/` (ROADMAP / FEATURES / ARCHITECTURE / TECH-STACK 등) |
116
+ | 2 | 커밋 메시지 | `git log dev --grep` (GIT_RULE 풍부 메시지) |
117
+ | 3 | diff | 변경 코드 자체 |
118
+
119
+ - 1순위 부재 시 2/3순위 자동 fallback + 사용자에게 *자료 한계* 보고
120
+ - 태스크 문서 = 본 task의 *세부 의도* / plan 문서 = *전체 의도* (Stage 순 / 의존 그래프 / 의도된 위치 분리). 충돌 영역의 *그림 전체*는 plan 문서가 더 명확한 경우 많음 (Stage 순서로 *먼저 머지된 쪽 다음 줄에 추가* 등)
121
+ - 정독 후 *의미 의도 추출* → 충돌 해결 → `git rebase --continue`
122
+
123
+ #### 4-c. 판단 불가 → 사용자 호출
124
+
125
+ - 해결 방향 후보 제시 + 사용자 결정 후 재개.
126
+ - 사용자가 중단 결정 시: `git -C "$WT_PATH" rebase --abort` 자동 + close 중단.
127
+
128
+ ### Step 5 — 태스크 문서에 충돌 해결 내역 추가 (해당 시)
129
+
130
+ 충돌 해결 1건이라도 발생했으면 task 문서에 기록.
131
+
132
+ `.gitignore` 케이스 분기:
133
+
134
+ | 케이스 | 위치 | 흐름 |
135
+ |--------|------|------|
136
+ | 미등록 | `$WT_PATH/.project/tasks/<vX.X>/...` | 워크트리 안 task 문서 수정 → Step 6 Phase 커밋에 *코드 + 문서 = 한 커밋*에 포함 |
137
+ | 등록 | `$MAIN_WT/.project/tasks/<vX.X>/...` | 워크트리 안 코드만 한 커밋 + 메인 워크트리 절대 경로 task 문서를 **proper-lockfile**로 별도 수정 (`bin/lib.js` `withMetaLock` — 머지 커밋 미포함, 메인 로컬 보존) |
138
+
139
+ 기록 형식 (task.md Result 섹션 안):
140
+ ```markdown
141
+ ### 충돌 해결 (close 직전 rebase)
142
+ - 자료 우선순위: 태스크 문서 (다른 세션 TASK-XXX) / 커밋 메시지 / diff
143
+ - 자료 한계 보고: (있으면 명시)
144
+ - 해결 방향: <한 줄 요약>
145
+ - 영향 파일: <목록>
146
+ ```
147
+
148
+ ### Step 6 — 머지 락 획득 + 락 안 재 rebase + 커밋 시퀀스
149
+
150
+ #### 6-1. 머지 락 획득
151
+
152
+ `bin/lib.js` `withMergeLock(projectId, fn, opts)` 호출. 내부 동작:
153
+
154
+ ```js
155
+ // proper-lockfile
156
+ await lockfile.lock(LOCK_FILE, {
157
+ stale: LOCK_TIMEOUT_MS,
158
+ retries: { retries: 5, factor: 1, minTimeout: 1000, maxTimeout: 1000 },
159
+ });
160
+ ```
161
+
162
+ 재시도 모두 실패 시 → 사용자 보고 + 중단.
163
+
164
+ #### 6-2. 락 안에서 rebase 재실행
165
+
166
+ ```sh
167
+ git -C "$WT_PATH" rebase dev
168
+ ```
169
+
170
+ 락 외 rebase 이후 *다른 세션이 dev 머지했을 수 있음* — 락 안 rebase로 흡수.
171
+ - 재충돌 발견 시 Step 4 에스컬레이션 재실행 + Step 5 문서 기록 재실행.
172
+
173
+ #### 6-3. Phase 기능 커밋 (Dev Plan 각 Phase마다 1개 — task-close가 자동 생성)
174
+
175
+ > **책임 영역**: taskery 정책상 `/task-dev` = *git 작업 X* (워크트리 코드만 수정). 본 단계가 *task-close가 uncommitted 변경분 정독 → task.md `## Dev Plan` Phase 진행 [x] 매핑 → Phase별 commit 자동 생성*하는 단일 진입점이다.
176
+
177
+ 자동 생성 절차:
178
+
179
+ 1. **uncommitted 변경분 정독**:
180
+ ```sh
181
+ git -C "$WT_PATH" status --porcelain
182
+ git -C "$WT_PATH" diff --name-only
183
+ ```
184
+ 2. **task.md `## Dev Plan` 정독** — Phase별 `진행: [x]` + 파일 매핑 추출.
185
+ 3. **Phase ↔ 변경 파일 매핑**:
186
+ - 한 Phase가 단독 파일 영역이면 → Phase별 1 커밋.
187
+ - 같은 파일이 여러 Phase에 걸쳐 있으면 → *단일 통합 커밋 1개*로 묶음 (Phase 번호 표기는 *Phase X+Y*).
188
+ - 매핑 모호 / Dev Plan 본문 추적 불가 시 → 사용자 호출 + 결정 (자동 진행 X).
189
+ - 메시지 형식 (GIT_RULE.md):
190
+ ```
191
+ {태그}: [TASK-<NNN>] Phase <N> - <작업 요약>
192
+
193
+ - <처리 내용 1>
194
+ - <처리 내용 2>
195
+ - 사유: <변경 이유>
196
+ ```
197
+ - 태그: feature → `feat:`, bug → `fix:`, improvement → `improve:`, refactor → `refactor:`, docs/chore → `docs:`, 테스트 → `test:`
198
+
199
+ > **GIT_RULE 풍부 메시지** — 본 메시지는 *충돌 해결 자료 2순위*로 쓰인다. 의도 한 줄 압축.
200
+
201
+ > **자동 분리 로직 코드 구현**은 본 SKILL.md 영역 외 — 메인 세션이 본 절차를 따라 *수동/대화형* 진행. 향후 `bin/lib.js`에 `splitUncommittedByPhase(wtPath, taskMd)` 영역 별도 라운드.
202
+
203
+ #### 6-4. flows/ 모듈 커밋 (해당 시)
204
+
205
+ `$WT_PATH/.project/flows/<module>.md` 변경분 있으면 별도 커밋:
206
+ ```
207
+ docs: [TASK-<NNN>] flows/<module>.md 갱신
208
+ ```
209
+
210
+ - **`.gitignore` 미등록 케이스 한정** — 등록 케이스는 *워크트리 외부* 메인 워크트리 직접 수정 + `withMetaLock`.
211
+
212
+ #### 6-5. task 파일 status → `closed` Edit
213
+
214
+ closed-immutable.sh hook *허용* 영역 (status=closed 적용된 *후* 재수정이 차단).
215
+
216
+ - **.gitignore 등록 케이스**: 메인 워크트리 task 문서를 `withMetaLock`으로 status=`closed` 갱신.
217
+ - **.gitignore 미등록 케이스**: 워크트리 안 task 문서를 Edit.
218
+
219
+ #### 6-6. 태스크 문서 커밋 (미등록 케이스 한정)
220
+
221
+ ```
222
+ docs: [TASK-<NNN>] 태스크 문서 완료
223
+ ```
224
+
225
+ - 대상: `$WT_PATH/.project/tasks/<vX.X>/<NNN>_<slug>.md` (단일) 또는 `.../TASK-<NNN>_<slug>/task.md` (폴더 승격) + spec-diffs / screenshots / mockup (vX.X 공통, TASK_DOC_RULE §1.5).
226
+ - **등록 케이스**: Step 6-5에서 메인 워크트리 직접 수정으로 처리 — 별도 커밋 X (워크트리 머지에 포함 X).
227
+
228
+ #### 6-7. CHANGELOG 커밋 (해당 시)
229
+
230
+ `$MAIN_WT/.project/rules/CHANGELOG_RULE.md` 정독 후 형식 / 위치 준수.
231
+
232
+ - 위치 분기:
233
+ - 미등록 — 워크트리 안 `$WT_PATH/.project/changelog/<YYYY-MM>.md` 갱신 + 커밋
234
+ - 등록 — `$MAIN_WT/.project/changelog/<YYYY-MM>.md` `withMetaLock` 갱신 (커밋 X)
235
+ - 본 task에서 변경분 없으면 본 단계 *완전히 스킵* (빈 commit 금지).
236
+
237
+ ### Step 7 — 메인 워크트리 uncommitted 검증 (머지 직전)
238
+
239
+ ```sh
240
+ git -C "$MAIN_WT" status --porcelain
241
+ ```
242
+
243
+ - 변경 있으면 → 사용자 호출 + 결정 (stash / 중단).
244
+ - 등록 케이스에서 task 문서 직접 수정이 *.gitignore 차단으로 status에 안 잡힘* — 정상.
245
+
246
+ ### Step 8 — dev 머지
247
+
248
+ ```sh
249
+ git -C "$MAIN_WT" merge --no-ff "$BRANCH"
250
+ ```
251
+
252
+ - `-m` 옵션 금지 (git 기본 메시지).
253
+ - 머지 커밋 해시 캡처: `MERGE_COMMIT=$(git -C "$MAIN_WT" rev-parse HEAD)`
254
+
255
+ ### Step 9 — 머지 락 해제
256
+
257
+ `withMergeLock` 콜백 종료 시 자동 release.
258
+
259
+ ### Step 10 — 마찰 신호 자체 감지 (`/log-friction` 발동 후보)
260
+
261
+ 본 task 진행 중 *마찰 신호* 누적 여부를 검사. 감지 시 `/log-friction` 등록을 사용자에게 제안.
262
+
263
+ 검사 항목:
264
+ - 동일 단계 재호출 ≥ 2회
265
+ - 실패 반복 (검증 명령 FAIL 2회 이상 / 격리 세션 FAIL 후 재구현 반복)
266
+ - 사용자 부정 반응 발화 누적
267
+ - **충돌 해결에서 *판단 불가 (4-c)* 1회 이상** — 멀티세션 자료 한계 신호
268
+
269
+ 분기:
270
+ - 감지 신호 있음 → *"이번 task에서 X 부분이 마찰이었어 보여 — `/log-friction`으로 등록할까?"* OK 시 자동 발동.
271
+ - 없음 → prompt X.
272
+
273
+ ### Step 11 — worktree remove 사전 검증
274
+
275
+ ```sh
276
+ git -C "$WT_PATH" status --porcelain # unstaged
277
+ git -C "$WT_PATH" ls-files --others --exclude-standard # 추적 X 파일
278
+ ```
279
+
280
+ - 발견 시 사용자 호출 + 결정:
281
+ - 보존 → Step 12, 13 모두 건너뜀 (브랜치도 보존 — 정합)
282
+ - 삭제 → Step 12 진행
283
+ - 취소 → close 중단 (dev 머지는 이미 완료)
284
+
285
+ ### Step 12 — 워크트리 제거
286
+
287
+ ```sh
288
+ git -C "$MAIN_WT" worktree remove "$WT_PATH"
289
+ ```
290
+
291
+ ### Step 13 — 브랜치 자동 삭제 / 보존
292
+
293
+ - **보존 키워드 감지** (`keep` / `--keep-branch` / `브랜치 남겨` / `브랜치 보존` / `브랜치 유지`) → 보존 + 워크트리도 보존 (Step 11~13 건너뛴 것과 정합).
294
+ - **그 외** → `git -C "$MAIN_WT" branch -d "$BRANCH"`
295
+
296
+ ### Step 14 — 안전망 출력
297
+
298
+ ```
299
+ 삭제됨: $BRANCH
300
+ 복구: git -C "$MAIN_WT" branch $BRANCH $MERGE_COMMIT
301
+ ```
302
+
303
+ ### Step 15 — 결과 보고
304
+
305
+ ```
306
+ ✅ TASK-<NNN> closed
307
+ - 작업 브랜치: <BRANCH> (삭제 / 보존)
308
+ - 워크트리: <WT_PATH> (제거 / 보존)
309
+ - 커밋: Phase <N>개 + 태스크 문서 + (CHANGELOG)
310
+ - dev 병합: --no-ff 완료 ($MERGE_COMMIT)
311
+ - 충돌 해결: <건수, 자료 한계 보고 있으면 포함>
312
+ - 상태: tested → closed
313
+ - 다음: 새 task 시작은 /task-init. 마찰 신호 감지된 경우 /log-friction 등록 제안
314
+ ```
315
+
316
+ ## 도구 가이드
317
+
318
+ - **Read**: GIT_RULE / task 파일 / CLAUDE.md 검증 명령 정독
319
+ - **Bash**: git 명령 (`branch`, `rebase`, `merge`, `worktree`) + 검증 명령 재실행. **유일하게 git 사용 허가된 스킬**
320
+ - **Edit / Write**: task 파일 갱신, CHANGELOG (메타 위치는 `.gitignore` 케이스에 따라)
321
+ - **bin/lib.js**: `withMergeLock` (머지 락) / `withMetaLock` (메타 파일 쓰기 락)
322
+
323
+ ## 주의사항
324
+
325
+ - **사용자 명시 호출 외 자체 진입 영구 금지** (stash FRICTION_LOG #6+10/#20) — task-close는 git 영역. 사용자가 *"X부터 Y까지"* 범위 명시했는데 Y가 close 이전 단계면 close 자체 진입 영구 X.
326
+ - **검증 명령 재실행 게이트** — `/task-dev` self-check와 *별개*. 환경 변화 / 부분 작업 잡는 안전망.
327
+ - **dev 직접 커밋 절대 X** — 워크트리에서만. dev에서 `git commit` 시도 시 git-guard.sh 차단.
328
+ - **`--no-ff` 강제** — 머지 커밋 없으면 분기 정보 영구 손실.
329
+ - **머지 락 직렬화** — 두 세션이 동시 머지 시도해도 한쪽씩 순차 진행. 락 외 rebase로 race 흡수 + 락 안 재 rebase로 다른 세션 머지 흡수.
330
+ - **충돌 자체 해결 3단계** — 단순 자동 / 의미적 자료 / 판단 불가 사용자. 자료 한계 발견 시 *반드시 사용자에게 보고* (1순위 자료 부재 등).
331
+ - **자료 한계 보고** — 충돌 분석 시 *2/3순위 fallback 사용했음*을 사용자에게 명시. 묵묵히 진행 X.
332
+ - **destructive 명령 사용자 승인 필수** — `git reset --hard` / `git push --force` / `git branch -D` / `git clean -fd` 사용자 명시 승인 없이 절대 실행 X. (단 `/task-close` 자동 흐름 `git branch -d` + `worktree remove`는 §"작업 브랜치 삭제 정책 — 자동 삭제 면제 조항" 면제)
333
+ - **민감 정보 staging X** — `.env` / `credentials.json` / API key 등 staging 절대 X.
334
+ - **빈 commit 금지** — CHANGELOG 변경 없으면 6-7 단계 스킵. `--allow-empty` 사용 금지.
335
+ - **`-m` 옵션 머지 커밋에 사용 금지** — git 기본 메시지 사용.
336
+
337
+ ## 상태 전이
338
+
339
+ | 진입 시 | 종료 시 |
340
+ |--------|--------|
341
+ | `tested` | `closed` |
342
+
343
+ (검증 명령 FAIL + 사용자 *"고쳐"* → `developing`으로 되돌림. 본 스킬 자체는 거기서 중단.)
344
+
345
+ ## 멀티세션 정합
346
+
347
+ - **머지 락** — `~/.taskery/<projectId>.merge.lock` 단일. 모든 세션 직렬화.
348
+ - **task 문서 단일 진실 소스** — `.gitignore` 케이스에 따라 메인 워크트리 또는 워크트리. 다른 세션의 충돌 해결 자료 정독 시 *SSoT 조회 → 워크트리 경로 산출* (미등록 케이스) 또는 *메인 워크트리 절대 경로* (등록 케이스).
349
+ - **워크트리 + 브랜치 자동 제거** — GIT_RULE.md "작업 브랜치 삭제 정책" 면제 조항 (taskery 한정). 보존 키워드 시 양쪽 보존.
350
+ - **safety net** — Step 14 복구 명령 출력. 사용자가 잘못 삭제 인지 시 즉시 복구 가능.
351
+ - **BACKLOG.md 무관** — `.project/tasks/<vX.X>/BACKLOG.md` 체크 마킹은 `/task-init` Step 7.5가 처리(`[ ]` → `[x]` + `- TASK: TASK-NNN`). `[x]` = *task로 옮김* 의미라 close 시점에 추가 마킹 X. 완료 추적은 `git log dev --grep 'BL-NNN'` + `npx @angar2/taskery status`.
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: task-dev
2
3
  description: task 구현 — Dev Plan Phase 순서대로 코드 작성 + self-check 게이트, planned → developing → developed
3
4
  ---
4
5
 
@@ -10,6 +11,23 @@ description: task 구현 — Dev Plan Phase 순서대로 코드 작성 + self-ch
10
11
 
11
12
  self-check 명령은 프로젝트 루트 `CLAUDE.md`의 *검증 명령* 섹션 참조 — 단일 진실 소스.
12
13
 
14
+ ## 멀티세션 메타 위치 (0.1.2+)
15
+
16
+ 본 스킬은 워크트리에서 호출된다. 메타(`.project/`, `CLAUDE.md`) 접근 시 **메인 워크트리 절대 경로** 우선.
17
+
18
+ ```sh
19
+ MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
20
+ ```
21
+
22
+ `.gitignore` 케이스 분기:
23
+
24
+ | 케이스 | task 문서 / Result 갱신 위치 | CLAUDE.md (검증 명령) |
25
+ |--------|---------------------------|----------------------|
26
+ | 등록 (퍼블릭 리포 default) | `$MAIN_WT/.project/tasks/<vX.X>/...` (`bin/lib.js` `withMetaLock`) | `$MAIN_WT/CLAUDE.md` |
27
+ | 미등록 | `$WT_PATH/.project/tasks/<vX.X>/...` (워크트리 안, 머지 시 dev 반영) | `$MAIN_WT/CLAUDE.md` (CLAUDE.md는 단일 소스) |
28
+
29
+ self-check 명령은 워크트리(`$WT_PATH`)에서 실행 — 코드 변경이 워크트리 안에 있으므로 검증 대상도 거기.
30
+
13
31
  ## 호출 시점
14
32
 
15
33
  - `/task-plan` 끝나고 기획 합의된 직후.
@@ -36,7 +54,10 @@ self-check 명령은 프로젝트 루트 `CLAUDE.md`의 *검증 명령* 섹션
36
54
  - `planned` → 신규 진행 (Step 2 status 전환).
37
55
  - `developing` → 이어가기 (Step 2 skip — 이미 developing).
38
56
  - 그 외 → 종료 + 안내.
39
- 4. 프로젝트 루트 `CLAUDE.md` Read → *검증 명령* 섹션의 린트/타입체크/빌드/테스트 명령 추출. 이 명령들이 self-check 게이트의 단일 진실 소스.
57
+ 4. 프로젝트 루트 `CLAUDE.md` Read → 두 섹션 명령 추출:
58
+ - **`## 검증 명령`** (코드 상태 — 빌드/린트/타입체크): self-check 게이트의 단일 진실 소스 (Step 6).
59
+ - **`## 테스트 명령`** (테스트 실행 — 단위/통합/E2E): 구현 후 테스트 실행의 단일 진실 소스 (Step 6.5).
60
+ - stash FRICTION_LOG #25 반영 — 두 섹션 분리. self-check 게이트는 *코드 상태*만, 테스트는 *별도 단계*.
40
61
 
41
62
  ### Step 2 — status 전환 (planned → developing)
42
63
 
@@ -74,21 +95,44 @@ Dev Plan에 Phase 0(plan 문서 변경)이 있으면:
74
95
  | 단순 버그 수정 (로직 변경 없음) | 불필요 |
75
96
  | 스타일/포맷/설정 변경 | 불필요 |
76
97
 
77
- ### Step 6 — self-check 게이트
98
+ ### Step 6 — self-check 게이트 (`## 검증 명령` — 코드 상태)
78
99
 
79
- Step 1에서 추출한 검증 명령을 *전부* 실행. 모두 PASS여야 `developed`로 전이 가능.
100
+ `CLAUDE.md` `## 검증 명령` 섹션의 명령을 *전부* 실행. 모두 PASS여야 다음 단계 (Step 6.5 테스트 실행) 진입 가능. 테스트 명령은 본 게이트에서 실행 X.
80
101
 
81
102
  | 명령 | PASS 기준 |
82
103
  |------|---------|
83
104
  | 린트 (예: `npm run lint`) | exit 0 + 에러 0 |
84
105
  | 타입체크 (예: `npm run typecheck`) | exit 0 |
85
106
  | 빌드 (예: `npm run build`) | exit 0 |
86
- | 단위 테스트 (예: `npm test <범위>`) | 모든 케이스 PASS |
87
107
 
88
- **FAIL 시**:
89
- 1. 메인이 자체 수정 시도 — 에러 메시지 분석 + 코드 수정 + 재실행.
90
- 2. 같은 종류 fail이 3회 반복되면 사용자에게 보고 + 판단 요청 (*"이 에러가 풀리지 않아. 추가 정보 필요"*).
91
- 3. 수정 + 재PASS 시까지 status `developing` 유지. PASS 못 받으면 `developed` 전환 X.
108
+ **FAIL 시 — 추측 fix 반복 방지 룰 (stash FRICTION_LOG #15+16+18 반영)**:
109
+
110
+ 1. **1회 실패 시 자체 수정 시도** — 에러 메시지 + 스택 트레이스 *전체 정독*. 추측 X. 실제 로그 데이터 기반 fix.
111
+ 2. **2회 이상 실패 시 진단 로그 추가** — `console.log` / `print` / `logger.debug` 등 디버그 로그 추가 후 *실제 동작 데이터* 확보 후 root cause 확정. 추측 fix 반복 영구 금지.
112
+ 3. **동일 신고 재발 시 즉시 root cause 분석 모드** — 사용자 또는 자동화에서 *동일 에러 / 동일 신고* 재발 시 추측 fix 중단. `grep -rn <symbol>` 으로 *모든 사용처* 확인 + `git blame` 으로 *언제 추가된 줄* 확인 + 진단 로그 추가해 *실제 데이터* 추적. 동명 property / 함수 가능성 *항상 의심* (한 위치 fix 후 재발 시 다른 위치 우선 의심).
113
+ 4. 같은 종류 fail이 3회 반복되면 사용자에게 보고 + 판단 요청 (*"이 에러가 풀리지 않아. 진단 로그 결과: ... 추가 정보 필요"*).
114
+ 5. 수정 + 재PASS 시까지 status `developing` 유지. PASS 못 받으면 `developed` 전환 X.
115
+
116
+ ### Step 6.5 — 테스트 실행 (`## 테스트 명령` — 코드 정상성)
117
+
118
+ stash FRICTION_LOG #14+19 / #25 반영 — 유닛 테스트는 본 단계에서 단일 시점 실행 (task-close / hook 영역 중복 제거).
119
+
120
+ `CLAUDE.md` `## 테스트 명령` 섹션의 명령을 *전부* 실행. 모두 PASS여야 `developed`로 전이 가능.
121
+
122
+ | 명령 | PASS 기준 |
123
+ |------|---------|
124
+ | 단위 테스트 (예: `npm test`) | 모든 케이스 PASS |
125
+ | 통합 테스트 (있을 시) | 모든 케이스 PASS |
126
+ | E2E 테스트 (있을 시) | 모든 시나리오 PASS |
127
+
128
+ **신규 테스트 식별자 등장 확인 (stash FRICTION_LOG #19 반영)**:
129
+
130
+ - 본 task에서 신규 테스트 추가되었으면 *단순 카운트 +N / 모든 PASS* 자체로 PASS 단정 X.
131
+ - 신규 *테스트 식별자* (suite / class / function / describe 등) 가 테스트 runner 결과 로그에 *실제 등장*했는지 grep 직접 확인 (1 hit 이상).
132
+ - 예: `grep -E "Suite \"<NewSuite>\"" test-output.log` → hit 1 이상.
133
+ - 등장 안 하면 *Suite 미실행* (빌드 시스템 등록 누락 등) → FAIL 처리.
134
+
135
+ **FAIL 시**: Step 6의 FAIL 룰 동일 적용 (추측 fix 반복 방지 / 진단 로그 / 동일 신고 재발 시 root cause).
92
136
 
93
137
  ### Step 7 — Result 섹션 진행 기록
94
138
 
@@ -135,6 +179,8 @@ Step 1에서 추출한 검증 명령을 *전부* 실행. 모두 PASS여야 `deve
135
179
  - **git 명령 절대 X** — 본 스킬은 코드만. `git commit` / `git push` / `git branch` 등 모두 `/task-close`에서. self-check fail 후 *재실행*도 git 무관.
136
180
  - **Phase 순서 건너뛰기 X** — Phase 1 끝나기 전 Phase 2 진행 X. 의존 관계 깨짐 + 디버깅 어려워짐.
137
181
  - **계획 외 스코프 확장 X** — Dev Plan에 없는 파일 다루기 전 사용자 confirm. *"이 부분 같이 작업해야 할 것 같은데 OK?"* 합의 후 진행.
182
+ - **모호 발화 confirm 룰 (stash FRICTION_LOG #21+22 반영)** — 사용자 발화가 코드/문서/기능 영역에서 *복수 매칭* 가능할 때 자율 추정 영구 금지. 메인 *자체 안 1개* + *"X 의미 맞아?"* 한 줄 confirm 후 진행. 옵션 4개 늘어놓기 금지 (메인 판단 위임 회피 패턴). 예: 사용자 *"환경설정 아이콘"* 발화 → popover 톱니 / Settings 탭바 아이콘 둘 다 가능 → 어느 영역인지 한 줄 confirm 필수.
183
+ - **디자인 산출 정독 의무 (stash FRICTION_LOG #14+19 / #12 일반화)** — task에 디자인 산출 (HTML 목업 / Figma / 디자인 파일 등) 있으면 메인이 *직접 Read* 후 구현. sub-agent 위임 금지 (요약만 받아 디자인 정합 깨짐). 구현 = 디자인 산출 기준 (역방향 X — 코드 편의로 디자인 어김 절대 X). 목업 위치 = `.project/tasks/<vX.X>/mockup/<task-doc-name>-mockup.html`.
138
184
  - **self-check FAIL 시 `developed` 전환 X** — 무리하게 상태 갱신 금지. 메인 자체 수정 시도 → 안 되면 사용자에게 보고. *"잘 될 거야"* 가정 금지.
139
185
  - **로그 심기 잊지 X** — Dev Plan 작성 시 `[로그]` 항목 명시되어 있으면 *반드시* 실제 로그 코드 삽입. 격리 세션 / 운영 디버깅 모두 의존.
140
186
  - **Result 섹션 진행만** — 테스트 결과는 `/task-test`가 기록. 메인이 *"잘 됐을 거야"* 가정 작성 금지.