@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
@@ -0,0 +1,91 @@
1
+ # CHANGELOG_RULE
2
+
3
+ > 본 파일은 taskery 시스템 권장 프로젝트별 CHANGELOG 정책이다.
4
+ > 우선순위: **이 파일** (`.project/rules/CHANGELOG_RULE.md`) → 메인 판단.
5
+ > 프로젝트별 변형이 필요하면 `.project/rules/CHANGELOG_RULE.local.md` 생성 (npx update 미터치).
6
+
7
+ ---
8
+
9
+ ## 1. 파일 위치 / 기본 구조
10
+
11
+ - **경로**: `.project/changelog/CHANGELOG.md` (단일 파일) 또는 `.project/changelog/<YYYY-MM>.md` (월별 분할, 선호)
12
+ - **형식**: Markdown. 각 항목 = `## [TASK-NNN] <한 줄 요약>` 시작
13
+ - **정렬**: 최신 항목이 *맨 위* (Reverse chronological order)
14
+
15
+ ---
16
+
17
+ ## 2. 항목 형식
18
+
19
+ 각 task close 시 새 항목 1개 추가:
20
+
21
+ ```markdown
22
+ ## [TASK-NNN] <한 줄 요약>
23
+
24
+ - **날짜**: YYYY-MM-DD
25
+ - **타입**: feature / bug / improvement / refactor / docs / chore
26
+ - **변경 요약**: <2-3 줄>
27
+ - **영향 파일**: <주요 파일 경로 리스트>
28
+ - **사유**: <변경 이유 한 줄>
29
+ ```
30
+
31
+ ### 필수 필드
32
+
33
+ 1. 헤더 `## [TASK-NNN] <한 줄 요약>` (한 줄)
34
+ 2. **날짜** (`YYYY-MM-DD`)
35
+ 3. **타입** (커밋 태그와 동일 — `feat` / `fix` / `improve` / `refactor` / `docs` / `chore`)
36
+ 4. **변경 요약** (2-3 줄)
37
+
38
+ ### 선택 필드
39
+
40
+ - 영향 파일 (참고용)
41
+ - 사유 (참고용)
42
+ - 관련 PR / 이슈 링크 (있을 시)
43
+
44
+ ---
45
+
46
+ ## 3. 삽입 위치 (중요)
47
+
48
+ - **최신 항목이 맨 위** — 기존 첫 `##` 항목 *바로 위*에 삽입
49
+ - 메인 세션이 CHANGELOG.md Edit 시 *파일 전체 구조 확인 후* 정확한 위치에 삽입 의무
50
+ - 중간 삽입 / 끝 삽입 금지
51
+
52
+ ---
53
+
54
+ ## 4. task-close 흐름과의 정합
55
+
56
+ `/task-close` Step 4-4 (CHANGELOG 커밋) 단계에서 본 RULE 참조:
57
+
58
+ 1. 본 RULE 정독
59
+ 2. 신규 항목 형식대로 작성
60
+ 3. *최신 위치 (맨 위)* 에 삽입
61
+ 4. 커밋 — 메시지 형식: `docs: [TASK-NNN] CHANGELOG 업데이트`
62
+
63
+ ---
64
+
65
+ ## 5. 예시
66
+
67
+ ```markdown
68
+ ## [TASK-042] 사용자 인증 OAuth 2.0 지원 추가
69
+
70
+ - **날짜**: 2026-06-15
71
+ - **타입**: feature
72
+ - **변경 요약**: Google / GitHub OAuth provider 추가. 기존 이메일·비밀번호 흐름 유지.
73
+ - **영향 파일**: `src/auth/oauth.ts`, `src/routes/auth.ts`, `migrations/0042_oauth.sql`
74
+ - **사유**: 외부 서비스 연동 요구 누적 — 인증 흐름 다변화
75
+
76
+ ## [TASK-041] 로그인 페이지 입력 검증 fix
77
+
78
+ - **날짜**: 2026-06-12
79
+ - **타입**: bug
80
+ - **변경 요약**: 이메일 형식 검증 누락으로 빈 입력 통과되던 버그 fix.
81
+ - **영향 파일**: `src/components/LoginForm.tsx`
82
+ - **사유**: TASK-038 신고 — 빈 이메일로 로그인 시도 시 서버 오류
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 6. 수정 이력
88
+
89
+ | 날짜 | 변경 사항 |
90
+ |------|----------|
91
+ | 2026-05-30 | 신규 작성 — 위치 / 형식 / 필수 필드 / task-close 정합 (stash FRICTION_LOG #8+9 반영) |
@@ -11,8 +11,9 @@
11
11
  - **git 작업은 메인 세션이 `/task-close` 스킬 또는 직접 수행**.
12
12
  - **main, dev 직접 커밋 절대 금지**: 모든 작업은 태스크 브랜치에서 진행.
13
13
  - **하나의 브랜치는 하나의 태스크만 담당**.
14
- - **작업 브랜치는 dev에서 분기, dev로 병합**.
14
+ - **작업 브랜치는 *task-init 시점에* dev에서 분기, *task-close 시점에* dev로 병합** (멀티세션 0.1.2+).
15
15
  - **dev → main 병합은 사용자가 직접 수행**.
16
+ - **수동 git 작업 시 정합성 보장 X** — taskery 명령(스킬 호출 / `npx @angar2/taskery <서브>`)으로만 운영. 수동 `git worktree add` / `branch` / `merge` 시 SSoT·락·자동 정리 흐름이 깨질 수 있음.
16
17
 
17
18
  ---
18
19
 
@@ -21,8 +22,8 @@
21
22
  | 브랜치 | 용도 |
22
23
  |--------|------|
23
24
  | `main` | 프로덕션 |
24
- | `dev` | 통합 개발 |
25
- | `{타입}/{개발자}_{TASK-NNN}_{kebab-slug}` | 태스크 작업 브랜치 |
25
+ | `dev` | 통합 개발 (메인 워크트리 = dev 전용) |
26
+ | `{타입}/{개발자}_TASK-NNN_{출처}_{슬러그}` | 태스크 작업 브랜치 (멀티세션 시스템 단일 식별자) |
26
27
 
27
28
  ### 브랜치 타입
28
29
 
@@ -45,14 +46,27 @@
45
46
  | Claude | `claude` |
46
47
  | 기타 AI | 해당 AI 이름 (예: `gpt`, `gemini`) |
47
48
 
49
+ ### 출처 (Source — 멀티세션 0.1.2+)
50
+
51
+ | 출처 | 의미 | 채번 주체 |
52
+ |------|------|---------|
53
+ | `BL-NNN` | 백로그 항목 | `/add-backlog` 스킬 (0.1.2). 버전별 `.project/tasks/<vX.X>/BACKLOG.md`에 누적 |
54
+ | `RM-NNN` | 로드맵 항목 | `/plan-init` (RM-NNN 채번 자동화는 후속 — 1차는 사용자 수동 명시) |
55
+ | `DR` | 직접 요구사항 (별도 ID 없음) | 사용자 발화 → `/task-init` |
56
+
48
57
  ### 브랜치 예시
49
58
 
50
59
  ```
51
- feature/claude_TASK-001_user-auth
52
- bug/angar2_TASK-002_login-crash
53
- refactor/gpt_TASK-003_cleanup-api
60
+ feature/claude_TASK-007_BL-003_login-feature
61
+ bug/angar2_TASK-012_DR_mobile-form-refresh
62
+ refactor/claude_TASK-018_RM-002_api-cleanup
63
+ docs/claude_TASK-021_DR_readme-rewrite
54
64
  ```
55
65
 
66
+ ### 케이스 2 — TASK 없는 작업 브랜치 (시스템 밖)
67
+
68
+ `TASK-NNN` 없는 작업 브랜치(`feature/claude_simple-config-fix` 등)는 *taskery 멀티세션 시스템 밖*에서 진행되는 단순/긴급 작업. SSoT 조회(`/task-init` 다음 번호 계산 / 진행중 목록)에서 자동 제외. **사용자 명시 운영 한정** — 메인 세션 자체 진입 금지.
69
+
56
70
  ---
57
71
 
58
72
  ## 커밋 태그
@@ -98,7 +112,8 @@ feat: [TASK-001] Phase 1 - 사용자 인증 로직 구현
98
112
  1. Phase별 기능 커밋 (각 Phase마다 1개)
99
113
  2. 태스크 문서 커밋
100
114
  3. CHANGELOG 커밋
101
- 4. dev 브랜치 병합 (--no-ff)
115
+ 4. dev 브랜치 병합 (--no-ff, 머지 락 직렬화)
116
+ 5. 워크트리 자동 제거 + 작업 브랜치 자동 삭제 (멀티세션 0.1.2+ — §"작업 브랜치 삭제 정책" 면제 조항)
102
117
  ```
103
118
 
104
119
  ### 태스크 문서 커밋 메시지
@@ -118,18 +133,111 @@ docs: [TASK-{NNN}] CHANGELOG 업데이트
118
133
  - 머지 커밋 메시지는 git 기본 메시지 사용
119
134
  - `-m` 옵션으로 커밋 메시지 지정 금지
120
135
  - **`--no-ff` 강제 (일반 타입)**: feature/bug/improvement/refactor 등 일반 작업 브랜치 → dev 병합 시 `git merge --no-ff {브랜치명}` 사용. fast-forward 병합 절대 금지. 머지 커밋이 없으면 작업 브랜치 삭제 후 분기 정보 영구 손실(90일 reflog GC 후 추적 불가).
121
- - **plan/roadmap 임시 docs 브랜치 예외**: 단일 커밋이라 `--ff-only` 가능.
136
+ - **plan/roadmap 임시 docs 브랜치 예외**: plan-init 단계의 단일 커밋(plan 신규/카피)에 한정 `--ff-only` 가능.
137
+ - **task 진행 중 ROADMAP/플랜 문서 갱신은 별도 `docs/*` 브랜치 분리 절대 금지**: 해당 task의 작업 브랜치 (`feature/*` / `improve/*` 등) 안에서 수정 + 다른 구현 커밋과 함께 `--no-ff` 머지로 dev 병합 (분기 정보 손실 방지).
122
138
 
123
139
  ---
124
140
 
125
141
  ## 작업 브랜치 삭제 정책
126
142
 
143
+ ### 기본 (멀티세션 외 / 케이스 2 / 사용자 수동 작업)
144
+
127
145
  작업 브랜치(feature/* / bug/* / improve/* / refactor/* / docs/* / chore/*)는 다음 조건 모두 만족 시에만 삭제한다:
128
146
  1. dev 브랜치에 `--no-ff` 병합 완료 (머지 커밋이 dev에 기록됨)
129
147
  2. 사용자 명시 승인 ("브랜치 삭제해" 등 직접 요청)
130
148
 
131
149
  **메인 세션 룰**: 사용자 승인 없는 작업 브랜치 삭제 지시 절대 금지. 머지 후 자동 삭제 X. 사용자가 직접 요청 시에만 `git branch -d {브랜치명}` 실행. (단, plan/roadmap 임시 docs 브랜치는 단일 커밋 ff-only 머지 후 자동 삭제 가능.)
132
150
 
151
+ ### `/task-close` 자동 삭제 면제 조항 (멀티세션 0.1.2+)
152
+
153
+ `/task-close` 마지막 단계의 *작업 브랜치 자동 삭제 + 워크트리 자동 제거*는 본 정책의 *사용자 명시 승인 룰* 면제 — 사용자가 `/task-close` 호출 자체로 *사전 승인*한 것으로 간주.
154
+
155
+ | 동작 | 명령 | 면제 사유 |
156
+ |------|------|----------|
157
+ | 워크트리 제거 | `git -C "$MAIN_WT" worktree remove "$WT_PATH"` | task 완료 후 격리 폴더 정리 필요. 사전 안전 검증 (§"멀티세션 워크트리 정책" 참조) 후 진행 |
158
+ | 작업 브랜치 삭제 | `git -C "$MAIN_WT" branch -d "$BRANCH"` | dev `--no-ff` 머지 완료 후 안전 삭제 (-D 강제 X). 머지 커밋이 dev에 박혀 분기 정보 보존 |
159
+
160
+ #### 보존 키워드 (양쪽 다 보존)
161
+
162
+ 사용자 발화에서 다음 키워드 감지 시 **워크트리 + 브랜치 모두 보존** (Step 11~13 건너뜀):
163
+ - `keep` / `--keep-branch` / `브랜치 남겨` / `브랜치 보존` / `브랜치 유지`
164
+
165
+ #### 사전 안전 검증 (자동 흐름 차단 트리거)
166
+
167
+ `/task-close` Step 11에서 다음 조건 발견 시 *자동 흐름 차단 + 사용자 호출*:
168
+ - 워크트리 안 미커밋 변경 (`git status --porcelain` 결과 있음)
169
+ - 워크트리 안 추적 X 파일 (`git ls-files --others --exclude-standard` 결과 있음)
170
+
171
+ 사용자 선택:
172
+ - 보존 → 워크트리 + 브랜치 모두 보존 (Step 12, 13 건너뜀)
173
+ - 삭제 → 정상 자동 흐름 (Step 12, 13 진행)
174
+ - 취소 → close 중단 (단, dev 머지는 이미 완료된 상태)
175
+
176
+ #### 안전망 출력 (브랜치 삭제 직후)
177
+
178
+ ```
179
+ 삭제됨: {브랜치명}
180
+ 복구: git -C "$MAIN_WT" branch {브랜치명} {머지 커밋 해시}
181
+ ```
182
+
183
+ #### 면제 범위 한정
184
+
185
+ 본 면제는 *`/task-close` 마지막 단계 자동 흐름 한정*. 그 외 모든 destructive 명령(`git reset --hard` / `git push --force` / `git branch -D` / `git clean -fd`)은 §"금지 사항" 그대로 사용자 명시 승인 필수.
186
+
187
+ ---
188
+
189
+ ## 멀티세션 워크트리 정책 (0.1.2+)
190
+
191
+ ### 메인 워크트리 = dev 전용
192
+
193
+ - 메인 워크트리는 항상 dev 체크아웃 상태 유지
194
+ - 모든 태스크 작업은 *별도 워크트리*에서 수행
195
+ - `/task-init` / `/task-close` 시작 시 검증 (위배 시 사용자 호출 + 중단)
196
+
197
+ ### 워크트리 위치
198
+
199
+ ```
200
+ ~/.taskery/worktrees/<projectId>/TASK-NNN_<출처>_<슬러그>/
201
+ ```
202
+
203
+ - `<projectId>`: `.taskery-manifest.json`의 `projectId` 필드 (8자 hex, taskery init 자동 생성)
204
+ - 부모 디렉토리는 `/task-init`이 자동 `mkdir -p`
205
+
206
+ ### 워크트리 생성 / 제거
207
+
208
+ | 작업 | 명령 | 주체 |
209
+ |------|------|------|
210
+ | 생성 | `git -C "$MAIN_WT" worktree add "$WT_PATH" -b "$BRANCH" dev` | `/task-init` |
211
+ | 제거 | `git -C "$MAIN_WT" worktree remove "$WT_PATH"` | `/task-close` (자동 흐름 + 안전 검증) |
212
+ | stale 정리 | `git -C "$MAIN_WT" worktree prune` | `npx @angar2/taskery prune` (사용자 확인 후) |
213
+
214
+ ### 메인 워크트리 절대 경로 검출
215
+
216
+ 워크트리 안에서 메인 워크트리 메타(`.project/`, `CLAUDE.md`)에 접근할 때 사용:
217
+
218
+ ```sh
219
+ MAIN_WT=$(dirname "$(git rev-parse --path-format=absolute --git-common-dir)")
220
+ ```
221
+
222
+ git ≥ 2.31 필요 (`--path-format=absolute` 옵션).
223
+
224
+ ### SSoT 조회 (진행중 태스크)
225
+
226
+ ```sh
227
+ git -C "$MAIN_WT" branch --no-merged dev --list \
228
+ 'feature/*_TASK-*' 'bug/*_TASK-*' 'improve/*_TASK-*' \
229
+ 'refactor/*_TASK-*' 'docs/*_TASK-*' 'chore/*_TASK-*'
230
+ ```
231
+
232
+ `_TASK-*` 패턴 강제로 케이스 2(TASK 없는 브랜치) 자동 제외. 별도 상태 파일/락 운영 X — git 분산 락(동일 브랜치명 자동 거부) + 결정적 슬러그(백로그/로드맵 항목 제목 → kebab-case)가 race 차단 2층 안전망.
233
+
234
+ ### 머지 직렬화 (head-to-head race 차단)
235
+
236
+ `/task-close` Step 6에서 `proper-lockfile` 기반 머지 락 (`~/.taskery/<projectId>.merge.lock`) 획득 후 rebase + 머지 시퀀스 실행:
237
+ - stale: manifest `lock_timeout_ms` (기본 30000ms)
238
+ - retries: 5회, 1초 간격
239
+ - 락 외 *사전 rebase* (UX용 조기 충돌 감지) → 락 안 *재 rebase*로 락 외에서 발생한 다른 세션 머지 흡수
240
+
133
241
  ---
134
242
 
135
243
  ## Hook 안전망 — `git-guard.sh`
@@ -167,3 +275,6 @@ docs: [TASK-{NNN}] CHANGELOG 업데이트
167
275
  | 2026-05-07 | `--no-ff` 강제 + 작업 브랜치 삭제 정책 + destructive 명령 사용자 승인 필수 룰 추가 |
168
276
  | 2026-05-08 | git 작업은 메인 세션이 `/task-close` 스킬 또는 직접 수행으로 단일화. git-guard.sh hook 안전망 명시 추가 |
169
277
  | 2026-05-09 | 표현 정제 — 인명 / 경박 표현 / 스킬 용어 / 이전 버전 비교 단락 정리 |
278
+ | 2026-05-30 | docs/* 브랜치 ff-only 예외 명시 — plan-init 단일 커밋 한정. task 진행 중 ROADMAP/플랜 갱신은 작업 브랜치 + --no-ff 명시 추가 (stash FRICTION_LOG #4 반영) |
279
+ | 2026-05-31 | 멀티세션 0.1.2 오버라이드 — 브랜치명에 출처(BL/RM/DR) 추가 / 케이스 2(TASK 없는 브랜치) 시스템 외 명시 / `/task-close` 자동 삭제 + 워크트리 제거 면제 조항 / 멀티세션 워크트리 정책 섹션 신규 (메인=dev 전용 / SSoT 조회 / 머지 락 직렬화) |
280
+ | 2026-05-31 | 0.1.2 백로그 스킬 추가 정합 — 출처 표 `BL-NNN` 채번 주체 `/backlog-add` → `/add-backlog`로 갱신 + 버전별 경로(`.project/tasks/<vX.X>/BACKLOG.md`) 명시 |
@@ -0,0 +1,85 @@
1
+ # MOCKUP_RULE
2
+
3
+ > 본 파일은 taskery 시스템 권장 UX/UI 구현 task의 HTML 목업 정책이다.
4
+ > 우선순위: **이 파일** (`.project/rules/MOCKUP_RULE.md`) → 메인 판단.
5
+ > 프로젝트별 변형이 필요하면 `.project/rules/MOCKUP_RULE.local.md` 생성 (npx update 미터치).
6
+
7
+ ---
8
+
9
+ ## 1. 목적
10
+
11
+ UX/UI 구현 task의 *시각 영역 사전 정합* + *task-test 시 USER 검수 기준 확보*. stash FRICTION_LOG #14+19 반영 — UX/UI 검증의 시각 fix 사이클 반복 마찰 사전 차단.
12
+
13
+ **효과**:
14
+ - 사용자가 *눈으로 보고* 의도 확인 → 인지 불일치 사전 차단
15
+ - 메인이 *시각 기준* 확보 → 구현 시 디자인 정합 검증 기준
16
+ - task-test USER 시각 시나리오의 *기준 파일* 역할
17
+
18
+ ---
19
+
20
+ ## 2. 적용 대상 task
21
+
22
+ **적용**:
23
+ - UX/UI 구현 포함 task (페이지 / 컴포넌트 신규 / 시각 변경 / 인터랙션 신규)
24
+ - `/task-plan` Step 2 Requirements 인터뷰 결과로 *UX/UI 구현 포함* 판단되면 Step 4.5 목업 프로세스 진입
25
+
26
+ **미적용**:
27
+ - 백엔드 / CLI / 인프라 / 설정 변경 등 시각 영역 없는 task
28
+ - UX/UI 포함이지만 사용자가 *"NO"* 응답한 task (Step 4.5에서 confirm)
29
+
30
+ ---
31
+
32
+ ## 3. 파일 위치 / 네이밍
33
+
34
+ - **경로**: `.project/tasks/<vX.X>/mockup/<task-doc-name>-mockup.html`
35
+ - **네이밍**: task 문서 파일명 + `-mockup.html`
36
+ - 예 1: `001_login-form.md` → `001_login-form-mockup.html`
37
+ - 예 2: 폴더 승격 `TASK-007_payment-flow/task.md` → `TASK-007_payment-flow-mockup.html`
38
+ - **task 1개 = 목업 1개** — multi-file 예외 영구 X. 복잡해도 한 파일 안 섹션 분리 (`<section id="popover">` 등)
39
+
40
+ ---
41
+
42
+ ## 4. 파일 형식
43
+
44
+ - 정적 HTML (외부 라이브러리 X)
45
+ - 단일 파일 안 inline `<style>` + 필요 시 vanilla `<script>`
46
+ - 시각 영역 (레이아웃 / 색상 / 간격 / 타이포 / 호버 효과) 본질 표현
47
+ - 인터랙션 가능 범위 (클릭 / 호버 시뮬) — 구현 정확도 ↑
48
+
49
+ ---
50
+
51
+ ## 5. 생성 흐름 (`/task-plan` Step 4.5 정합)
52
+
53
+ 1. UX/UI 구현 task 판단 (Step 2 Requirements 인터뷰 결과)
54
+ 2. 사용자에게 *"HTML 목업 만들까?"* 한 줄 confirm
55
+ 3. OK → 메인이 정적 HTML 생성 → 사용자 시각 승인 (✓ → 진행 / ✗ → 수정 재승인)
56
+ 4. 승인된 목업 = task-test의 *시각 영역 USER 검수 기준*
57
+
58
+ ---
59
+
60
+ ## 6. 두 시점 활용
61
+
62
+ | 시점 | 활용 |
63
+ |------|------|
64
+ | `/task-dev` | 메인이 *직접 Read* (sub-agent 위임 X) 후 구현. 구현 = 목업 기준 (역방향 X — 코드 편의로 목업 어김 절대 X) |
65
+ | `/task-test` | 격리 세션 prompt에서 *목업 파일 정독 후 시각 USER 시나리오 기준*으로 사용. 자동 비교 X. 사용자 검수 보고 시 *체크리스트 + 목업 경로 명시* |
66
+
67
+ ---
68
+
69
+ ## 7. 시각 fix 사이클 사전 예고
70
+
71
+ 시각 영역은 한 사이클로 100% 일치 보장 X. `/task-plan` Test Plan 작성 시 + `/task-test` 결과 보고 시 *"fix 사이클 1~2회 예상"* 사용자 안내 (기대치 사전 정렬, 부정 반응 누적 방지).
72
+
73
+ ---
74
+
75
+ ## 8. 디자인 산출 정독 의무
76
+
77
+ 목업 = 디자인 산출. 메인이 *직접 Read* 후 구현 (sub-agent 위임 X — 요약만 받아 시각 정합 깨짐 함정 회피). stash FRICTION_LOG #12 일반화.
78
+
79
+ ---
80
+
81
+ ## 9. 수정 이력
82
+
83
+ | 날짜 | 변경 사항 |
84
+ |------|----------|
85
+ | 2026-05-30 | 신규 작성 — UX/UI task HTML 목업 위치 / 형식 / 생성 흐름 / 두 시점 활용 / 시각 fix 사이클 예고 / 디자인 정독 의무 정의 (stash FRICTION_LOG #14+19 / #12 반영) |
@@ -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,29 +158,57 @@ 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. 정상 로그인 → 홈(/)으로 리다이렉트 + 세션 쿠키 확인.
176
-
177
- 검증 명령:
178
- - `npm run lint` PASS
179
- - `npm run typecheck` PASS
180
- - `npm run build` PASS
174
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
175
+ |---|---------|------|------|----------|
176
+ | 1 | <한 줄 설명> | [AUTO] / [USER] | <카탈로그 방식> | <명확한 기대값> |
177
+ | 2 | ... | ... | ... | ... |
181
178
  ```
182
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`) |
202
+
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
+
183
212
  ### 2.6 Result 기록 (`/task-dev`, `/task-test` 끝)
184
213
 
185
214
  1. `/task-dev` 끝에 phase별 진행 결과 기록:
@@ -310,25 +339,17 @@ draft → planned → developing → developed → testing → tested → closed
310
339
  ```markdown
311
340
  ## Test Plan
312
341
 
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
342
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
343
+ |---|---------|------|------|----------|
344
+ | 1 | 빈 이메일 + 비밀번호 제출 | [USER] | 수동 검수 | "이메일 입력 필요" + "비밀번호 입력 필요" 표시, API 호출 X |
345
+ | 2 | 잘못된 이메일 형식 ("abc") | [USER] | 수동 검수 | "올바른 이메일 형식 아님" 표시, API 호출 X |
346
+ | 3 | 짧은 비밀번호 ("123") | [USER] | 수동 검수 | "비밀번호 8자 이상 필요" 표시, API 호출 X |
347
+ | 4 | 정상값 제출 | [USER] | 수동 검수 | API 호출 → 정상 응답 시 / 리다이렉트 |
348
+ | 5 | 한국어 ↔ 영어 전환 | [USER] | 수동 검수 | 메시지 언어 따라 변경 |
330
349
  ```
331
350
 
351
+ > 검증 명령 / 테스트 명령은 `CLAUDE.md` 두 섹션을 격리 세션이 자동 참조 — Test Plan 본문 재인용 X.
352
+
332
353
  ### 4.6 Result
333
354
 
334
355
  **역할**: 진행 + 테스트 결과 통합. *"실제로 어떻게 됐는가"*.
@@ -379,8 +400,11 @@ draft → planned → developing → developed → testing → tested → closed
379
400
  - 진행: [x]
380
401
 
381
402
  ## Test Plan
382
- - `grep -n "Instalation" README.md` → 결과 0행.
383
- - `grep -n "Installation" README.md` → 1행 이상.
403
+
404
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
405
+ |---|---------|------|------|----------|
406
+ | 1 | README.md 안 오타 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Instalation" README.md` 결과 0건 |
407
+ | 2 | README.md 안 정정 표기 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Installation" README.md` 결과 1건 이상 |
384
408
 
385
409
  ## Result
386
410
 
@@ -479,32 +503,16 @@ draft → planned → developing → developed → testing → tested → closed
479
503
 
480
504
  ## Test Plan
481
505
 
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
506
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
507
+ |---|---------|------|------|----------|
508
+ | 1 | 정상 로그인 | [AUTO] | API/엔드포인트 호출 | POST /api/auth/login {email, password} → 200, body {token}, Set-Cookie: refreshToken |
509
+ | 2 | 잘못된 비밀번호 | [AUTO] | API/엔드포인트 호출 | 401, body {error: "이메일 또는 비밀번호가 올바르지 않습니다"} |
510
+ | 3 | 미등록 이메일 (enumeration 방어) | [AUTO] | API/엔드포인트 호출 | 401, body 메시지 #2와 동일 |
511
+ | 4 | 빈 입력 / 형식 오류 | [AUTO] | API/엔드포인트 호출 | 400, validation 에러 |
512
+ | 5 | JWT 검증 — 유효 토큰 | [AUTO] | API/엔드포인트 호출 | GET /api/protected with Authorization → 200 |
513
+ | 6 | JWT 검증 — 만료 / 무효 | [AUTO] | API/엔드포인트 호출 | 401 |
514
+ | 7 | Rate limit (11회 연속) | [AUTO] | 시나리오 스크립트 실행 | 11번째 요청 429, 헤더 X-RateLimit-Remaining: 0 |
515
+ | 8 | Refresh token | [AUTO] | API/엔드포인트 호출 | GET /api/auth/refresh with cookie → 200, 새 token 발급 |
508
516
 
509
517
  ## Result
510
518
 
@@ -573,18 +581,11 @@ draft → planned → developing → developed → testing → tested → closed
573
581
 
574
582
  ## Test Plan
575
583
 
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
584
+ | # | 시나리오 | 분류 | 방식 | PASS 기준 |
585
+ |---|---------|------|------|----------|
586
+ | 1 | iOS Safari 검색어 입력 후 검색 버튼 클릭 | [USER] | 수동 검수 | 페이지 URL의 search query만 갱신, 새로고침 X (네트워크 탭 document 요청 X) |
587
+ | 2 | 데스크톱 Chrome 동일 동작 (회귀) | [USER] | 수동 검수 | 회귀 X (기존 정상 동작 유지) |
588
+ | 3 | onSubmit handler preventDefault 회귀 테스트 | [AUTO] | 입출력 비교 | fireEvent.submit + expect(preventDefault) 호출 확인 |
588
589
 
589
590
  ## Result
590
591
 
@@ -612,3 +613,4 @@ draft → planned → developing → developed → testing → tested → closed
612
613
  | 2026-05-08 | 초안 — 5컬럼 헤더 / 7상태 / 6섹션 / 4단 layer 가이드 / 완성 예시 3개 |
613
614
  | 2026-05-08 | §1.5 추가 — task 파일/폴더/부속 자료 위치 단일 진실 소스. spec-diffs/screenshots는 vX.X 공통 통일. closed-immutable hook 보호 범위는 task.md 본 파일만 (스킬 본문 간 위치 모순 통일) |
614
615
  | 2026-05-09 | 표현 정제 — 인명 / 경박 표현 / 스킬 용어 / 이전 버전 비교 단락 정리 |
616
+ | 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 정합) |