@angar2/taskery 0.1.1 → 0.1.3

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