@simplysm/sd-claude 14.0.55 → 14.0.57
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.
- package/claude/references/sd-simplysm-v14/sd-claude/assets.md +2 -4
- package/claude/rules/sd-claude-rules.md +29 -0
- package/claude/rules/sd-options.md +19 -22
- package/claude/rules/sd-response-format.md +35 -0
- package/claude/settings.json +2 -0
- package/claude/skills/sd-check/SKILL.md +30 -3
- package/claude/skills/sd-claude-docs/SKILL.md +62 -29
- package/claude/skills/sd-claude-docs/merge-source.py +47 -0
- package/claude/skills/sd-debug/SKILL.md +322 -31
- package/claude/skills/sd-debug/references/ach-matrix.md +154 -0
- package/claude/skills/sd-debug/references/branching-5whys.md +126 -0
- package/claude/skills/sd-debug/references/fishbone-categories.md +142 -0
- package/claude/skills/sd-debug/references/fta-template.md +176 -0
- package/claude/skills/sd-debug/references/repro-collab.md +159 -0
- package/claude/skills/sd-debug/references/repro-minimize.md +107 -0
- package/claude/skills/sd-debug/references/verification-tools.md +204 -0
- package/claude/skills/sd-deliverable/SKILL.md +1 -1
- package/claude/skills/sd-dev/SKILL.md +22 -71
- package/claude/skills/sd-inner-clarify/SKILL.md +24 -9
- package/claude/skills/sd-plan/SKILL.md +82 -21
- package/claude/skills/sd-prompt/SKILL.md +66 -23
- package/claude/skills/sd-prompt/references/eval-runner.md +2 -2
- package/claude/skills/sd-review/SKILL.md +201 -25
- package/claude/skills/sd-review/merge-source.py +66 -0
- package/claude/skills/sd-tdd/SKILL.md +2 -2
- package/claude/skills/sd-use/SKILL.md +5 -8
- package/claude/skills/sd-wbs/SKILL.md +90 -12
- package/package.json +1 -1
- package/claude/skills/sd-claude-docs/merge-source.sh +0 -23
- package/claude/skills/sd-dev/subagent-preamble.md +0 -22
- package/claude/skills/sd-inner-debug/SKILL.md +0 -145
- package/claude/skills/sd-inner-review/SKILL.md +0 -173
- package/claude/skills/sd-inner-review/merge-source.sh +0 -41
|
@@ -5,14 +5,38 @@ description: 프로젝트 요구사항을 Feature 단위로 분해하는 스킬.
|
|
|
5
5
|
|
|
6
6
|
# sd-wbs: 프로젝트 분해 (WBS)
|
|
7
7
|
|
|
8
|
+
WBS는 고객 중심으로 **무엇을 만들어야 하는지(What)** 를 확정하는 산출물이다.
|
|
9
|
+
Feature 범위에는 이후 `/sd-dev`가 바로 시작되어도 해석이 갈리지 않는 고객 동작과 업무 규칙만 남긴다.
|
|
10
|
+
|
|
8
11
|
## Step 1: 요구사항 수집
|
|
9
12
|
|
|
10
13
|
사용자가 제공한 요구사항에 대한 분석을 시작한다.
|
|
11
14
|
문서 파일(docx, xlsx, pdf 등)이 제공된 경우, `/sd-doc-extract`로 내용을 추출하여 분석한다.
|
|
12
15
|
기존 wbs 경로를 제공하고 수정하기를 원하는 경우, 해당 문서를 읽고 업데이트한다.
|
|
16
|
+
기존 WBS를 수정할 때는 기존 체크박스 상태(`[ ]`/`[x]`), Feature 번호, 사용자 메모, 이미 확정된 제외 사항을 임의 초기화·삭제하지 않는다.
|
|
17
|
+
Feature 번호 변경이 필요한 경우 기존 번호 → 새 번호 매핑과 변경 사유를 문서에 남긴다.
|
|
13
18
|
마이그레이션 등 기존 시스템이 요구사항 원천인 경우, 기존 코드베이스를 참조하여 기능을 파악한다.
|
|
14
19
|
요구사항과 함께 **프로젝트 개요**(배경, 환경, 전제조건, 기술적 제약)를 파악한다.
|
|
15
|
-
|
|
20
|
+
|
|
21
|
+
### 원본 완독 보고 (CRITICAL)
|
|
22
|
+
|
|
23
|
+
`/sd-inner-clarify`를 호출하기 **전에 반드시** 다음 보고를 출력한다. 보고 없이 명확화 단계로 진입하는 것은 **금지(NEVER)**.
|
|
24
|
+
|
|
25
|
+
**[원본 분석 보고]** 형식:
|
|
26
|
+
|
|
27
|
+
- 자료 1: `{파일경로 또는 메시지 영역}` ({분량: 페이지/라인/메일 통수 등}) — 완독 여부: [완독 | 부분({읽지 못한 구간})]. 핵심 발화/구절 요약: ...
|
|
28
|
+
- 자료 2: ...
|
|
29
|
+
|
|
30
|
+
규칙:
|
|
31
|
+
|
|
32
|
+
- **완독 의무**: 사용자가 제공한 모든 원본(첨부 파일, 정리된 마크다운, 메시지 본문, 메일 thread, 회의 대본 등)을 끝까지 읽는다. 키워드 검색만으로 종결하지 않는다.
|
|
33
|
+
- **메일 thread**: 모든 통수를 명시하고 각각 읽었음을 확인한다. 발신자/수신자/제목/일시를 식별 가능하게 적는다.
|
|
34
|
+
- **회의 대본**: 발화자 단위로 핵심 결정·요구를 추출한다. "전체 봄"으로 종결하면 위반.
|
|
35
|
+
- **분량 명시**: 각 자료의 페이지/라인/통수 등 분량을 객관 수치로 출력하여 부분 독해를 표면화한다.
|
|
36
|
+
- **부분 독해 금지**: "부분"으로 보고된 자료가 있으면 추가 읽기를 수행하여 완독 상태로 전환한다. 부분 상태로 `/sd-inner-clarify` 진입 금지.
|
|
37
|
+
- **사용자 메시지 본문 포함**: 메시지에 직접 붙여넣어진 요구사항·예시·제약도 자료로 취급하여 보고에 포함한다.
|
|
38
|
+
|
|
39
|
+
이 보고가 출력된 뒤에만 `/sd-inner-clarify` 스킬을 호출하여 명확화한다.
|
|
16
40
|
|
|
17
41
|
## Step 2: Impact Mapping
|
|
18
42
|
|
|
@@ -25,6 +49,28 @@ Impact Mapping 트리(Goal → Actor → Impact → Deliverable)를 구축한다
|
|
|
25
49
|
- 기술적 구현 방법(How) — 인증 방식, 통신 프로토콜, 프레임워크, 아키텍처 패턴 등 — 에 대한 결정은 분석 단계에서 하지 않는다.
|
|
26
50
|
- `/sd-inner-clarify` 스킬을 호출하여 명확화한다.
|
|
27
51
|
|
|
52
|
+
#### What/How 분류 규칙 (CRITICAL)
|
|
53
|
+
|
|
54
|
+
**다음 항목은 sd-wbs에서 반드시 확정한다 — sd-plan으로 위임 금지(NEVER):**
|
|
55
|
+
|
|
56
|
+
- 고객/사용자 동작, 업무 규칙, 정책, 예외 흐름
|
|
57
|
+
- 수치(최대/최소/기본값/허용 범위), 기간, 시간대, 경계값
|
|
58
|
+
- 권한, 역할, 상태, 상태 전이, 열거값(enum 후보)
|
|
59
|
+
- 화면/플로우의 분기 조건과 결과
|
|
60
|
+
- 기능 포함 여부 자체
|
|
61
|
+
|
|
62
|
+
**다음 항목은 sd-plan에서 결정한다 — sd-wbs에서 묻지 않는다:**
|
|
63
|
+
|
|
64
|
+
- 인증 방식, 통신 프로토콜, 프레임워크, 아키텍처 패턴
|
|
65
|
+
- DB 종류, API 형태, 컴포넌트 구조, 테스트 분해
|
|
66
|
+
- 라이브러리 선택, 의존성 주입, import 패턴
|
|
67
|
+
|
|
68
|
+
**분류가 모호하면 What으로 분류한다 (default = sd-wbs 확정 대상).**
|
|
69
|
+
|
|
70
|
+
- "plan에서 결정될 것 같다"는 자체 판단으로 위임 금지(NEVER).
|
|
71
|
+
- "어차피 sd-plan이 WBS 미확정/누락을 되돌릴 것이다"는 안전망 의존 금지(NEVER). 그 절차는 sd-wbs의 누락을 잡는 백업이지, sd-wbs의 책임을 다음 단계로 떠넘기는 경로가 아니다.
|
|
72
|
+
- 모호한 항목은 `/sd-inner-clarify`로 사용자에게 직접 질문하여 What/How를 확정한다.
|
|
73
|
+
|
|
28
74
|
### 명확화 항목
|
|
29
75
|
|
|
30
76
|
| 질문 | 도출 요소 |
|
|
@@ -108,16 +154,17 @@ Feature는 독립적으로 설계·개발·검증할 수 있는 최소 **기능*
|
|
|
108
154
|
|
|
109
155
|
### Feature 병합 규칙
|
|
110
156
|
|
|
111
|
-
**CRITICAL: 기계적 판정 규칙 (예외 없음, 재량 금지)**
|
|
157
|
+
**CRITICAL: 기계적 판정 규칙 (조건 충족 시 예외 없음, 재량 금지)**
|
|
112
158
|
|
|
113
159
|
아래 중 **하나라도** 해당하면 무조건(MUST) 해당 Feature들을 단일 Feature로 병합한다.
|
|
114
160
|
|
|
115
161
|
1. **Feature 이름에 Actor(역할)가 괄호/접미사로 포함된 경우** (예: "(관리자)", "(직원)", "(고객)", "관리자용", "직원용")
|
|
116
162
|
2. **동일 도메인 엔터티에 대해 아키텍처 레이어별로 Feature를 분할한 경우** (예: "도서 DB 스키마", "도서 API", "도서 UI")
|
|
117
|
-
3.
|
|
163
|
+
3. **동일 도메인 엔터티 또는 동일 업무 흐름 안에서 두 Feature의 범위에 동일하거나 유사한 사용자 동작이 각각 등장하는 경우** (예: "도서 목록 조회(관리자)", "도서 목록 조회(직원)") — 뷰/필터/권한/Actor 차이는 병합 사유를 면제하지 않는다
|
|
118
164
|
|
|
119
165
|
그 외 규칙:
|
|
120
166
|
|
|
167
|
+
- 동작명이 유사하더라도 도메인 엔터티, 업무 목적, 생명주기가 다르면 병합하지 않는다. (예: "도서 목록 조회" + "주문 목록 조회" — 병합하지 않음)
|
|
121
168
|
- 같은 세부기능을 공유한다는 이유로 독립 모듈을 하나의 Feature로 묶지 않는다. (예: event-bus Feature + 모달 Feature + 토스트 Feature — 묶지 않음)
|
|
122
169
|
- 범주는 Epic, 개별 기능이 Feature (예: "알림" Epic → 토스트 알림, 모달 알림, 이메일 알림 각각이 Feature)
|
|
123
170
|
- 가능한한 의존성 순서로 정렬
|
|
@@ -127,11 +174,32 @@ Feature는 독립적으로 설계·개발·검증할 수 있는 최소 **기능*
|
|
|
127
174
|
|
|
128
175
|
각 Feature에는 다음 4가지를 반드시 포함한다.
|
|
129
176
|
|
|
130
|
-
- **범위**: 해당 Feature의 세부 기능을 사용자 기능(user-facing function) 수준으로 **MUST 빠짐없이** 나열한다. (절대 누락되어선 안된다. 누락된것은 다음단계에서 제외사항으로 판단될 수 있다.)
|
|
177
|
+
- **범위**: 해당 Feature의 세부 기능을 사용자 기능(user-facing function) 수준으로 **MUST 빠짐없이** 나열한다. 각 범위 항목 끝에는 항목별 근거를 `(근거: ...)` 형식으로 반드시 기재한다. (절대 누락되어선 안된다. 누락된것은 다음단계에서 제외사항으로 판단될 수 있다.)
|
|
131
178
|
- **경계**: 이 Feature가 **하지 않는 것** 중 다른 Feature에서 다루거나 다룰 수 있는 것을 명시한다. 인접 Feature와의 경계가 모호한 경우 특히 중요하다. (프로젝트 전체에서 제외되는 항목은 문서 하단의 "제외 사항"에 기재한다.)
|
|
132
|
-
- **근거**: 범위가 도출된 근거 혹은 출처를 명시한다. (요구사항, 사용자 답변, 첨부문서 등) 개발에 필요한 참조 파일/자료 경로가 있으면 확인 목적과 함께 기록한다.
|
|
179
|
+
- **근거**: 범위가 도출된 근거 혹은 출처를 명시한다. (Impact Mapping Deliverable, 요구사항, 사용자 답변, 첨부문서 등) 개발에 필요한 참조 파일/자료 경로가 있으면 확인 목적과 함께 기록한다.
|
|
133
180
|
- **의존성**: 다른 Feature와의 의존 관계를 기록한다. 형식: Feature 번호만 쉼표로 나열 (예: `1.1, 2.3`) 또는 `없음`. 의존성에 따라 병렬 진행할 수 있으므로 정확한 판단이 **CRITICAL**.
|
|
134
181
|
|
|
182
|
+
#### 범위 항목 작성 형식
|
|
183
|
+
|
|
184
|
+
범위 항목은 `대상/사용자 + 동작 + 조건/결과 + 항목별 근거`가 드러나는 문장으로 작성한다.
|
|
185
|
+
|
|
186
|
+
- **좋은 예:** 사용자는 도서명 또는 저자명으로 도서 목록을 검색한다. (근거: 요구사항 2.1)
|
|
187
|
+
- **좋은 예:** 검색 결과가 없으면 빈 결과 상태를 확인한다. (근거: 사용자 답변)
|
|
188
|
+
- **나쁜 예:** 검색 기능
|
|
189
|
+
- **나쁜 예:** 도서 목록 개선
|
|
190
|
+
|
|
191
|
+
항목별 근거가 없는 범위는 Feature에 포함하지 않는다. 필요해 보이지만 근거가 없으면 `/sd-inner-clarify`로 포함 여부를 질문한다.
|
|
192
|
+
|
|
193
|
+
### 미확정 요구 처리 규칙
|
|
194
|
+
|
|
195
|
+
**CRITICAL: Feature 범위에는 구현자가 바로 `/sd-dev`로 들어가도 해석이 갈리지 않는 확정된 고객 동작과 업무 규칙만 남긴다.**
|
|
196
|
+
|
|
197
|
+
- WBS Feature 안에는 "후속 확정", "보류", "추후 결정", "협의 필요" 같은 미확정 usecase를 넣지 않는다.
|
|
198
|
+
- 원문에 미확정이라고 적힌 고객 요구, 업무 규칙, 정책, 예외 흐름은 WBS 작성 시점에 `/sd-inner-clarify`로 질문하여 **확정될 때까지 반복**한다. 추정 진행이나 "추후 결정" fallback은 금지(NEVER).
|
|
199
|
+
- 사용자가 명시적으로 "포함 안 함"으로 결정한 항목만 "제외 사항"에 기재한다.
|
|
200
|
+
- Feature의 범위 항목은 완료 판정 가능한 사용자 동작으로만 작성하고, 각 항목에 출처를 남긴다.
|
|
201
|
+
- 기술 구현 방식(API 형태, DB 구조, 프레임워크, 테스트 분해 등)은 WBS에서 결정하지 않는다. 해당 결정은 `/sd-plan`에서 다룬다.
|
|
202
|
+
|
|
135
203
|
#### 의존성 판단 절차
|
|
136
204
|
|
|
137
205
|
의존성은 아래 두 종류를 모두 판단한다:
|
|
@@ -183,6 +251,13 @@ Feature를 작성하다가 "이건 시스템 동작상 당연히 필요하다"
|
|
|
183
251
|
4. **Feature 독립성 (단일 책임)** — 한 Feature의 이름과 실제 범위가 일치하는지 확인한다. 이름에 드러나지 않는 일을 몰래 수행하면 분리한다.
|
|
184
252
|
5. **병합 규칙 준수** — Step 3 "Feature 병합 규칙"의 기계적 판정 규칙을 위반하는 Feature가 없는지 확인한다.
|
|
185
253
|
6. **범위 항목의 검증 가능성** — 각 세부 기능이 완료 판정 가능한 구체적 표현인지 확인한다. "개선한다", "최적화한다" 같은 모호한 표현은 구체 동작으로 재작성한다.
|
|
254
|
+
7. **미확정 요구 제거** — "후속 확정", "보류", "추후 결정", "협의 필요" 같은 표현이 Feature 범위/경계/근거에 남아 있으면 `/sd-inner-clarify`로 확정 질문을 수행하여 모두 확정 처리한다.
|
|
255
|
+
8. **범위 항목별 근거 확인** — 모든 범위 항목 끝에 `(근거: ...)`가 있는지 확인한다. 근거가 없는 항목은 `/sd-inner-clarify`로 확정 처리한다.
|
|
256
|
+
9. **plan 위임 차단** — Feature 범위/경계/근거에 "plan에서 결정", "구현 시 결정", "추후 결정", "협의 필요", "별도 확정" 같은 표현이나 sd-plan으로 위임 대기 중인 항목이 남아 있는지 점검한다. 발견 시 다음 절차를 수행한다.
|
|
257
|
+
- Step 2 "What/How 분류 규칙"에 따라 해당 항목의 영역을 재분류한다.
|
|
258
|
+
- **What으로 분류되면** `/sd-inner-clarify`로 확정 질문을 강제하고, 답변을 받아 Feature 범위에 반영한다.
|
|
259
|
+
- **How로 분류되면** 해당 항목을 Feature 범위에서 제거하고, 경계 또는 근거에 "sd-plan에서 결정"임을 명시한다.
|
|
260
|
+
- **"plan으로 미루기" 표현을 그대로 남기는 것은 금지(NEVER).**
|
|
186
261
|
|
|
187
262
|
### 의존성 매트릭스
|
|
188
263
|
|
|
@@ -242,8 +317,8 @@ Feature를 작성하다가 "이건 시스템 동작상 당연히 필요하다"
|
|
|
242
317
|
|
|
243
318
|
**범위:**
|
|
244
319
|
|
|
245
|
-
-
|
|
246
|
-
- 배경 클릭으로 닫기
|
|
320
|
+
- 사용자는 상세 정보를 팝업으로 열고 닫는다. (근거: 요구사항 "팝업 형태로 상세 정보 표시")
|
|
321
|
+
- 사용자는 배경 클릭으로 팝업을 닫는다. (근거: 사용자 답변 "배경 클릭으로 닫기 필요")
|
|
247
322
|
|
|
248
323
|
**경계:**
|
|
249
324
|
|
|
@@ -251,30 +326,33 @@ Feature를 작성하다가 "이건 시스템 동작상 당연히 필요하다"
|
|
|
251
326
|
|
|
252
327
|
**근거:**
|
|
253
328
|
|
|
329
|
+
- Impact Mapping Deliverable: "상세 정보 팝업"
|
|
254
330
|
- 요구사항: "팝업 형태로 상세 정보 표시"
|
|
255
331
|
- 사용자 답변: "배경 클릭으로 닫기 필요"
|
|
256
332
|
|
|
257
333
|
## 제외 사항
|
|
258
334
|
|
|
259
|
-
-
|
|
335
|
+
- 애니메이션 효과 — 사유: 사용자 명시적 제외 / 출처: 사용자 답변 / 재검토 조건: 별도 UX 개선 Feature 요청 시
|
|
260
336
|
```
|
|
261
337
|
|
|
262
338
|
**진행 상황:** Feature별 `[ ]` 체크박스로 진행을 추적한다.
|
|
263
339
|
|
|
264
340
|
**제외 사항:**
|
|
265
341
|
|
|
266
|
-
-
|
|
267
|
-
- 각
|
|
342
|
+
- 사용자가 명시적으로 "포함 안 함"으로 결정한 항목과 Impact Mapping에서 Goal에 연결되지 않는 기능을 나열한다.
|
|
343
|
+
- 각 항목은 `제외 항목 — 사유: ... / 출처: ... / 재검토 조건: ...` 형식으로 작성한다.
|
|
344
|
+
- 사유에는 Goal 미연결, 사용자 명시적 제외, 범위 초과 중 하나를 사용한다. "미확정"은 사유로 사용하지 않는다 (미확정은 `/sd-inner-clarify`로 반드시 확정 처리).
|
|
268
345
|
|
|
269
346
|
## Step 6: 정보 유실 방지 검증
|
|
270
347
|
|
|
271
348
|
문서 작성 후, 대화에서 수집한 모든 구체적 정보가 문서에 기록되었는지 검증한다.
|
|
272
349
|
|
|
273
|
-
- 사용자의 답변에 포함된 구체적 수치, 열거 항목, 업무 규칙, 제약 조건이 누락 없이 Feature 근거 또는 프로젝트 개요에 기록되었는가?
|
|
350
|
+
- 사용자의 답변에 포함된 구체적 수치, 열거 항목, 업무 규칙, 제약 조건이 누락 없이 Feature 범위의 항목별 근거, Feature 근거 또는 프로젝트 개요에 기록되었는가?
|
|
274
351
|
- 언급된 참조 파일/문서 경로가 확인 목적과 함께 기록되었는가?
|
|
352
|
+
- 기존 WBS를 수정한 경우 체크박스 상태, Feature 번호, 사용자 메모, 제외 사항이 임의 초기화·삭제되지 않았는가?
|
|
275
353
|
- 누락 발견 시 문서에 반영한 뒤 저장한다.
|
|
276
354
|
|
|
277
|
-
**
|
|
355
|
+
**CRITICAL: 각 Feature는 새 세션에서 진행되므로, 절대(NEVER) WBS 문서에 누락이 있어서는 안됨**
|
|
278
356
|
|
|
279
357
|
## Step 7: 수행 순서 안내
|
|
280
358
|
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# 패키지 소스 파일을 하나의 텍스트 파일로 병합
|
|
3
|
-
# Usage: merge-source.sh <패키지경로> <출력파일경로>
|
|
4
|
-
|
|
5
|
-
pkg_path="$1"
|
|
6
|
-
output="$2"
|
|
7
|
-
|
|
8
|
-
if [ -z "$pkg_path" ] || [ -z "$output" ]; then
|
|
9
|
-
echo "Usage: $0 <package-path> <output-file>" >&2
|
|
10
|
-
exit 1
|
|
11
|
-
fi
|
|
12
|
-
|
|
13
|
-
mkdir -p "$(dirname "$output")"
|
|
14
|
-
|
|
15
|
-
files=$(find "$pkg_path/src" -name "*.ts" 2>/dev/null | sort)
|
|
16
|
-
[ -d "$pkg_path/scss" ] && files+=$'\n'$(find "$pkg_path/scss" -name "*.scss" 2>/dev/null | sort)
|
|
17
|
-
|
|
18
|
-
echo "$files" | while IFS= read -r f; do
|
|
19
|
-
[ -z "$f" ] && continue
|
|
20
|
-
echo "=== $f ==="
|
|
21
|
-
cat "$f"
|
|
22
|
-
echo
|
|
23
|
-
done > "$output"
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# subagent 실행 환경
|
|
2
|
-
|
|
3
|
-
## 도구 제약
|
|
4
|
-
|
|
5
|
-
- **Skill 도구 사용 불가.** 스킬 호출(`/sd-xxx`)이 필요하면 해당 `.claude/skills/{스킬명}/SKILL.md`를 Read하여 직접 수행하세요.
|
|
6
|
-
- 예: `/sd-inner-clarify` → `.claude/skills/sd-inner-clarify/SKILL.md`를 Read하여 수행
|
|
7
|
-
- 예: `/sd-inner-debug` → `.claude/skills/sd-inner-debug/SKILL.md`를 Read하여 수행
|
|
8
|
-
- **AskUserQuestion 도구 사용 불가.** sd-options 규칙(`.claude/rules/sd-options.md`)의 AskUserQuestion 호출 의무는 아래 NEED_INPUT 프로토콜로 대체합니다.
|
|
9
|
-
- 그 외 프로젝트 규칙(`.claude/rules/`)은 모두 준수하세요.
|
|
10
|
-
|
|
11
|
-
## NEED_INPUT 프로토콜
|
|
12
|
-
|
|
13
|
-
사용자에게 질문/확인/선택지 제시가 필요할 때, 작업을 중단하고 아래 형식으로 응답을 종료합니다.
|
|
14
|
-
상위 에이전트(sd-dev)가 사용자와 상호작용한 뒤 SendMessage로 결정을 전달합니다.
|
|
15
|
-
|
|
16
|
-
---NEED_INPUT---
|
|
17
|
-
상황: {상황 설명 - 충분한 맥락 포함}
|
|
18
|
-
선택지:
|
|
19
|
-
- A) {label}: {description}
|
|
20
|
-
- B) {label}: {description}
|
|
21
|
-
추천: {추천 선택지와 사유}
|
|
22
|
-
---END_NEED_INPUT---
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sd-inner-debug
|
|
3
|
-
description: 근본 원인 분석(ACH) 로직. 문제 발생시, 원인분석 및 해결방안을 도축하기 위해 사용한다.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# sd-inner-debug: 근본 원인 분석
|
|
7
|
-
|
|
8
|
-
## 공통 규칙
|
|
9
|
-
|
|
10
|
-
### 분석 원칙
|
|
11
|
-
|
|
12
|
-
- **근본 원인 제거**: 증상을 숨기는 해결이 아닌, 원인 자체를 제거하는 방향으로 분석한다. 반드시 "왜 이 문제가 발생하는가?"를 근원까지 추적한다.
|
|
13
|
-
- **추측 금지**: "~일 수 있다", "~가능성이 높다"로 원인을 단정하지 않는다. 코드를 읽고, 로그를 확인하고, 재현하여 **증거 기반**으로 원인을 특정한다.
|
|
14
|
-
- **외부 탓 금지**: 라이브러리/런타임 버그를 원인으로 지목하기 전에, 내 코드가 해당 API를 올바르게 사용하고 있는지 먼저 검증한다. 공식 문서·소스코드·이슈 트래커에서 동일 보고가 없으면 내 코드 문제로 간주한다.
|
|
15
|
-
- **우회 해결 금지**: 증상을 감지하여 보정하는 코드는 근본 해결이 아니다. API를 잘못 사용하고 있다면 사용 방식 자체를 수정한다.
|
|
16
|
-
|
|
17
|
-
#### 편법/우회방법 금지 목록
|
|
18
|
-
|
|
19
|
-
| 편법(예시) | 문제 |
|
|
20
|
-
| -------------------------------------------- | ------------------------------------------------------ |
|
|
21
|
-
| `setTimeout` / `requestAnimationFrame` | 타이밍 문제를 회피할 뿐 해결하지 않는다 |
|
|
22
|
-
| `try-catch`로 에러 무시 | 런타임 문제를 숨긴다 |
|
|
23
|
-
| `as any` / `any` 타입 | 타입 안전성을 포기한다 |
|
|
24
|
-
| `@ts-ignore` / `@ts-expect-error` | 타입 에러를 숨길 뿐 해결하지 않는다 |
|
|
25
|
-
| `// eslint-disable` / `/* eslint-disable */` | 린트 규칙을 무력화한다 |
|
|
26
|
-
| 플래그 변수 (`isReady`, `isLoaded`) | 조건을 우회한다 |
|
|
27
|
-
| `?.` 옵셔널 체이닝으로 undefined 무시 | 값이 undefined/null인 원인을 추적하지 않고 `?.`로 무시한다 |
|
|
28
|
-
| `.skip` / 테스트 삭제 | 테스트 커버리지를 줄인다 |
|
|
29
|
-
|
|
30
|
-
### ACH 매트릭스 셀 정의
|
|
31
|
-
|
|
32
|
-
각 셀은 다음 중 하나:
|
|
33
|
-
|
|
34
|
-
- **C (Consistent):** 증거가 가설과 일치 — 반드시 증거 등급을 함께 표기한다:
|
|
35
|
-
- `C(code)`: 코드에서 직접 관찰 (변수값, 호출 체인, 설정 파일, 타입 정의 등)
|
|
36
|
-
- `C(doc)`: 공식 문서, GitHub 이슈, changelog, 라이브러리 소스 코드에서 확인
|
|
37
|
-
- `C(infer)`: 직접 확인 불가, 추론에 기반 — **이 등급만으로는 가설을 확정할 수 없다**
|
|
38
|
-
- **I (Inconsistent):** 증거가 가설과 불일치 — 코드에서 직접 관찰 가능한 모순이 있을 때만 표시. 추론/추측에 의한 I 표시 금지.
|
|
39
|
-
- **N (Neutral):** 증거가 가설과 무관
|
|
40
|
-
|
|
41
|
-
**외부 라이브러리/프레임워크 동작에 대한 가설** (예: "X 라이브러리가 Y를 인식하지 못한다")은 반드시 다음 중 하나로 뒷받침해야 `C(doc)` 이상이 된다:
|
|
42
|
-
|
|
43
|
-
- GitHub 이슈 (`gh search issues` 또는 `WebSearch`로 검색)
|
|
44
|
-
- 공식 문서/changelog
|
|
45
|
-
- 라이브러리 소스 코드에서 해당 동작을 직접 확인
|
|
46
|
-
|
|
47
|
-
뒷받침 없이 "그럴 것이다"라고 추정하면 `C(infer)`이며, 이것만으로는 가설을 확정할 수 없다.
|
|
48
|
-
|
|
49
|
-
## Step 1: 문제 식별
|
|
50
|
-
|
|
51
|
-
### 1-1. GitHub 이슈 입력
|
|
52
|
-
|
|
53
|
-
입력이 GitHub 이슈 참조(`owner/repo#N` 또는 `#N`)인 경우, `gh issue view`로 이슈 내용을 조회하여 아래 항목을 추출한다. `#N`만 입력된 경우 현재 리포의 이슈로 간주한다.
|
|
54
|
-
|
|
55
|
-
### 1-2. 추출 항목
|
|
56
|
-
|
|
57
|
-
사용자 입력(또는 조회된 이슈)에서 다음을 추출한다:
|
|
58
|
-
|
|
59
|
-
- **증상** — 해당하는 유형으로 기록:
|
|
60
|
-
- **에러 유형:** 에러 메시지 원문 인용
|
|
61
|
-
- **동작 이상 유형:** 기대 동작과 실제 동작을 각각 명시
|
|
62
|
-
- **위치** — 에러 발생 파일:라인 또는 관련 기능/화면
|
|
63
|
-
- **재현 절차** — 문제가 발생하는 구체적 조작 순서
|
|
64
|
-
|
|
65
|
-
`/sd-inner-clarify` 스킬을 호출하여 명확화한다.
|
|
66
|
-
|
|
67
|
-
## Step 2: 근본 원인 추적 (ACH)
|
|
68
|
-
|
|
69
|
-
### 2-1. 복수가설 생성
|
|
70
|
-
|
|
71
|
-
수집된 컨텍스트로부터 원인 가설을 **2개 이상** 세운다. 다음 카테고리를 고려하여 다양한 가설을 확보한다:
|
|
72
|
-
|
|
73
|
-
- 입력/데이터 문제
|
|
74
|
-
- 상태 관리 문제
|
|
75
|
-
- 타이밍/순서 문제
|
|
76
|
-
- 타입/형변환 문제
|
|
77
|
-
- 환경/설정 문제
|
|
78
|
-
- 최근 변경에 의한 회귀
|
|
79
|
-
|
|
80
|
-
**ACH 매트릭스 초기화:** 가설 x 증거 매트릭스를 구성한다. 현재까지 수집된 증거(에러 메시지, 재현 조건, 코드 분석 결과)를 초기 증거로 등록한다.
|
|
81
|
-
|
|
82
|
-
### 2-2. 실험 → 업데이트 → 폐기 (반복)
|
|
83
|
-
|
|
84
|
-
**판별 실험 선택:** 가설을 가장 많이 구분할 수 있는 검증 도구를 선택하여 실험한다.
|
|
85
|
-
|
|
86
|
-
| 검증 도구 | 적용 조건 |
|
|
87
|
-
| -------------------- | ------------------------------------------------- |
|
|
88
|
-
| **역추적** | 스택 트레이스가 있거나 문제 발현 지점이 명확할 때 |
|
|
89
|
-
| **데이터 흐름 추적** | 잘못된 값이 출력되거나 기대와 다른 결과가 나올 때 |
|
|
90
|
-
| **변경 이력 분석** | "이전엔 됐는데 안 됨", 회귀가 의심될 때 |
|
|
91
|
-
| **제약 조건 추론** | 간헐적이거나 특정 환경/입력에서만 발생할 때 |
|
|
92
|
-
|
|
93
|
-
**매트릭스 업데이트:** 실험 결과를 새 증거로 추가하고, 각 가설에 대해 C/I/N을 표시한다.
|
|
94
|
-
|
|
95
|
-
**가설 폐기:** I(불일치)가 있는 가설만 폐기한다.
|
|
96
|
-
|
|
97
|
-
**분석 한계 명시:** 런타임 데이터(API 응답, DB 결과 등)를 직접 확인할 수 없는 경우, 그 한계를 ACH 결과에 명시한다 — "실제 데이터를 확인하지 못했으므로 추정에 기반한 판정"임을 밝힌다.
|
|
98
|
-
|
|
99
|
-
#### 검증 도구 상세
|
|
100
|
-
|
|
101
|
-
**역추적 (Backward Reasoning)** — 문제 발현 지점에서 출발하여 원인 방향으로 거슬러 올라간다:
|
|
102
|
-
|
|
103
|
-
1. 문제 발생 지점의 변수 상태 확인
|
|
104
|
-
2. 해당 변수의 마지막 할당(definition) 위치 추적
|
|
105
|
-
3. 잘못된 값이 최초로 유입된 지점까지 반복
|
|
106
|
-
|
|
107
|
-
**데이터 흐름 추적 (Data Flow Tracing)** — 데이터의 생명주기를 따라가며 불일치 지점을 찾는다:
|
|
108
|
-
|
|
109
|
-
1. Input 지점 식별 (API 요청, DB 읽기, 사용자 입력 등)
|
|
110
|
-
2. Transform 체인을 순서대로 나열 (함수 호출, 매핑, 직렬화 등)
|
|
111
|
-
3. 각 단계의 기대값 vs 실제값 비교
|
|
112
|
-
4. 최초 불일치 지점 = 버그 위치
|
|
113
|
-
|
|
114
|
-
**변경 이력 분석 (Change History Analysis)** — 최근 변경과 버그의 상관관계를 분석한다:
|
|
115
|
-
|
|
116
|
-
1. 버그 발생 시점 전후의 코드 변경 조회 (`git log`, `git diff`)
|
|
117
|
-
2. 에러 관련 파일과 변경된 파일의 교집합 분석
|
|
118
|
-
3. 변경 내용의 의미적 분석 (리팩토링 vs 로직 변경 vs API 계약 변경)
|
|
119
|
-
|
|
120
|
-
**제약 조건 추론 (Constraint-based Reasoning)** — 발생/비발생 조건을 체계적으로 좁혀간다:
|
|
121
|
-
|
|
122
|
-
1. 발생 조건 수집: 어떤 입력/환경/순서에서 발생하는가?
|
|
123
|
-
2. 비발생 조건 수집: 어떤 경우 발생하지 않는가?
|
|
124
|
-
3. 차이 분석: 발생/비발생 조건의 차이가 원인을 가리킴
|
|
125
|
-
|
|
126
|
-
#### 반복 규칙
|
|
127
|
-
|
|
128
|
-
- 남은 가설 0개면 현재까지의 분석 결과를 사용자에게 보고하고, 추가 컨텍스트를 요청한다
|
|
129
|
-
|
|
130
|
-
## Step 3: 방안 제시
|
|
131
|
-
|
|
132
|
-
### 출력 규칙
|
|
133
|
-
|
|
134
|
-
- **폐기된 가설 제외**: Step 2에서 I(불일치)로 폐기된 가설은 방안 제시에 포함하지 않는다. 살아남은 가설의 해결방안만 선택지로 제시한다.
|
|
135
|
-
- **ACH 매트릭스 비출력**: 매트릭스 전체를 사용자에게 출력하지 않는다. 분석 결과는 살아남은 원인과 그 근거만 간결하게 요약한다.
|
|
136
|
-
|
|
137
|
-
### 선택지 구성
|
|
138
|
-
|
|
139
|
-
살아남은 원인별 해결방안을 선택지로 구성한다. 원인이 1개면 해당 원인의 방안들이 선택지가 되고, 원인이 복수면 각 "원인X.방안Y"가 선택지가 된다.
|
|
140
|
-
|
|
141
|
-
각 선택지에는 **반론**(이 원인/방안이 틀릴 수 있는 이유)을 반드시 포함한다.
|
|
142
|
-
|
|
143
|
-
### 양식
|
|
144
|
-
|
|
145
|
-
@.claude/rules/sd-options.md 를 그대로 따른다. 별도 양식을 사용하지 않는다.
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sd-inner-review
|
|
3
|
-
description: (내부 전용) 코드 리뷰 분석 로직. sd-review, sd-dev 등에서 호출된다. 직접 호출하지 않는다.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# sd-inner-review: 코드 리뷰 분석
|
|
7
|
-
|
|
8
|
-
## Step 1: 대상 결정
|
|
9
|
-
|
|
10
|
-
인자로 경로가 지정되면 해당 경로, 미지정이면 프로젝트 전체를 분석한다.
|
|
11
|
-
|
|
12
|
-
- `/sd-inner-review src/services` → `src/services` 하위만
|
|
13
|
-
- `/sd-inner-review` → 프로젝트 루트 전체
|
|
14
|
-
|
|
15
|
-
**CRITICAL: git 명령 사용 금지.** `git diff`, `git status`, `git log`, `git show` 등 git 명령으로 대상 파일을 결정하지 않는다. 리뷰 대상은 오직 인자로 지정된 경로 또는 대화 맥락에서 사용자가 지정한 범위이다. "최근 변경 파일", "커밋된 파일" 등의 개념으로 대상을 좁히지 않는다.
|
|
16
|
-
|
|
17
|
-
## Step 2: 컨텍스트 수집
|
|
18
|
-
|
|
19
|
-
프로젝트의 기술 스택, 컨벤션등의 규칙을 파악한다.
|
|
20
|
-
|
|
21
|
-
### 소스 수집
|
|
22
|
-
|
|
23
|
-
대상 경로 유형에 따라 소스를 수집한다.
|
|
24
|
-
|
|
25
|
-
- **패키지 디렉토리** (경로 내 `src/` 존재): `merge-source.sh`로 병합하여 단일 파일로 읽는다.
|
|
26
|
-
```bash
|
|
27
|
-
TS=$(date +%y%m%d%H%M%S)
|
|
28
|
-
bash .claude/skills/sd-inner-review/merge-source.sh ./.tmp/review/$TS.txt --dir <패키지경로>
|
|
29
|
-
```
|
|
30
|
-
- **개별 파일 목록**:
|
|
31
|
-
- **5개 미만**: 각 파일을 개별 Read로 읽는다.
|
|
32
|
-
- **5개 이상**: `merge-source.sh`로 병합하여 단일 파일로 읽는다.
|
|
33
|
-
```bash
|
|
34
|
-
TS=$(date +%y%m%d%H%M%S)
|
|
35
|
-
bash .claude/skills/sd-inner-review/merge-source.sh ./.tmp/review/$TS.txt --files <파일1> <파일2> ...
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Step 3: 분석
|
|
39
|
-
|
|
40
|
-
대상 파일을 읽고, 4가지 관점으로 이슈를 탐지한다.
|
|
41
|
-
|
|
42
|
-
### 분석 절차
|
|
43
|
-
|
|
44
|
-
각 함수/모듈에 대해:
|
|
45
|
-
|
|
46
|
-
1. **의도 파악** — 함수명, 변수명, 주석에서 의도를 기술
|
|
47
|
-
2. **수식·계산 검증** — 구체적 숫자를 대입하여 중간 결과 추적
|
|
48
|
-
3. **부작용 열거** — 의도상 있어야 하지만 코드에 없는 부작용 탐지
|
|
49
|
-
4. **에지케이스 시뮬레이션** — 빈 값, 경계값, 이례적 입력 추적
|
|
50
|
-
|
|
51
|
-
### 체크리스트
|
|
52
|
-
|
|
53
|
-
아래 관점별 체크리스트로 이슈를 식별한다.
|
|
54
|
-
|
|
55
|
-
#### 요구사항 대비 (SPEC) — 요구사항 원천이 제공된 경우에만
|
|
56
|
-
|
|
57
|
-
요구사항 원천이 있으면 이를 기준으로 코드와 대조한다. 원천은 형식을 가리지 않는다:
|
|
58
|
-
|
|
59
|
-
검증 항목:
|
|
60
|
-
|
|
61
|
-
- 요구사항 미구현: 원천에 명시된 동작·규칙이 실제 코드에 반영되지 않음
|
|
62
|
-
- 요구사항 위반: 원천의 규칙·결정과 다르게 구현
|
|
63
|
-
- 경계 초과(스코프 크립): 원천에 "제외"/"다루지 않음"으로 명시된 항목이 구현됨
|
|
64
|
-
- 진행 상태 불일치(체크박스·상태표가 있는 경우): 문서상 완료인데 산출물 없음 또는 그 반대
|
|
65
|
-
|
|
66
|
-
근거 태그: `[근거: 사용자 요청 "..."]`, `[근거: 이메일 {제목}]`, `[근거: wbs Feature X.Y 경계]`, `[근거: Feature X.Y Scenario "..."]`, `[근거: 설계 결정 D2]` 등 출처 형식에 맞춰 명시
|
|
67
|
-
|
|
68
|
-
#### 로직 버그 (LOGIC)
|
|
69
|
-
|
|
70
|
-
실행은 되지만 결과가 틀린 이슈:
|
|
71
|
-
|
|
72
|
-
- 의도-구현 불일치: 함수명/주석이 암시하는 동작과 실제 구현이 다른 경우 (예: 합산해야 하는데 덮어쓰기)
|
|
73
|
-
- 비즈니스 로직 오류: 잘못된 계산 순서, 잘못된 조건, 잘못된 수식 (예: 할인 후 세금 vs 세금 후 할인)
|
|
74
|
-
- 누락된 단계: 프로세스에 반드시 있어야 하는 단계가 빠짐. 함수가 하는 일의 부작용(side effect)을 나열하고, 빠진 부작용이 없는지 확인한다 (예: 주문 생성 → DB 삽입은 있지만 재고 차감/결제 처리가 없음)
|
|
75
|
-
- 상태 전이 오류: 허용되지 않아야 하는 상태 변경이 가능 (예: 배송 완료된 주문 취소 가능)
|
|
76
|
-
- 데이터 정합성: 한쪽은 업데이트하고 다른 쪽은 안 하는 부분 업데이트
|
|
77
|
-
- 에지케이스 논리 오류: 도메인 수준의 경계값 처리 누락 (예: 생일 지남 여부를 고려하지 않는 나이 계산)
|
|
78
|
-
|
|
79
|
-
#### 일관성/통일성 (CONSIST)
|
|
80
|
-
|
|
81
|
-
같은 코드베이스 내에서 같은 개념이 다른 방식으로 표현된 이슈:
|
|
82
|
-
|
|
83
|
-
- 네이밍 불일치: 같은 개념에 대해 파일/모듈마다 다른 이름 사용 (예: `userId` vs `userIdx` vs `uid`)
|
|
84
|
-
- 파라미터 순서 불일치: 유사한 함수들 간 파라미터 순서가 다름 (예: `update(id, name)` vs `update(name, id)`)
|
|
85
|
-
- 반환 구조 불일치: 같은 종류의 함수/API인데 반환 형태가 다름 (예: 어떤 건 raw 객체, 어떤 건 `{ items, total }` 래핑)
|
|
86
|
-
- 패턴 불일치: 같은 역할의 코드가 파일마다 다른 패턴으로 구현됨 (예: 에러 처리 방식, 초기화 방식이 제각각)
|
|
87
|
-
- 디렉토리/파일 구조 불일치: 같은 성격의 모듈인데 파일 배치나 구조가 다름
|
|
88
|
-
|
|
89
|
-
#### 성능 (PERF)
|
|
90
|
-
|
|
91
|
-
- O(n^2) 이상의 중첩 루프 (같은 컬렉션을 반복 순회)
|
|
92
|
-
- N+1 쿼리 패턴 (루프 내 DB/API 호출)
|
|
93
|
-
- 불필요한 직렬 await (Promise.all로 병렬화 가능한 독립 호출)
|
|
94
|
-
|
|
95
|
-
#### 설계 (DESIGN)
|
|
96
|
-
|
|
97
|
-
- 함수명/변수명과 실제 동작의 괴리 (의미론적 네이밍 문제)
|
|
98
|
-
- 한 함수가 너무 많은 책임 (단일 책임 원칙 위반)
|
|
99
|
-
- 호출 그래프 중복 실행: 명시적 호출과 간접 호출(이벤트 구독 등)을 통해 동일 로직이 여러 경로로 중복 실행되는 경우
|
|
100
|
-
- 에러 발생 가능한 호출(DB, 네트워크, JSON.parse 등)에 에러 처리 없음
|
|
101
|
-
- 에러 삼킴 (빈 catch 블록)
|
|
102
|
-
- 리소스 미해제 / 메모리 릭 패턴:
|
|
103
|
-
- 해제되지 않는 구독: Observable subscribe 후 unsubscribe/destroy 누락, addEventListener 후 removeEventListener 누락
|
|
104
|
-
- 해제되지 않는 타이머: setInterval/setTimeout을 등록하고 clear하지 않음
|
|
105
|
-
- 무한 축적 컬렉션: Map/Set/Array에 항목을 추가만 하고 제거·초기화하지 않아 무한히 커지는 패턴
|
|
106
|
-
- 스트림/커넥션 미닫힘: 파일 스트림, DB 커넥션 등 열고 닫지 않음
|
|
107
|
-
- 경계 타입 혼용: 한 타입이 내부 처리용과 외부 전달용(Worker, IPC, API 응답, 레이어 간 반환 등) 역할을 겸하여, 소비자가 쓰지 않는 필드가 노출되거나 역할이 모호해짐
|
|
108
|
-
- dead code: 선언·정의되어 있지만 실제로 사용되지 않는 코드. 사용되지 않는 파라미터/옵션 프로퍼티, 도달하지 않는 분기, 할당만 하고 이후 로직에 영향을 주지 않는 값 등 — 린터가 잡지 못하지만 존재함으로써 유지보수 부담을 높이거나 호출자에게 잘못된 기대를 심어줌
|
|
109
|
-
|
|
110
|
-
### Severity 기준
|
|
111
|
-
|
|
112
|
-
| Severity | 기준 | 예시 |
|
|
113
|
-
| ------------ | -------------------------------------- | ---------------------------------- |
|
|
114
|
-
| **Critical** | 데이터 손실/손상, 잘못된 비즈니스 결과 | 합산 대신 덮어쓰기, 상태 전이 오류 |
|
|
115
|
-
| **Medium** | 특정 조건에서 잘못된 동작, 누락된 처리 | 상태 체크 누락, 에러 처리 부재 |
|
|
116
|
-
| **Low** | 개선하면 좋지만 당장 오동작하지는 않음 | 성능 비효율, 설계 개선 제안 |
|
|
117
|
-
|
|
118
|
-
## Step 4: 거짓양성 필터링
|
|
119
|
-
|
|
120
|
-
Step 3에서 탐지된 이슈를 하나씩 순회하며, 해당 위치의 코드와 관련 컨텍스트(호출자, 프레임워크 패턴, 프로젝트 컨벤션 등)를 다시 읽고 실제로 문제가 맞는지 검증한다. 거짓양성으로 판단되면 사유와 함께 제외한다.
|
|
121
|
-
|
|
122
|
-
### 거짓양성 판단 기준
|
|
123
|
-
|
|
124
|
-
다음 중 하나에 해당하면 거짓양성으로 판단한다:
|
|
125
|
-
|
|
126
|
-
- **프레임워크/라이브러리 의도된 패턴**: 프레임워크가 권장하거나 요구하는 방식으로 작성된 코드 (예: Angular의 lifecycle hook 호출 순서, RxJS의 구독 패턴)
|
|
127
|
-
- **상위 레이어에서 이미 처리**: 이슈로 지적한 누락이 호출자·미들웨어·프레임워크 레벨에서 이미 처리되고 있는 경우
|
|
128
|
-
- **의도적 설계 결정**: 코드베이스 내 동일 패턴이 일관되게 사용되어 의도적 선택임이 확인되는 경우
|
|
129
|
-
- **실행 경로 도달 불가**: 실제 호출 흐름상 해당 조건에 도달할 수 없는 경우 (타입 시스템, 선행 검증 등으로 보장)
|
|
130
|
-
- **외부 의존성 제약**: 외부 라이브러리/API의 동작 특성상 불가피한 코드이며, 대안이 없는 경우
|
|
131
|
-
|
|
132
|
-
### 검증 절차
|
|
133
|
-
|
|
134
|
-
각 이슈에 대해:
|
|
135
|
-
|
|
136
|
-
1. 해당 코드의 **호출자(caller)** 를 추적하여 실제 사용 맥락 확인
|
|
137
|
-
2. 코드베이스 내 **동일 패턴의 다른 사례**가 있는지 검색
|
|
138
|
-
3. 위 판단 기준에 해당하는지 평가
|
|
139
|
-
4. 거짓양성이면 사유를 기록하고 제외, 아니면 이슈 유지
|
|
140
|
-
|
|
141
|
-
불확실한 경우, @.claude/rules/sd-options.md 의 지침에 따라 사용자에게 질문하여 명확화 한다.
|
|
142
|
-
|
|
143
|
-
## Step 5: 이슈 정리
|
|
144
|
-
|
|
145
|
-
Step 4를 통과한 이슈들을 최종 리포트 품질을 위해 정리한다.
|
|
146
|
-
|
|
147
|
-
### 동일 근본 원인 통합
|
|
148
|
-
|
|
149
|
-
서로 다른 위치에서 탐지되었지만 동일한 근본 원인을 공유하는 이슈들을 하나로 통합한다:
|
|
150
|
-
|
|
151
|
-
- 같은 잘못된 가정/오해에서 파생된 여러 이슈 → 근본 원인 1건으로 병합, 개별 발현 위치는 하위 목록으로 기재
|
|
152
|
-
- 같은 패턴이 여러 파일에 반복된 이슈 → 대표 사례 1건 + "동일 패턴 N건" 표기
|
|
153
|
-
|
|
154
|
-
### 중복 제거
|
|
155
|
-
|
|
156
|
-
- 동일 위치·동일 내용의 이슈가 다른 카테고리로 중복 탐지된 경우, 가장 적합한 카테고리 1건만 유지
|
|
157
|
-
- 상위 이슈가 하위 이슈를 포함하는 경우(예: 설계 이슈가 해결되면 로직 이슈도 해소), 상위 이슈만 유지
|
|
158
|
-
|
|
159
|
-
### Severity 재조정
|
|
160
|
-
|
|
161
|
-
전체 이슈 목록이 확정된 시점에서 severity를 재평가한다:
|
|
162
|
-
|
|
163
|
-
- 통합으로 영향 범위가 넓어진 이슈 → severity 상향 검토
|
|
164
|
-
- 단독으로 보면 Medium이지만 다른 이슈와 결합 시 Critical이 되는 경우 → 상향
|
|
165
|
-
- 초기 분석 시 과대평가된 이슈 → 하향
|
|
166
|
-
|
|
167
|
-
### 우선순위 정렬
|
|
168
|
-
|
|
169
|
-
최종 이슈 목록을 다음 기준으로 정렬한다:
|
|
170
|
-
|
|
171
|
-
1. Severity (Critical → Medium → Low)
|
|
172
|
-
2. 동일 severity 내에서는 영향 범위가 넓은 순
|
|
173
|
-
3. 동일 영향 범위 내에서는 카테고리 순 (LOGIC → CONSIST → PERF → DESIGN)
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# 리뷰 대상 소스 파일을 하나의 텍스트 파일로 병합
|
|
3
|
-
# Usage:
|
|
4
|
-
# merge-source.sh <출력파일> --dir <디렉토리경로>
|
|
5
|
-
# merge-source.sh <출력파일> --files <파일1> <파일2> ...
|
|
6
|
-
|
|
7
|
-
output="$1"
|
|
8
|
-
shift
|
|
9
|
-
|
|
10
|
-
if [ -z "$output" ]; then
|
|
11
|
-
echo "Usage: $0 <output-file> --dir <dir-path> | --files <file1> <file2> ..." >&2
|
|
12
|
-
exit 1
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
mkdir -p "$(dirname "$output")"
|
|
16
|
-
|
|
17
|
-
mode="$1"
|
|
18
|
-
shift
|
|
19
|
-
|
|
20
|
-
files=""
|
|
21
|
-
if [ "$mode" = "--dir" ]; then
|
|
22
|
-
dir_path="$1"
|
|
23
|
-
if [ -z "$dir_path" ]; then
|
|
24
|
-
echo "Error: --dir requires a directory path" >&2
|
|
25
|
-
exit 1
|
|
26
|
-
fi
|
|
27
|
-
files=$(find "$dir_path/src" -name "*.ts" 2>/dev/null | sort)
|
|
28
|
-
[ -d "$dir_path/scss" ] && files+=$'\n'$(find "$dir_path/scss" -name "*.scss" 2>/dev/null | sort)
|
|
29
|
-
elif [ "$mode" = "--files" ]; then
|
|
30
|
-
files=$(printf '%s\n' "$@")
|
|
31
|
-
else
|
|
32
|
-
echo "Error: specify --dir or --files" >&2
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
echo "$files" | while IFS= read -r f; do
|
|
37
|
-
[ -z "$f" ] && continue
|
|
38
|
-
echo "=== $f ==="
|
|
39
|
-
cat "$f"
|
|
40
|
-
echo
|
|
41
|
-
done > "$output"
|