@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.
@@ -97,14 +97,15 @@ draft → planned → developing → developed → testing → tested → closed
97
97
  | 폴더 승격 task | `.project/tasks/<vX.X>/TASK-<NNN>_<slug>/task.md` | `/task-init` (규모 large 또는 사용자 명시 또는 추가 자료 다수) |
98
98
  | spec-diffs (변경된 plan 문서 추적) | `.project/tasks/<vX.X>/spec-diffs/<NNN>_<slug>_spec-diff.md` (**vX.X 공통** — 단일/폴더 모두) | `/task-plan` Step 6 (Phase 0 변경 시) |
99
99
  | screenshots (UI 작업 자료) | `.project/tasks/<vX.X>/screenshots/<NNN>_*.png` (**vX.X 공통**) | `/task-test` 격리 세션 또는 메인 |
100
- | 폴더 승격 task의 추가 자료 (서브 문서, mockup 등) | `TASK-<NNN>_<slug>/` 안 자유 | 메인 / `/task-dev` |
100
+ | mockup (UX/UI HTML 목업) | `.project/tasks/<vX.X>/mockup/<task-doc-name>-mockup.html` (**vX.X 공통** — 단일/폴더 모두) | `/task-plan` Step 4.5 (UX/UI task 한정) — 단일 진실 소스 `MOCKUP_RULE.md` |
101
+ | 폴더 승격 task의 추가 자료 (서브 문서 등) | `TASK-<NNN>_<slug>/` 안 자유 | 메인 / `/task-dev` |
101
102
 
102
103
  **원칙**:
103
- - spec-diffs / screenshots는 *vX.X 공통* — 파일명 NNN prefix로 task 식별. 폴더 승격 task도 동일 (별도 spec-diffs/screenshots 만들지 X).
104
+ - spec-diffs / screenshots / mockup은 *vX.X 공통* — 파일명 NNN prefix 또는 task 문서 파일명으로 task 식별. 폴더 승격 task도 동일 (별도 spec-diffs/screenshots/mockup 만들지 X).
104
105
  - vX.X 공통 디렉토리는 `/plan-init` Step 5가 mkdir.
105
- - 폴더 승격은 *task의 추가 자료*용 (서브 문서, mockup, 디자인 자료 등) — *spec-diffs/screenshots 위치 X*.
106
+ - 폴더 승격은 *task의 추가 자료*용 (서브 문서 / 디자인 자료 등) — *spec-diffs / screenshots / mockup 위치 X*.
106
107
 
107
- **closed-immutable hook 보호 범위** — task.md 본 파일만 (단일 파일 또는 폴더 승격 task.md). spec-diffs / screenshots / 폴더 승격 추가 자료는 *역사적 자료*로 자유 수정.
108
+ **closed-immutable hook 보호 범위** — task.md 본 파일만 (단일 파일 또는 폴더 승격 task.md). spec-diffs / screenshots / mockup / 폴더 승격 추가 자료는 *역사적 자료*로 자유 수정.
108
109
 
109
110
  ---
110
111
 
@@ -157,27 +158,78 @@ draft → planned → developing → developed → testing → tested → closed
157
158
 
158
159
  ### 2.5 Test Plan 작성 (`/task-plan` 4단계)
159
160
 
160
- 양식 강제 X — *작업에 맞게 자유롭게* 채움. 다만 가이드라인 따름:
161
+ **본질** — Test Plan = *본 task에서 구현한 요구사항이 정상 동작하는지* 검증 시나리오. **유닛 테스트 X** (유닛 테스트는 `/task-dev` Step 6.5에서 단일 시점 실행 — 코드 정상성 영역, Test Plan과 직교).
161
162
 
162
- - **자기완결적**: `/task-test` 격리 세션이 *task.md만 보고도* 수행 가능. 메인의 plan/dev 컨텍스트 없이.
163
- - **명령/기대값 포함**: 무엇을 실행하고 무엇이 기대되는지 명확.
164
- - **메인 가정 X**: 격리 세션이 *코드와 동작만 신뢰*. *"잘 될 거야"* 같은 가정 금지.
163
+ **검증 대상**:
164
+ - 기능 동작: 사용자 입력 → 기대 결과 / API 호출 → 응답 / 데이터 처리 → 상태 변화
165
+ - UX/UI 동작: 클릭 → 결과 / 호버 → 상태 / 드래그 → 위치 변경
166
+ - UX/UI 시각: 레이아웃 / 색상 / 간격 / 호버 효과 (목업 기준)
167
+ - 백엔드 동작: 시스템 호출 → 외부 응답 / 사이드 이펙트 / 에러 처리
165
168
 
166
- 자유 형식 (체크리스트 / 시나리오 / 명령 나열 등):
169
+ **시나리오 형식**:
167
170
 
168
171
  ```markdown
169
172
  ## Test Plan
170
173
 
171
- 1. `npm run dev` 실행 → 로그인 페이지(/login) 접속.
172
- 2. 빈 값 제출 → 에러 메시지 *"이메일 입력 필요"* 표시 확인.
173
- 3. 잘못된 이메일 형식 → *"올바른 이메일 형식이 아닙니다"* 확인.
174
- 4. DB에 미등록 계정 → 401 + *"계정 없음"* 확인.
175
- 5. 정상 로그인 → 홈(/)으로 리다이렉트 + 세션 쿠키 확인.
174
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
175
+ |---|---------|------|------|----------|
176
+ | 1 | <한 줄 설명> | [AUTO] / [USER] | <카탈로그 방식> | <명확한 기대값> |
177
+ | 2 | ... | ... | ... | ... |
178
+ ```
179
+
180
+ **분류 강제**:
181
+ - `[AUTO]` — 자동화 가능. 격리 세션이 *실제 명령 실행 + 결과 로그* 확보.
182
+ - `[USER]` — 자동화 불가 (UI 인터랙션 / 시각 디자인 / 사용자 입력). 격리 세션은 UNCERTAIN 분류 + *사용자 직접 검수 항목*으로 리턴.
183
+
184
+ **방식 카탈로그** (시나리오마다 1개 이상):
185
+
186
+ | 방식 | 적용 영역 |
187
+ |------|----------|
188
+ | 수동 검수 | UI / UX / 인터랙션 |
189
+ | 시나리오 스크립트 실행 | 백엔드 / 통합 흐름 (end-to-end script — bash / node 등) |
190
+ | API/엔드포인트 호출 | 백엔드 / 외부 인터페이스 (실제 호출 + 응답·상태 코드 확인) |
191
+ | 입출력 비교 | 함수 / 변환 / 처리 (snapshot / golden file) |
192
+ | 사이드 이펙트 확인 | DB / 파일 / 로그 |
193
+ | 회귀 시나리오 | 기존 기능 영향 (직전 동작하던 시나리오 재실행) |
194
+ | E2E 자동화 도구 | UI 자동화 (Playwright / Cypress / XCTest UI Test 등) |
195
+
196
+ **UX/UI 영역 분리** (UX/UI 구현 task 한정):
197
+
198
+ | 영역 | 자동화 가능 | 자동화 불가 |
199
+ |------|------------|------------|
200
+ | 동작 (클릭 / 호버 / 드래그 / 입력 → 결과) | `[AUTO]` E2E 자동화 스크립트 | `[USER]` 체크리스트 |
201
+ | 시각 (레이아웃 / 색상 / 간격 / 호버 효과) | (자동 비교 의미 X — 픽셀 단위 + 주관 판단 영역) | `[USER]` 체크리스트 + 목업 기준 (`mockup/<task-doc-name>-mockup.html`) |
176
202
 
177
- 검증 명령:
178
- - `npm run lint` PASS
179
- - `npm run typecheck` PASS
180
- - `npm run build` PASS
203
+ **시각 영역 fix 사이클 사전 예고** — 시각 시나리오 있으면 Test Plan 끝에 *"시각 영역 항목 N개 — fix 사이클 1~2회 예상"* 명시 (사용자 기대치 사전 정렬).
204
+
205
+ **검증 / 테스트 명령 참조** — `CLAUDE.md`의 `## 검증 명령` (코드 상태: 빌드 / 린트 / 타입체크) + `## 테스트 명령` (테스트 실행: 단위 / 통합 / E2E) 두 섹션을 격리 세션이 자동 참조. Test Plan 본문에 재인용 불필요.
206
+
207
+ **가이드라인**:
208
+ - **자기완결적**: `/task-test` 격리 세션이 *task.md만 보고도* 수행 가능. 메인의 plan/dev 컨텍스트 없이.
209
+ - **명령 / 기대값 포함**: 무엇을 실행하고 무엇이 기대되는지 명확.
210
+ - **메인 가정 X**: 격리 세션이 *코드와 동작만 신뢰*. *"잘 될 거야"* 같은 가정 금지.
211
+ - **grep/Read-only 존재 확인 시나리오 = 보조용** (stash FRICTION_LOG 2026-06-01 반영) — 구현 코드의 존재 여부를 grep/Read로 재확인하는 시나리오는 *동어반복*. PASS 카운트에서 제외하거나 실동작 시나리오의 *보조*로만 사용. 단독 검증 가치 X.
212
+ - **요구사항당 end-to-end 1개 이상 강제** — Requirements 각 항목이 *사용자 관점에서 실제 작동하는지* 검증하는 end-to-end 실동작 시나리오 최소 1개 보장. 산출물 실행 → 결과 확인 형태.
213
+ - **무거운 검증 회피 영구 금지** — 부담(빌드 수 분+ / 외부 의존 / 환경 설정) 이유로 실동작 시나리오를 grep 동어반복으로 대체 X. 최소 1회는 실제 산출물로 확인. 부담은 *fix 사이클 1~2회 예상* 같은 사전 예고로 처리 (생략 사유 X).
214
+
215
+ **요구사항 ↔ 시나리오 커버리지 점검** (필수 — stash FRICTION_LOG 2026-06-01 반영):
216
+
217
+ Test Plan 작성 완료 후 *반드시* 점검. *"누적/리셋 안 함"* 같은 요구사항이 시나리오에서 통째로 빠지는 누락 차단용.
218
+
219
+ 1. Requirements 합의 항목 전체를 *매트릭스*로 펼침.
220
+ 2. 각 항목당 *최소 1개 시나리오 커버* 확인.
221
+ 3. 미커버 발견 시 → 시나리오 보강 후 재점검.
222
+
223
+ 형식 (Test Plan 끝에 첨부):
224
+
225
+ ```markdown
226
+ ### Requirements ↔ Test Plan 매트릭스
227
+
228
+ | 요구사항 | 커버 시나리오 # |
229
+ |---------|----------------|
230
+ | <Req 1 한 줄> | #1, #3 |
231
+ | <Req 2 한 줄> | #2 (end-to-end) |
232
+ | <Req 3 한 줄> | #5 |
181
233
  ```
182
234
 
183
235
  ### 2.6 Result 기록 (`/task-dev`, `/task-test` 끝)
@@ -310,25 +362,17 @@ draft → planned → developing → developed → testing → tested → closed
310
362
  ```markdown
311
363
  ## Test Plan
312
364
 
313
- 1. `npm run dev` 실행 → http://localhost:3000/login 접속.
314
- 2. 빈 이메일 + 비밀번호 제출:
315
- - 기대: *"이메일 입력 필요"* + *"비밀번호 입력 필요"* 표시. API 호출 X.
316
- 3. 잘못된 이메일 형식 (예: "abc"):
317
- - 기대: *"올바른 이메일 형식 아님"* 표시. API 호출 X.
318
- 4. 짧은 비밀번호 (예: "123"):
319
- - 기대: *"비밀번호 8자 이상 필요"* 표시. API 호출 X.
320
- 5. 정상값 제출:
321
- - 기대: API 호출 → 정상 응답 시 / 리다이렉트.
322
- 6. 한국어 ↔ 영어 전환:
323
- - 기대: 메시지 언어 따라 변경.
324
-
325
- 검증 명령:
326
- - `npm run lint` PASS
327
- - `npm run typecheck` PASS
328
- - `npm run build` PASS
329
- - `npm test src/utils/validation.test.ts` PASS
365
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
366
+ |---|---------|------|------|----------|
367
+ | 1 | 빈 이메일 + 비밀번호 제출 | [USER] | 수동 검수 | "이메일 입력 필요" + "비밀번호 입력 필요" 표시, API 호출 X |
368
+ | 2 | 잘못된 이메일 형식 ("abc") | [USER] | 수동 검수 | "올바른 이메일 형식 아님" 표시, API 호출 X |
369
+ | 3 | 짧은 비밀번호 ("123") | [USER] | 수동 검수 | "비밀번호 8자 이상 필요" 표시, API 호출 X |
370
+ | 4 | 정상값 제출 | [USER] | 수동 검수 | API 호출 → 정상 응답 시 / 리다이렉트 |
371
+ | 5 | 한국어 ↔ 영어 전환 | [USER] | 수동 검수 | 메시지 언어 따라 변경 |
330
372
  ```
331
373
 
374
+ > 검증 명령 / 테스트 명령은 `CLAUDE.md` 두 섹션을 격리 세션이 자동 참조 — Test Plan 본문 재인용 X.
375
+
332
376
  ### 4.6 Result
333
377
 
334
378
  **역할**: 진행 + 테스트 결과 통합. *"실제로 어떻게 됐는가"*.
@@ -379,8 +423,11 @@ draft → planned → developing → developed → testing → tested → closed
379
423
  - 진행: [x]
380
424
 
381
425
  ## Test Plan
382
- - `grep -n "Instalation" README.md` → 결과 0행.
383
- - `grep -n "Installation" README.md` → 1행 이상.
426
+
427
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
428
+ |---|---------|------|------|----------|
429
+ | 1 | README.md 안 오타 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Instalation" README.md` 결과 0건 |
430
+ | 2 | README.md 안 정정 표기 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Installation" README.md` 결과 1건 이상 |
384
431
 
385
432
  ## Result
386
433
 
@@ -479,32 +526,16 @@ draft → planned → developing → developed → testing → tested → closed
479
526
 
480
527
  ## Test Plan
481
528
 
482
- 1. `npm run dev` 실행 → API 서버 :3000.
483
- 2. 정상 로그인:
484
- - POST /api/auth/login { email: "test@x.com", password: "Password123!" }
485
- - 기대: 200, body { token: "eyJ..." }, Set-Cookie: refreshToken=...
486
- 3. 잘못된 비밀번호:
487
- - POST /api/auth/login { email: "test@x.com", password: "wrong" }
488
- - 기대: 401, body { error: "이메일 또는 비밀번호가 올바르지 않습니다" }
489
- 4. 미등록 이메일:
490
- - 기대: 401, **동일 메시지** (enumeration 방어)
491
- 5. 빈 입력 / 형식 오류:
492
- - 기대: 400, validation 에러
493
- 6. JWT 검증:
494
- - GET /api/protected with Authorization: Bearer <token>
495
- - 기대: 200 (유효 토큰) / 401 (만료, 무효)
496
- 7. Rate limit:
497
- - 11회 연속 요청
498
- - 기대: 11번째 요청 429
499
- 8. Refresh token:
500
- - GET /api/auth/refresh with cookie
501
- - 기대: 200, 새 token 발급
502
-
503
- 검증 명령:
504
- - `npm run lint` PASS
505
- - `npm run typecheck` PASS
506
- - `npm run build` PASS
507
- - `npm test src/api/auth.test.ts` PASS
529
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
530
+ |---|---------|------|------|----------|
531
+ | 1 | 정상 로그인 | [AUTO] | API/엔드포인트 호출 | POST /api/auth/login {email, password} → 200, body {token}, Set-Cookie: refreshToken |
532
+ | 2 | 잘못된 비밀번호 | [AUTO] | API/엔드포인트 호출 | 401, body {error: "이메일 또는 비밀번호가 올바르지 않습니다"} |
533
+ | 3 | 미등록 이메일 (enumeration 방어) | [AUTO] | API/엔드포인트 호출 | 401, body 메시지 #2와 동일 |
534
+ | 4 | 빈 입력 / 형식 오류 | [AUTO] | API/엔드포인트 호출 | 400, validation 에러 |
535
+ | 5 | JWT 검증 — 유효 토큰 | [AUTO] | API/엔드포인트 호출 | GET /api/protected with Authorization → 200 |
536
+ | 6 | JWT 검증 — 만료 / 무효 | [AUTO] | API/엔드포인트 호출 | 401 |
537
+ | 7 | Rate limit (11회 연속) | [AUTO] | 시나리오 스크립트 실행 | 11번째 요청 429, 헤더 X-RateLimit-Remaining: 0 |
538
+ | 8 | Refresh token | [AUTO] | API/엔드포인트 호출 | GET /api/auth/refresh with cookie → 200, 새 token 발급 |
508
539
 
509
540
  ## Result
510
541
 
@@ -573,18 +604,11 @@ draft → planned → developing → developed → testing → tested → closed
573
604
 
574
605
  ## Test Plan
575
606
 
576
- 1. `npm run dev` 실행 → iOS Safari로 http://localhost:3000/search 접속.
577
- 2. 검색어 입력 후 검색 버튼 클릭:
578
- - 기대: 페이지 URL의 search query만 갱신, 새로고침 X (네트워크 탭에서 document 요청 X 확인).
579
- 3. 데스크톱 Chrome 동일 동작:
580
- - 기대: 회귀 X (기존 정상 동작 유지).
581
- 4. 단위 테스트:
582
- - `npm test src/components/SearchForm.test.tsx` PASS.
583
-
584
- 검증 명령:
585
- - `npm run lint` PASS
586
- - `npm run typecheck` PASS
587
- - `npm run build` PASS
607
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
608
+ |---|---------|------|------|----------|
609
+ | 1 | iOS Safari 검색어 입력 후 검색 버튼 클릭 | [USER] | 수동 검수 | 페이지 URL의 search query만 갱신, 새로고침 X (네트워크 탭 document 요청 X) |
610
+ | 2 | 데스크톱 Chrome 동일 동작 (회귀) | [USER] | 수동 검수 | 회귀 X (기존 정상 동작 유지) |
611
+ | 3 | onSubmit handler preventDefault 회귀 테스트 | [AUTO] | 입출력 비교 | fireEvent.submit + expect(preventDefault) 호출 확인 |
588
612
 
589
613
  ## Result
590
614
 
@@ -612,3 +636,5 @@ draft → planned → developing → developed → testing → tested → closed
612
636
  | 2026-05-08 | 초안 — 5컬럼 헤더 / 7상태 / 6섹션 / 4단 layer 가이드 / 완성 예시 3개 |
613
637
  | 2026-05-08 | §1.5 추가 — task 파일/폴더/부속 자료 위치 단일 진실 소스. spec-diffs/screenshots는 vX.X 공통 통일. closed-immutable hook 보호 범위는 task.md 본 파일만 (스킬 본문 간 위치 모순 통일) |
614
638
  | 2026-05-09 | 표현 정제 — 인명 / 경박 표현 / 스킬 용어 / 이전 버전 비교 단락 정리 |
639
+ | 2026-05-30 | stash FRICTION_LOG 기반 정합 — §1.5 mockup 행 추가 (vX.X 공통, 단일 진실 소스 MOCKUP_RULE) + §2.5 Test Plan 본질 재정의 (실질 동작 시나리오 + `[AUTO]` / `[USER]` 분류 강제 + 카탈로그 7방식 + UX/UI 영역 분리 매트릭스 + 시각 fix 사이클 사전 예고 + 검증 / 테스트 명령 두 섹션 참조) + §4.5 / §5 완성 예시 3개 Test Plan 형식 갱신 (분류 표 + PASS 기준 명시. 기존 번호 매김 시나리오 + 검증 명령 나열은 옛 형식). (stash FRICTION_LOG #14+19 / #25 정합) |
640
+ | 2026-06-02 | 0.1.3 F5 정합 — §2.5 가이드라인 안티패턴 3종 추가 (grep/Read-only 보조용 / 요구사항당 end-to-end 1개 이상 / 무거운 검증 회피 금지) + 요구사항 ↔ 시나리오 커버리지 점검 단계 신설 (stash FRICTION_LOG 2026-06-01 Test Plan 동어반복 + 누락 마찰 반영) |
@@ -1,7 +1,7 @@
1
1
  # CLAUDE.md
2
2
 
3
3
  > 이 파일은 메인 세션이 *매 세션 시작 시 자동 로드*하는 단일 진입점이다.
4
- > 프로젝트 메타 + 검증 명령 + 룰 참조 + 스킬 8종 + 동기화 룰만 포함한다.
4
+ > 프로젝트 메타 + 검증 명령 + 룰 참조 + 스킬 9종 + 동기화 룰만 포함한다.
5
5
  > 사람용 도메인 설명은 `.project/PROJECT.md`, 진입 가이드는 `.project/AGENT-GUIDE.md` 참조.
6
6
 
7
7
  ---
@@ -17,17 +17,79 @@
17
17
 
18
18
  ---
19
19
 
20
+ ## 메인 세션 최상위 룰
21
+
22
+ > 본 룰은 *모든 스킬 호출 / 사용자 발화 처리 / 작업 진행*에 적용. 위반 시 사용자 마찰 직결.
23
+
24
+ 1. **범위 준수** — 사용자가 명시한 범위/행동만 수행. 명시 외 자체 진입 영구 금지. 예: 사용자가 *"X부터 Y까지"* 지시 → Y 끝에서 정지 + 상태 보고 + 다음 단계 명시 호출 대기.
25
+ 2. **Skill 정식 발동** — task 단계는 반드시 Skill 도구로 정식 호출. 가이드 본문을 머릿속 절차로 대체 금지 (컴팩트 세션 / 시스템 리마인더 인지 상태에서도 동일).
26
+ 3. **워크트리 자가 진단** — 세션 시작 시 현재 cwd가 *메인 워크트리*인지 *태스크 워크트리*인지 자가 판단 (`git rev-parse --show-toplevel` + `~/.taskery/worktrees/` 경로 비교). 태스크 워크트리면 *해당 진행중 태스크 컨텍스트*로 진입, 메인 워크트리면 *새 태스크 / 진행중 목록 인터뷰* 흐름.
27
+ 4. **모호 발화 자의 해석 금지** — *"워크트리 없이"* / *"메인에서"* / *"이 자리에서 그냥"* 류로 읽히는 발화 = 코어 규칙(메인 워크트리 = dev 전용) 충돌 신호. 즉시 정지 + 규칙 한 줄 명시 + 1줄 confirm 요청. 자의 해석 후 진행 영구 금지. 사용자 의도가 *오타/모호*일 가능성을 *워크트리 사용*으로 읽는 게 자연스러움.
28
+
29
+ ---
30
+
31
+ ## 멀티세션 워크트리 (0.1.2+)
32
+
33
+ > 멀티세션 = 같은 프로젝트에서 *여러 메인 세션이 독립 태스크를 병렬*로 진행. git worktree로 작업 폴더 격리, dev 머지 시 직렬화.
34
+
35
+ - **메인 워크트리 = dev 전용**: 메인 워크트리는 항상 `dev` 체크아웃 상태. 모든 태스크 작업은 *예외 없이* 별도 워크트리에서 수행. 메인 워크트리 HEAD를 dev에서 떼는 어떤 작업(`git checkout <task-branch>` / `git switch <task-branch>` / `git reset` HEAD 이동 / `git rebase` HEAD 이동 등)도 영구 금지. *"잠깐만 메인에서"* / *"테스트 한 번만 메인에서"* 같은 예외 발화도 거부 — 별도 워크트리에서 처리.
36
+ - **워크트리 위치**: `~/.taskery/worktrees/<projectId>/TASK-NNN_<출처>_<슬러그>/`
37
+ - `<projectId>`: `.taskery-manifest.json` `projectId` (8자 hex)
38
+ - `<출처>`: `BL-NNN` / `RM-NNN` / `DR`
39
+ - **`/task-init`이 워크트리 생성** + **`/task-close`가 dev 머지 + 워크트리 자동 제거** (자동 흐름. 보존 키워드 `keep` / `브랜치 남겨` 등 발화 시 둘 다 보존).
40
+ - **메인 메타 접근**: 워크트리에서 `.project/`, `CLAUDE.md` 등 접근 시 *메인 워크트리 절대 경로* 사용:
41
+ ```sh
42
+ MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
43
+ ```
44
+ - **수동 git 작업 시 정합성 보장 X** — taskery 명령(스킬 / `npx @angar2/taskery <서브>`)으로만 운영.
45
+ - **CLI 보조 명령**:
46
+ - `npx @angar2/taskery status` — 진행중 태스크 + 워크트리 + dev 머지 상태 요약
47
+ - `npx @angar2/taskery prune` — stale 워크트리 대화형 정리
48
+
49
+ 상세: `.project/rules/GIT_RULE.md` "멀티세션 워크트리 정책" 섹션.
50
+
51
+ 요건: git ≥ 2.31 (`--path-format=absolute` 옵션 필요).
52
+
53
+ ---
54
+
55
+ ## 백로그 (0.1.2+)
56
+
57
+ > `.project/tasks/<vX.X>/BACKLOG.md` = *버전별 task 후보 누적*. 사용자 발화로 1건씩 얕은 분석(개요 / 대상 영역) 곁들여 추가.
58
+
59
+ - **`/add-backlog`**: 사용자 *"~ 백로그에 추가"* 발화 → 얕은 분석(코드 탐색 X, 추정 수준) → BL-NNN 채번 → BACKLOG.md append (`[ ]` 대기).
60
+ - **`/task-init` 연동**: 사용자 *"백로그의 BL-NNN 진행"* 발화 → 해당 항목 *확인 마킹*. `[ ]` → `[x]` + `- TASK: TASK-NNN` 추가 (다회 진행 시 콤마).
61
+ - **체크박스 의미**: `[ ]` = 미확인 (task로 옮기지 않은 메모) / `[x]` = 확인 완료 (task로 옮김). **dev 머지 완료 의미 X** — 완료 여부는 `git log dev --grep 'BL-NNN'` + 브랜치명 추적 + `taskery status`.
62
+ - **글로벌 `.project/BACKLOG.md`** (plan 기획 후보 카탈로그) 는 본 흐름 무관 — `/plan-init` 영역.
63
+
64
+ 상세: `.claude/skills/add-backlog/SKILL.md`.
65
+
66
+ ---
67
+
20
68
  ## 검증 명령
21
69
 
22
- > `/task-dev` self-check / `/task-test` 격리 게이트 / `/task-close` 최종 게이트 / `pre-commit-verify.sh` hook이 *모두 이 섹션을 단일 진실 소스로 참조*.
70
+ > *코드 상태 검증* (빌드 / 린트 / 타입체크). 테스트 실행은 본 섹션 X — `## 테스트 명령` 참조.
71
+ > `/task-dev` self-check / `/task-close` 최종 게이트가 *이 섹션을 단일 진실 소스로 참조*.
23
72
  > 백틱(`...`) 안 명령 그대로 실행됨. 언어/프레임워크 따라 변경.
24
73
 
25
74
  - 린트: `<예: npm run lint>`
26
75
  - 타입체크: `<예: npm run typecheck>` (TypeScript / Flow / mypy 등 — 해당 시)
27
76
  - 빌드: `<예: npm run build>`
77
+
78
+ > 위 항목 중 *프로젝트에 해당 없는 것*은 행 자체 삭제. 빈 백틱(\`\`)은 사용 금지.
79
+
80
+ ---
81
+
82
+ ## 테스트 명령
83
+
84
+ > *테스트 실행* (단위 / 통합 / E2E 등). 코드 상태 검증은 `## 검증 명령` 참조.
85
+ > `/task-dev` 구현 후 테스트 + `/task-test` 격리 세션이 *이 섹션을 단일 진실 소스로 참조*.
86
+ > 백틱(`...`) 안 명령 그대로 실행됨. 언어/프레임워크 따라 변경.
87
+
28
88
  - 단위 테스트: `<예: npm test>`
89
+ - 통합 테스트: `<예: npm run test:integration>` (있을 시)
90
+ - E2E 테스트: `<예: npx playwright test>` (있을 시)
29
91
 
30
- > 위 4 항목 중 *프로젝트에 해당 없는 것*은 행 자체 삭제. 빈 백틱(\`\`)은 사용 금지.
92
+ > 위 항목 중 *프로젝트에 해당 없는 것*은 행 자체 삭제. 빈 백틱(\`\`)은 사용 금지.
31
93
 
32
94
  ---
33
95
 
@@ -37,11 +99,13 @@
37
99
  |----|------|------|
38
100
  | TASK_DOC_RULE | `.project/rules/TASK_DOC_RULE.md` | task 문서 양식 (헤더 5컬럼 / 6 섹션 / 7 상태) |
39
101
  | GIT_RULE | `.project/rules/GIT_RULE.md` (있으면) → 글로벌 `~/.claude/rules/GIT_RULE.md` (fallback) | git 정책 (브랜치 / 커밋 / 머지) |
102
+ | CHANGELOG_RULE | `.project/rules/CHANGELOG_RULE.md` | CHANGELOG 작성 정책 (위치 / 형식 / 필수 필드) |
103
+ | MOCKUP_RULE | `.project/rules/MOCKUP_RULE.md` | UX/UI task의 HTML 목업 위치 / 형식 / 네이밍 |
40
104
  | `*.local.md` | `.project/rules/` | (옵션) 사용자 오버라이드 — `*.local.md` suffix는 npx 미터치 |
41
105
 
42
106
  ---
43
107
 
44
- ## 스킬 8종 — project > plan > task 위계 + 회고
108
+ ## 스킬 9종 — project > plan > task 위계 + 회고
45
109
 
46
110
  | 스킬 | 레벨 | 역할 |
47
111
  |------|------|------|
@@ -52,22 +116,24 @@
52
116
  | `/task-dev` | task | Phase 순서 구현 + self-check (planned → developed) |
53
117
  | `/task-test` | task | Task tool 격리 검증 (developed → tested) |
54
118
  | `/task-close` | task | 검증 명령 게이트 + 커밋 + dev 병합 (tested → closed) |
119
+ | `/add-backlog` | meta | 사용자 발화로 버전별 BACKLOG.md에 항목 1건 추가 (얕은 분석 + BL-NNN 채번 — 0.1.2+) |
55
120
  | `/log-friction` | meta | FRICTION_LOG.md에 사용자 불편 한 행 기록 |
56
121
 
57
122
  본문은 `.claude/skills/<스킬>/SKILL.md` 참조.
58
123
 
59
124
  ---
60
125
 
61
- ## Hook 안전망 — Catastrophic 3종
126
+ ## Hook 안전망 — Catastrophic 2종
62
127
 
63
128
  | Hook | 영역 | 잡는 것 |
64
129
  |------|------|--------|
65
130
  | `git-guard.sh` | PreToolUse(Bash) | main/dev 직접 커밋 / `--force` / `--no-verify` / `branch -D` / `reset --hard` / `clean -fd` |
66
- | `pre-commit-verify.sh` | PreToolUse(Bash) | `git commit` 시 위 *검증 명령* 모두 PASS 게이트. 하나라도 fail → 차단 |
67
- | `closed-immutable.sh` | PreToolUse(Write\|Edit) | `closed` 상태 task.md 본 파일 재수정 차단 (정상 흐름은 새 task로). spec-diffs/screenshots는 자유 수정 (역사적 자료) |
131
+ | `closed-immutable.sh` | PreToolUse(Write\|Edit) | `closed` 상태 task.md 본 파일 재수정 차단 (정상 흐름은 새 task로). spec-diffs / screenshots / mockup은 자유 수정 (역사적 자료) |
68
132
 
69
133
  **잘 지키면 hook 작동 0회 (무해). catastrophic만 차단.**
70
134
 
135
+ > 이전 `pre-commit-verify.sh` hook은 폐기 — task-close Step 2 게이트 + git-guard 안전망으로 충분 (redundant 검증 사이클 제거). 폐기 사유는 [plan/HOOKS.md](../plan/HOOKS.md) §5 참조.
136
+
71
137
  ---
72
138
 
73
139
  ## 불편 데이터
@@ -1,97 +0,0 @@
1
- #!/bin/bash
2
- # .claude/hooks/pre-commit-verify.sh
3
- # PreToolUse(Bash) 훅 — git commit 시점에 검증 명령 모두 PASS 게이트
4
- #
5
- # 잡는 것:
6
- # git commit 명령 감지 → 프로젝트 루트 CLAUDE.md '## 검증 명령' 섹션의 명령 모두 실행
7
- # 하나라도 fail (exit code != 0) → exit 2 (commit 차단)
8
- #
9
- # Process catastrophic — 결정적 영역(린트/타입/빌드/테스트). 합리적 변형 없음.
10
- # 잘 지키면 작동 0회 (무해 — /task-dev self-check + /task-close 게이트로 이미 PASS 상태에서 commit).
11
- # 부분 작업 / 환경 변화 / 가정 누설 시 catastrophic 차단 안전망.
12
- #
13
- # Single source of truth: 프로젝트 루트 CLAUDE.md '## 검증 명령' 섹션
14
- # 형식 예:
15
- # ## 검증 명령
16
- # - 린트: `npm run lint`
17
- # - 타입체크: `npm run typecheck`
18
- # - 빌드: `npm run build`
19
- # - 단위테스트: `npm test`
20
-
21
- INPUT=$(cat)
22
-
23
- # tool_input.command 추출
24
- CMD=$(echo "$INPUT" | python3 -c "
25
- import sys, json
26
- try:
27
- d = json.load(sys.stdin)
28
- print(d.get('tool_input', {}).get('command', ''))
29
- except Exception:
30
- print('')
31
- " 2>/dev/null)
32
-
33
- # git commit 명령 아니면 통과
34
- if ! echo "$CMD" | grep -qE '(^|;|&&|\|\|)\s*git\s+commit\b'; then
35
- exit 0
36
- fi
37
-
38
- # CLAUDE.md 정독 — 프로젝트 루트
39
- if [ ! -f "./CLAUDE.md" ]; then
40
- echo "pre-commit-verify: 프로젝트 루트 CLAUDE.md 없음. 검증 명령 단일 진실 소스 누락 — commit 차단." >&2
41
- echo " '/project-init' 또는 'npx @angar2/taskery init' 호출해 CLAUDE.md 생성." >&2
42
- exit 2
43
- fi
44
-
45
- # '## 검증 명령' 섹션 추출 + 백틱(`...`) 안 명령 추출
46
- COMMANDS=$(python3 <<'PYEOF'
47
- import re
48
-
49
- try:
50
- with open('./CLAUDE.md') as f:
51
- content = f.read()
52
- except Exception:
53
- raise SystemExit('claude_md_read_failed')
54
-
55
- # '## 검증 명령' 섹션 (다음 ## 헤딩 또는 EOF까지)
56
- m = re.search(r'^##\s*검증\s*명령\s*$([\s\S]*?)(?=^##\s|\Z)', content, re.MULTILINE)
57
- if not m:
58
- raise SystemExit('section_missing')
59
-
60
- section = m.group(1)
61
- # 백틱 안 명령 추출 — list item(`-`로 시작) 줄에서만
62
- # (blockquote `>` 메타 텍스트 등 비-list 백틱 오인식 방지)
63
- cmds = []
64
- for line in section.split('\n'):
65
- stripped = line.strip()
66
- if stripped.startswith('-'):
67
- cmds.extend(re.findall(r'`([^`]+)`', stripped))
68
- for c in cmds:
69
- print(c)
70
- PYEOF
71
- )
72
-
73
- # 섹션 누락 / 추출 실패 케이스
74
- if [ -z "$COMMANDS" ]; then
75
- echo "pre-commit-verify: CLAUDE.md '## 검증 명령' 섹션 없거나 명령 없음. commit 차단." >&2
76
- echo " CLAUDE.md에 '## 검증 명령' 섹션 추가 + 백틱 안에 명령 작성 (예: \`npm run lint\`)." >&2
77
- exit 2
78
- fi
79
-
80
- # 각 명령 실행 — 하나라도 fail → 차단
81
- FAILED=""
82
- while IFS= read -r cmd; do
83
- [ -z "$cmd" ] && continue
84
- echo "pre-commit-verify: 실행 — $cmd" >&2
85
- if ! eval "$cmd" >/dev/null 2>&1; then
86
- FAILED="$FAILED\n - FAIL: $cmd"
87
- fi
88
- done <<< "$COMMANDS"
89
-
90
- if [ -n "$FAILED" ]; then
91
- echo "pre-commit-verify: 검증 명령 실패 — commit 차단." >&2
92
- printf "%b\n" "$FAILED" >&2
93
- echo " /task-dev self-check 또는 /task-close 게이트 통과 후 다시 시도." >&2
94
- exit 2
95
- fi
96
-
97
- exit 0