@simplysm/sd-claude 14.0.56 → 14.0.58
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/angular/ui-data/sd-crud-list.md +99 -1
- package/claude/references/sd-simplysm-v14/angular/ui-data/sd-sheet.md +27 -0
- package/claude/references/sd-simplysm-v14/angular/ui-form/sd-select.md +20 -0
- package/claude/references/sd-simplysm-v14/sd-claude/assets.md +3 -5
- package/claude/rules/sd-claude-rules.md +31 -2
- package/claude/rules/sd-options.md +19 -22
- package/claude/rules/sd-response-format.md +36 -0
- package/claude/skills/sd-check/SKILL.md +30 -3
- package/claude/skills/sd-clarify/SKILL.md +94 -0
- 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-commit/SKILL.md +3 -11
- 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-dev/SKILL.md +18 -73
- package/claude/skills/sd-plan/SKILL.md +156 -40
- package/claude/skills/sd-prompt/SKILL.md +68 -25
- package/claude/skills/sd-prompt/references/eval-runner.md +2 -2
- package/claude/skills/sd-refactor/SKILL.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 +3 -4
- package/claude/skills/sd-use/SKILL.md +5 -8
- package/claude/skills/sd-wbs/SKILL.md +163 -31
- 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-clarify/SKILL.md +0 -78
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-claude-docs
|
|
3
3
|
description: 프로젝트 분석을 통해 CLAUDE.md(개발자용)와 README.md/docs(소비자용) 문서를 동시 생성하는 스킬. "init", "CLAUDE.md 생성", "README 생성", "LLM 문서 만들어줘", "패키지 문서 생성" 등을 요청할 때 사용한다.
|
|
4
|
-
|
|
4
|
+
model: haiku
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# sd-claude-docs: CLAUDE.md + README.md/docs 통합 생성
|
|
@@ -95,7 +95,7 @@ version: "14.0.51" → 메이저 버전: 14 → {문서 루트}: .claude/referen
|
|
|
95
95
|
|
|
96
96
|
### 1-4. `.claude/rules/` 스캔
|
|
97
97
|
|
|
98
|
-
디렉토리가 존재하면
|
|
98
|
+
디렉토리가 존재하면 `.claude/rules/*.md`에 매칭되는 룰 본문 파일을 읽어 이미 다루고 있는 주제를 목록화한다. 단, `*.eval.md` 파일은 룰의 Eval 시나리오이므로 제외한다. 해당 주제의 상세 규칙 본문은 **CLAUDE.md에서 제외**한다 — 파일 간 규칙 중복은 LLM이 고유 지침 대신 중복 컨텍스트를 처리하게 되어 지침의 효과를 약화시킨다.
|
|
99
99
|
|
|
100
100
|
### 1-5. 프로젝트 유형 감지
|
|
101
101
|
|
|
@@ -124,7 +124,7 @@ subagent가 개별 파일을 하나씩 Read하는 대신 병합 파일 1회 Read
|
|
|
124
124
|
|
|
125
125
|
```bash
|
|
126
126
|
TS=$(date +%y%m%d%H%M%S)
|
|
127
|
-
|
|
127
|
+
python .claude/skills/sd-claude-docs/merge-source.py {패키지경로} ./.tmp/docs/$TS/{패키지명}-source.txt
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### 3-2. subagent 병렬 실행
|
|
@@ -164,18 +164,37 @@ Step 2의 "Step 4 수행" 열이 "수행"인 경우에만 진행한다.
|
|
|
164
164
|
|
|
165
165
|
### 4-1. 콘텐츠 구성
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
루트 CLAUDE.md는 Claude가 이 저장소에서 작업하기 전에 읽고 따르는 **작업 지침서**로 작성한다. 프로젝트 소개서, 기술 스택 요약서, 아키텍처 설명서처럼 작성하지 않는다.
|
|
168
|
+
|
|
169
|
+
Step 1 결과와 Step 3의 각 패키지 CLAUDE.md를 조합하여 루트 CLAUDE.md를 생성한다. `.claude/rules/`에서 이미 다루는 주제(1-4에서 감지)의 상세 규칙 본문은 **제외**한다. 패키지 CLAUDE.md에 기술된 상세(패키지 내부 구조, 패턴, API 사용법 등)는 루트에 중복하지 않는다. 루트에는 작업자가 어느 패키지와 어떤 문서를 먼저 봐야 하는지 판단할 수 있는 수준의 라우팅 정보만 둔다.
|
|
170
|
+
|
|
171
|
+
#### 작성 원칙
|
|
172
|
+
|
|
173
|
+
- **작업자가 바로 행동할 수 있게 작성한다**: "무엇을 읽고 → 어디를 수정하고 → 어떤 명령으로 검증하는가"를 중심으로 쓴다.
|
|
174
|
+
- **설명보다 지침을 우선한다**: 기술 스택·아키텍처·패키지 역할은 작업 판단에 필요한 만큼만 짧게 쓴다.
|
|
175
|
+
- **중복을 피한다**: `.claude/rules/*.md`, 패키지 CLAUDE.md, 소비자 README/docs에 이미 있는 상세 내용은 링크하거나 한 줄로 라우팅한다.
|
|
176
|
+
- **금지와 대안을 함께 쓴다**: 금지 명령어·금지 API·금지 패턴을 쓰는 경우 허용되는 명령어·API·패턴을 같은 항목에 적는다.
|
|
177
|
+
- **명령어는 실제 스크립트 기준으로 쓴다**: 일반적인 `npm run script -- --flag` 습관을 추측으로 적용하지 않는다. `package.json` 스크립트가 `pnpm sd-cli <command>`처럼 커스텀 CLI를 감싸면 `--target` 같은 옵션은 중간 `--` 없이 작성한다.
|
|
168
178
|
|
|
169
179
|
#### 포함할 섹션
|
|
170
180
|
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
- **명령어**: 1-2의 스크립트를
|
|
175
|
-
-
|
|
176
|
-
-
|
|
181
|
+
- **작업 언어**: 사용자 응답 언어, 저장소 문서 언어, 공개 소비자 문서 작성 관점
|
|
182
|
+
- **저장소 구조와 수정 경계**: 워크스페이스 경로, 루트/패키지/테스트/문서 산출물의 책임 경계
|
|
183
|
+
- **패키지 라우팅**: 사용자 요청 유형별로 먼저 볼 패키지·테스트·문서 경로를 표로 정리
|
|
184
|
+
- **명령어**: 1-2의 스크립트를 작업 유형별 bash 코드 블록으로 포매팅, 각 명령을 언제 쓰는지 인라인 주석 추가
|
|
185
|
+
- **코딩 규칙**: 1-3에서 선별한 규칙 중 작업 중 실수하기 쉬운 전역 금지·필수 규칙을 불릿 리스트로 포매팅
|
|
186
|
+
- **테스트와 검증 기준**: 변경 유형별 최소 검증 명령, 통합 테스트 전제 조건, 실행하지 못한 경우 보고 기준
|
|
187
|
+
- **주의할 변경사항**: lockfile, 생성물, 공개 API, 설정 파일처럼 파급이 큰 파일을 언제 함께 갱신해야 하는지 기술
|
|
188
|
+
|
|
189
|
+
실질적 내용이 없는 섹션은 생략한다. 필요 시 위 외 섹션도 추가한다 (예: 네이티브 앱 실행, 브라우저 검증).
|
|
190
|
+
|
|
191
|
+
#### 제외할 내용
|
|
177
192
|
|
|
178
|
-
|
|
193
|
+
- 프로젝트 홍보 문구, 긴 개요, 기술 스택 나열만을 위한 섹션
|
|
194
|
+
- 패키지 내부 디렉토리별 상세 설명 — 패키지 CLAUDE.md에 둔다
|
|
195
|
+
- 공개 API 사용법, 예제, anti-pattern — 소비자 README/docs에 둔다
|
|
196
|
+
- `.claude/rules/*.md`에 이미 있는 상세 규칙 본문
|
|
197
|
+
- 작업 판단에 쓰이지 않는 의존 관계 다이어그램
|
|
179
198
|
|
|
180
199
|
### 4-2. 병합
|
|
181
200
|
|
|
@@ -188,38 +207,52 @@ Step 1 결과와 Step 3의 각 패키지 CLAUDE.md를 조합하여 루트 CLAUDE
|
|
|
188
207
|
````markdown
|
|
189
208
|
# Simplysm
|
|
190
209
|
|
|
191
|
-
pnpm 모노레포.
|
|
210
|
+
pnpm 기반 TypeScript ESM 모노레포. 이 파일은 Claude가 작업 전에 읽는 저장소 작업 지침이다.
|
|
192
211
|
|
|
193
|
-
##
|
|
212
|
+
## 작업 언어
|
|
194
213
|
|
|
195
|
-
|
|
214
|
+
- 사용자 안내와 작업 요약은 한국어로 작성한다.
|
|
215
|
+
- 공개 소비자 문서는 패키지를 사용하는 LLM이 바로 코드를 작성할 수 있는 작업 라우터 형태로 작성한다.
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
pnpm dev [targets..] # 서버 패키지를 개발 모드로 실행
|
|
199
|
-
pnpm watch [targets..] # 라이브러리 패키지를 watch 빌드
|
|
200
|
-
```
|
|
217
|
+
## 저장소 구조와 수정 경계
|
|
201
218
|
|
|
202
|
-
|
|
219
|
+
- 워크스페이스는 `packages/*`, `tests/*`이다.
|
|
220
|
+
- 공개 패키지 코드를 수정하면 해당 패키지의 소비자 문서도 함께 확인한다.
|
|
221
|
+
- 루트 설정, lockfile, 생성물은 관련 변경이 있을 때만 수정한다.
|
|
203
222
|
|
|
204
|
-
|
|
205
|
-
pnpm check [targets..] # 전체 검사
|
|
206
|
-
pnpm typecheck [targets..] # TypeScript 타입 체크
|
|
207
|
-
```
|
|
223
|
+
## 패키지 라우팅
|
|
208
224
|
|
|
209
|
-
|
|
225
|
+
| 요청 유형 | 먼저 볼 위치 | 함께 확인할 위치 |
|
|
226
|
+
|-----------|--------------|------------------|
|
|
227
|
+
| Angular UI | `packages/angular` | `{문서 루트}/angular/README.md` |
|
|
228
|
+
| 서비스 서버 | `packages/service-server` | `tests/service` |
|
|
229
|
+
| ORM | `packages/orm-common`, `packages/orm-node` | `tests/orm` |
|
|
210
230
|
|
|
211
|
-
|
|
231
|
+
## 명령어
|
|
212
232
|
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
233
|
+
```bash
|
|
234
|
+
pnpm check [--target <pkg>] # 패키지 변경 후 타입체크와 lint 실행
|
|
235
|
+
pnpm typecheck [--target <pkg>] # 타입 오류만 확인
|
|
236
|
+
pnpm lint [--target <pkg>] # lint 오류만 확인
|
|
237
|
+
vitest run <path> # 변경 범위에 맞는 테스트 실행
|
|
217
238
|
```
|
|
218
239
|
|
|
219
240
|
## 코딩 규칙
|
|
220
241
|
|
|
221
242
|
- `import type` 필수 (`verbatimModuleSyntax`), `#private` 금지 → `private` 키워드 사용
|
|
222
243
|
- `console.*` 금지, `Buffer` 금지 → `Uint8Array`
|
|
244
|
+
|
|
245
|
+
## 테스트와 검증 기준
|
|
246
|
+
|
|
247
|
+
- 타입·lint 영향이 있는 변경은 `pnpm check [--target <pkg>]`로 검증한다.
|
|
248
|
+
- 런타임 로직 변경은 관련 `vitest run <path>`를 함께 실행한다.
|
|
249
|
+
- 실행하지 못한 검증은 최종 응답에 이유와 남은 위험을 적는다.
|
|
250
|
+
|
|
251
|
+
## 주의할 변경사항
|
|
252
|
+
|
|
253
|
+
- 공개 API를 바꾸면 소비자 문서와 API 인덱스를 함께 갱신한다.
|
|
254
|
+
- 의존성 변경이 있을 때만 lockfile을 갱신한다.
|
|
255
|
+
- 생성물은 생성 명령을 실행한 경우에만 갱신한다.
|
|
223
256
|
````
|
|
224
257
|
|
|
225
258
|
## Step 5: 결과 보고
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def collect_source_files(package_path: Path) -> list[Path]:
|
|
9
|
+
files: list[Path] = []
|
|
10
|
+
|
|
11
|
+
src_dir = package_path / "src"
|
|
12
|
+
if src_dir.is_dir():
|
|
13
|
+
files.extend(path for path in src_dir.rglob("*.ts") if path.is_file())
|
|
14
|
+
|
|
15
|
+
scss_dir = package_path / "scss"
|
|
16
|
+
if scss_dir.is_dir():
|
|
17
|
+
files.extend(path for path in scss_dir.rglob("*.scss") if path.is_file())
|
|
18
|
+
|
|
19
|
+
return sorted(files, key=lambda path: path.as_posix())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def write_merged_source(files: list[Path], output_path: Path) -> None:
|
|
23
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
|
|
25
|
+
with output_path.open("w", encoding="utf-8", newline="\n") as output:
|
|
26
|
+
for file_path in files:
|
|
27
|
+
output.write(f"=== {file_path.as_posix()} ===\n")
|
|
28
|
+
text = file_path.read_text(encoding="utf-8")
|
|
29
|
+
output.write(text)
|
|
30
|
+
if not text.endswith("\n"):
|
|
31
|
+
output.write("\n")
|
|
32
|
+
output.write("\n")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main(argv: list[str]) -> int:
|
|
36
|
+
if len(argv) != 3:
|
|
37
|
+
print("Usage: merge-source.py <package-path> <output-file>", file=sys.stderr)
|
|
38
|
+
return 1
|
|
39
|
+
|
|
40
|
+
package_path = Path(argv[1])
|
|
41
|
+
output_path = Path(argv[2])
|
|
42
|
+
write_merged_source(collect_source_files(package_path), output_path)
|
|
43
|
+
return 0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
raise SystemExit(main(sys.argv))
|
|
@@ -9,20 +9,12 @@ model: haiku
|
|
|
9
9
|
## 프로세스
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
Step 1: 스테이징
|
|
12
|
+
Step 1: 스테이징 → Step 2: Diff 분석 → Step 3: 메시지 작성 → Step 4: 커밋
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
## Step 1: 스테이징
|
|
15
|
+
## Step 1: 스테이징
|
|
16
16
|
|
|
17
|
-
모든
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
mkdir -p .tmp && git add -A && git diff --staged > ".tmp/$(date +%y%m%d%H%M%S)_commit.txt"
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
파일이 비어있으면 스테이징된 변경사항이 없는 것이다. 사용자에게 알리고 중단한다.
|
|
24
|
-
|
|
25
|
-
생성된 파일을 Read하여 전체 변경 내역을 확인한다.
|
|
17
|
+
`git add -A`로 모든 변경을 스테이징한다 (sd-commit은 전체 단일 커밋 정책이므로 "관련 파일만 add" 권고를 의도적으로 오버라이드).
|
|
26
18
|
|
|
27
19
|
## Step 2: Diff 분석
|
|
28
20
|
|
|
@@ -1,56 +1,347 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-debug
|
|
3
|
-
description: 버그·동작 이상의 근본
|
|
3
|
+
description: 버그·동작 이상의 근본 원인을 RCA(Root Cause Analysis) 기법과 ACH(Analysis of Competing Hypotheses)로 분석하여 보고하는 스킬. "디버그", "에러 분석", "버그 원인 찾아줘", "왜 이렇게 동작해?", "왜 안 돼?" 등을 요청할 때 사용한다. 분석과 보고만 수행하고 코드 수정·후속 스킬 호출은 하지 않는다. 단순 코드 리뷰는 sd-review를, 기능 추가/수정은 sd-dev를 사용한다.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# sd-debug: 근본 원인 분석
|
|
6
|
+
# sd-debug: 근본 원인 분석 및 보고
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
버그·동작 이상을 RCA 기법(Fishbone → 5 Whys → FTA)과 ACH 매트릭스로 분석하여 근본 원인과 해결책을 보고한 뒤 즉시 종료한다.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
분석 파이프라인:
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
```
|
|
13
|
+
Phase 0: 진입 가드
|
|
14
|
+
↓
|
|
15
|
+
Phase 1: 증거 수집
|
|
16
|
+
↓
|
|
17
|
+
Phase 2: 재현 & 최소화 [Delta Debugging]
|
|
18
|
+
↓
|
|
19
|
+
Phase 3: Fishbone 분기 [RCA — 가설 발산, ≥3개]
|
|
20
|
+
↓
|
|
21
|
+
Phase 4: ACH 매트릭스 [가설 × 증거 평가, 수렴]
|
|
22
|
+
↓
|
|
23
|
+
Phase 5: 분기형 5 Whys [RCA — 인과 종축 추적]
|
|
24
|
+
↓
|
|
25
|
+
Phase 6: Fault Tree (조건부) [RCA — 복합 인과]
|
|
26
|
+
↓
|
|
27
|
+
Phase 7: 보고 & 종료
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 분석 원칙
|
|
31
|
+
|
|
32
|
+
- **근본 원인 제거**: 증상을 숨기는 해결이 아닌, 원인 자체를 제거하는 방향으로 분석한다. 반드시 "왜 이 문제가 발생하는가?"를 근원까지 추적한다.
|
|
33
|
+
- **추측 금지**: "~일 수 있다", "~가능성이 높다"로 원인을 단정하지 않는다. 코드를 읽고, 로그를 확인하고, 재현하여 증거 기반으로 원인을 특정한다.
|
|
34
|
+
- **외부 탓 금지**: 라이브러리/런타임 버그를 원인으로 지목하기 전에, 내 코드가 해당 API를 올바르게 사용하고 있는지 먼저 검증한다. 공식 문서·소스코드·이슈 트래커에서 동일 보고가 없으면 내 코드 문제로 간주한다.
|
|
35
|
+
- **반증 우선 (Falsification First)**: 가설을 입증하려 하지 말고, 매 단계 "어떻게 하면 이 가설이 *틀릴 수 있는가*"를 먼저 묻는다.
|
|
36
|
+
- **One variable at a time**: 검증 시 한 번에 한 변수만 변경한다. 동시 변경은 인과 식별을 깬다.
|
|
37
|
+
- **분석·보고에서 종료**: 분석과 보고만 수행한다. 코드 수정이나 후속 스킬 호출을 하지 않는다. 후속 작업은 사용자 지시를 받은 뒤에만 시작한다.
|
|
38
|
+
|
|
39
|
+
### 편법/우회방법 금지 목록
|
|
40
|
+
|
|
41
|
+
해결책으로 다음을 제안하는 것을 금지한다.
|
|
42
|
+
|
|
43
|
+
| 편법(예시) | 문제 |
|
|
44
|
+
| -------------------------------------------- | ---------------------------------------------------------- |
|
|
45
|
+
| `setTimeout` / `requestAnimationFrame` | 타이밍 문제를 회피할 뿐 해결하지 않는다 |
|
|
46
|
+
| `try-catch`로 에러 무시 | 런타임 문제를 숨긴다 |
|
|
47
|
+
| `as any` / `any` 타입 | 타입 안전성을 포기한다 |
|
|
48
|
+
| `@ts-ignore` / `@ts-expect-error` | 타입 에러를 숨길 뿐 해결하지 않는다 |
|
|
49
|
+
| `// eslint-disable` / `/* eslint-disable */` | 린트 규칙을 무력화한다 |
|
|
50
|
+
| 플래그 변수 (`isReady`, `isLoaded`) | 조건을 우회한다 |
|
|
51
|
+
| `?.` 옵셔널 체이닝으로 undefined 무시 | 값이 undefined/null인 원인을 추적하지 않고 `?.`로 무시한다 |
|
|
52
|
+
| `.skip` / 테스트 삭제 | 테스트 커버리지를 줄인다 |
|
|
53
|
+
|
|
54
|
+
### 증거 등급
|
|
55
|
+
|
|
56
|
+
증거를 가설에 매핑할 때 다음 등급으로 표기한다.
|
|
57
|
+
|
|
58
|
+
- **C(code)**: 코드에서 직접 관찰 (변수값, 호출 체인, 설정 파일, 타입 정의 등)
|
|
59
|
+
- **C(doc)**: 공식 문서, GitHub 이슈, changelog, 라이브러리 소스 코드에서 확인
|
|
60
|
+
- **C(infer)**: 직접 확인 불가, 추론에 기반 — 이 등급만으로는 가설을 확정할 수 없다
|
|
61
|
+
- **I**: 증거가 가설과 불일치 — 코드에서 직접 관찰 가능한 모순이 있을 때만 표시. 추론에 의한 I 표시 금지
|
|
62
|
+
- **N**: 증거가 가설과 무관
|
|
63
|
+
|
|
64
|
+
외부 라이브러리/프레임워크 동작에 대한 가설(예: "X 라이브러리가 Y를 인식하지 못한다")은 반드시 다음 중 하나로 뒷받침해야 `C(doc)` 이상이 된다.
|
|
65
|
+
|
|
66
|
+
- GitHub 이슈 (`gh search issues` 또는 `WebSearch`로 검색)
|
|
67
|
+
- 공식 문서/changelog
|
|
68
|
+
- 라이브러리 소스 코드에서 해당 동작을 직접 확인
|
|
69
|
+
|
|
70
|
+
뒷받침 없이 "그럴 것이다"라고 추정하면 `C(infer)`이며, 이것만으로는 가설을 확정할 수 없다.
|
|
71
|
+
|
|
72
|
+
### 인지편향 가드
|
|
73
|
+
|
|
74
|
+
LLM 디버깅의 주요 실패 모드와 차단 룰.
|
|
75
|
+
|
|
76
|
+
- **Anchor bias** — 첫 가설에 매달리는 편향: Phase 3에서 가설 ≥3개 강제로 차단
|
|
77
|
+
- **Confirmation bias** — 가설 부합 증거만 수집하는 편향: Phase 4의 가설 × 증거 매트릭스로 모든 증거를 모든 가설에 평가하여 차단
|
|
78
|
+
- **단일 인과사슬 함정** — "왜?"가 한 줄로 좁아지는 편향: Phase 5에서 매 단계 ≥2 분기 강제로 차단
|
|
79
|
+
- **Falsification 누락** — 가설 입증만 하는 편향: 모든 검증 실험 전에 "이 가설을 어떻게 깨뜨릴 수 있는가" 먼저 명시
|
|
80
|
+
|
|
81
|
+
## Phase 0: 진입 가드
|
|
82
|
+
|
|
83
|
+
입력에서 의도를 분리한다.
|
|
84
|
+
|
|
85
|
+
- "디버그", "왜 이래?", "원인 찾아줘", "에러 분석" → 분석 모드
|
|
86
|
+
- "고쳐줘", "수정해줘", "바꿔줘" → 분석 모드 + 후속 수정 핸드오프 의사. 단, 본 스킬은 분석/보고에서 종료하며, 수정은 사용자가 별도 지시 후 `/sd-dev` 등을 호출해야 한다.
|
|
87
|
+
|
|
88
|
+
분석 모드에서는 어떤 코드 수정도 하지 않는다. 진단용 print/assert 삽입도 직접 수행하지 않으며, 필요시 Phase 4의 검증 실험으로만 *지시* 한다.
|
|
89
|
+
|
|
90
|
+
## Phase 1: 증거 수집
|
|
91
|
+
|
|
92
|
+
### 1-1. GitHub 이슈 입력
|
|
93
|
+
|
|
94
|
+
입력이 GitHub 이슈 참조(`owner/repo#N` 또는 `#N`)인 경우, `gh issue view`로 이슈 내용을 조회하여 아래 항목을 추출한다. `#N`만 입력된 경우 현재 리포의 이슈로 간주한다.
|
|
95
|
+
|
|
96
|
+
### 1-2. 추출 항목
|
|
97
|
+
|
|
98
|
+
사용자 입력(또는 조회된 이슈)에서 다음을 추출한다.
|
|
99
|
+
|
|
100
|
+
- **증상** — 해당하는 유형으로 기록
|
|
101
|
+
- 에러 유형: 에러 메시지 원문 인용
|
|
102
|
+
- 동작 이상 유형: 기대 동작과 실제 동작을 각각 명시
|
|
103
|
+
- **위치** — 에러 발생 `파일:라인` 또는 관련 기능/화면
|
|
104
|
+
- **재현 절차** — 문제가 발생하는 구체적 조작 순서
|
|
105
|
+
- **환경** — OS, 런타임 버전, 입력 데이터, 시점 (간헐 발생 여부)
|
|
106
|
+
- **최근 변경** — 언제부터 발생했는지, 관련 커밋
|
|
107
|
+
- **출처** — GitHub 이슈에서 시작된 경우 `owner/repo#N` 형식. 그 외에는 `direct`
|
|
108
|
+
|
|
109
|
+
누락 항목이 있으면 `/sd-clarify` 스킬을 호출하여 명확화한다.
|
|
110
|
+
|
|
111
|
+
## Phase 2: 재현 & 최소화
|
|
112
|
+
|
|
113
|
+
### 2-1. 재현 가능성 분류
|
|
114
|
+
|
|
115
|
+
먼저 이 버그가 LLM 환경에서 직접 재현 가능한지 분류한다. 분류 결과에 따라 2-2~2-4 중 적용 분기가 결정된다.
|
|
116
|
+
|
|
117
|
+
| 레벨 | 정의 | 예시 |
|
|
118
|
+
| ---- | -------------------------- | ------------------------------------------------------------- |
|
|
119
|
+
| L1 | LLM 직접 재현 가능 | 단위·통합 테스트 실패, dev 서버 실행 시 에러, 코드/입력만으로 재현 |
|
|
120
|
+
| L2 | 사용자 환경 의존 | 특정 OS/브라우저 버전, 사용자 설정·데이터, 특정 시점 |
|
|
121
|
+
| L3 | 하드웨어 의존 | 디바이스, USB/시리얼/카메라/GPS, Capacitor 플러그인 |
|
|
122
|
+
| L4 | 간헐 발생 | race condition, 메모리 압력, 타이밍 |
|
|
123
|
+
| L5 | 프로덕션 데이터 의존 | 실제 DB 상태, 외부 API 응답 시점, 사용자별 데이터 |
|
|
124
|
+
|
|
125
|
+
분류가 모호하면 사용자에게 단일 질문으로 확인한다. 한 버그가 복수 레벨에 해당할 수 있다 (예: L3 + L4).
|
|
126
|
+
|
|
127
|
+
### 2-2. L1 처리 — 직접 재현 + Delta Debugging
|
|
128
|
+
|
|
129
|
+
L1 케이스에서는 수집된 재현 절차를 도구로 직접 실행하여 증상을 재현한다. 재현하지 않고 가설 단계로 넘어가는 것은 금지한다.
|
|
130
|
+
|
|
131
|
+
- 코드 실행 (`pnpm test`, `pnpm dev` 등)
|
|
132
|
+
- 입력 데이터 주입
|
|
133
|
+
- 환경/설정 적용
|
|
134
|
+
|
|
135
|
+
재현 성공 시 Delta Debugging 알고리즘으로 1-minimal 케이스까지 축소한다.
|
|
136
|
+
|
|
137
|
+
1. 실패하는 입력/변경 집합 D를 절반으로 분할 (D1, D2)
|
|
138
|
+
2. D1, D2 각각으로 테스트
|
|
139
|
+
- 한쪽에서 실패 재현되면 그쪽으로 좁히기
|
|
140
|
+
- 양쪽 모두 실패 안 하면 더 작게 쪼개기
|
|
141
|
+
3. 한 글자/한 줄도 빼지 못하는 minimal까지 반복
|
|
142
|
+
|
|
143
|
+
적용 대상:
|
|
144
|
+
|
|
145
|
+
- 입력 데이터 — 어떤 레코드가 깨뜨리는가
|
|
146
|
+
- 코드 변경 — `git bisect`로 어떤 커밋이 도입했는가
|
|
147
|
+
- 파일/함수 — 어떤 호출이 원인인가
|
|
148
|
+
|
|
149
|
+
상세 알고리즘은 `references/repro-minimize.md` 참조.
|
|
150
|
+
|
|
151
|
+
### 2-3. L2~L5 처리 — 사용자 협업 정보 수집
|
|
152
|
+
|
|
153
|
+
LLM이 직접 재현할 수 없는 케이스에서는 사용자에게 정보 수집을 요청한다. 레벨별 필수 수집 항목:
|
|
154
|
+
|
|
155
|
+
| 레벨 | 수집 항목 |
|
|
156
|
+
| ---- | -------------------------------------------------------------------------------------------------- |
|
|
157
|
+
| L2 | 정확한 재현 절차, 콘솔 로그, 네트워크 캡처 (HAR), 스크린샷/영상, 환경 정보 (OS·브라우저·버전·로케일) |
|
|
158
|
+
| L3 | 디바이스 로그 (`adb logcat` / Xcode console / 시리얼 dump), 디바이스 모델·OS 버전, 주변기기 사양·연결 상태 |
|
|
159
|
+
| L4 | 재현 빈도 (N/M회), 발생 시점 패턴, 발생 직전 상태·조작, 동시성 조건 (동시 사용자 수, 부하) |
|
|
160
|
+
| L5 | 익명화된 요청/응답 페이로드, DB 스키마 + 샘플 row, 발생 시점의 외부 API 응답·시각 |
|
|
161
|
+
|
|
162
|
+
요청은 단일 질문으로 묶어 사용자 부담을 줄인다. 수집된 정보를 Phase 4의 ACH 매트릭스 증거로 등록한다. 상세는 `references/repro-collab.md` 참조.
|
|
163
|
+
|
|
164
|
+
### 2-4. 재현 불가 모드의 가설 검증
|
|
165
|
+
|
|
166
|
+
L2~L5에서 사용자 정보를 받아도 LLM이 직접 실행으로 검증할 수 없는 부분이 남는다. 이 모드에서는:
|
|
167
|
+
|
|
168
|
+
- **트레이스 시뮬레이션**: 코드 트레이스·로직 분석·타입 체크로 가설을 좁힌다 (실행 없이)
|
|
169
|
+
- **C(infer) 인정**: Phase 4 ACH 매트릭스에서 C(infer) 비중이 자연스럽게 높아짐. 매트릭스 갱신 단계마다 *추가 사용자 데이터 요청* 을 트리거하여 C(infer)를 C(code)/C(doc)으로 승격시키도록 노력한다
|
|
170
|
+
- **단정 금지**: 단정적 결론을 피하고, 살아남은 가설이 복수면 모두 보고한다
|
|
171
|
+
- **재현 한계 명시**: Phase 7 보고에서 "직접 재현 못 한 부분"을 분석 한계 섹션에 분리해 적는다
|
|
13
172
|
|
|
14
|
-
##
|
|
173
|
+
## Phase 3: Fishbone 분기 — 가설 발산
|
|
15
174
|
|
|
16
|
-
|
|
175
|
+
### 3-1. 6축 카테고리
|
|
17
176
|
|
|
18
|
-
|
|
177
|
+
수집된 증거로부터 다음 6축에 대해 각각 가설을 1개 이상 생성한다. 전체 가설 수는 **3개 이상**이어야 한다.
|
|
19
178
|
|
|
20
|
-
|
|
179
|
+
| 축 | 예시 |
|
|
180
|
+
|-----------------|------|
|
|
181
|
+
| 코드 | 로직 오류, 타입 불일치, 순서/조건 오류 |
|
|
182
|
+
| 입력·데이터 | 예상 못 한 값, NULL/빈 값, 인코딩, 경계값 |
|
|
183
|
+
| 환경·설정 | 환경변수, 설정 파일, 의존성 버전, 빌드 타겟 |
|
|
184
|
+
| 타이밍·동시성 | race condition, async 순서, 트랜잭션 격리 |
|
|
185
|
+
| 외부 의존 | 라이브러리 버그/변경, API 응답 변경, DB 스키마 변경 |
|
|
186
|
+
| 상태 관리 | 캐시/메모리 상태, 잘못된 초기화, 잔존 상태 |
|
|
21
187
|
|
|
22
|
-
|
|
23
|
-
- `{topic}` — 에러/이슈의 핵심을 나타내는 간결한 키워드 (예: `null-ref`, `race-condition`, `async-init`)
|
|
188
|
+
상세 가이드는 `references/fishbone-categories.md` 참조.
|
|
24
189
|
|
|
25
|
-
###
|
|
190
|
+
### 3-2. 가설 형식
|
|
26
191
|
|
|
27
|
-
|
|
28
|
-
# 디버그: {문제 한 줄 요약}
|
|
192
|
+
각 가설은 다음 형식으로 명시한다.
|
|
29
193
|
|
|
30
|
-
|
|
194
|
+
- **가설 ID**: H1, H2, ...
|
|
195
|
+
- **카테고리**: 6축 중 하나
|
|
196
|
+
- **주장**: "X가 Y이다" 또는 "X가 Y하기 때문에 Z가 발생한다"
|
|
197
|
+
- **검증 가능성**: 어떤 실험으로 입증/반증할 수 있는가
|
|
31
198
|
|
|
32
|
-
|
|
33
|
-
- **완료 시 참고:** GitHub 이슈인 경우, 수정 완료 후 해당 이슈의 close 및 comment가 필요할 수 있다.
|
|
199
|
+
가설은 사용자에게 출력하지 않고 내부 작업으로 유지한다 (Phase 7 보고에서는 살아남은 원인만 노출).
|
|
34
200
|
|
|
35
|
-
##
|
|
201
|
+
## Phase 4: ACH 매트릭스 — 가설 평가
|
|
36
202
|
|
|
37
|
-
-
|
|
38
|
-
- **증상:** `{에러 메시지 원문}` 또는 기대: {기대 동작} / 실제: {실제 동작}
|
|
39
|
-
- **위치:** `{file_path:line_number}` 또는 {관련 기능/화면}
|
|
40
|
-
- **재현 절차:** {조작 순서}
|
|
203
|
+
### 4-1. 매트릭스 초기화
|
|
41
204
|
|
|
42
|
-
|
|
205
|
+
가설(열) × 증거(행) 매트릭스를 구성한다. 현재까지 수집된 증거(에러 메시지, 재현 조건, 코드 분석 결과)를 초기 증거로 등록한다.
|
|
43
206
|
|
|
44
|
-
|
|
207
|
+
```
|
|
208
|
+
| H1 | H2 | H3 | ...
|
|
209
|
+
--------------|----------|----------|----------|
|
|
210
|
+
증거 E1 | C(code) | I | N |
|
|
211
|
+
증거 E2 | I | C(doc) | C(infer) |
|
|
212
|
+
증거 E3 | C(code) | C(code) | I |
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 4-2. 판별 실험 → 매트릭스 갱신
|
|
216
|
+
|
|
217
|
+
가설을 가장 많이 구분할 수 있는 검증 도구를 선택하여 실험한다.
|
|
218
|
+
|
|
219
|
+
| 검증 도구 | 적용 조건 |
|
|
220
|
+
| ------------------ | -------------------------------------------------- |
|
|
221
|
+
| 역추적 | 스택 트레이스가 있거나 문제 발현 지점이 명확할 때 |
|
|
222
|
+
| 데이터 흐름 추적 | 잘못된 값이 출력되거나 기대와 다른 결과가 나올 때 |
|
|
223
|
+
| 변경 이력 분석 | "이전엔 됐는데 안 됨", 회귀가 의심될 때 |
|
|
224
|
+
| 제약 조건 추론 | 간헐적이거나 특정 환경/입력에서만 발생할 때 |
|
|
225
|
+
|
|
226
|
+
상세 적용법은 `references/verification-tools.md` 참조.
|
|
227
|
+
|
|
228
|
+
각 실험마다 "이 실험으로 어떤 가설이 *반증* 될 수 있는가"를 먼저 명시한다 (Falsification First). 실험 결과를 새 증거로 매트릭스에 추가하고, 각 가설에 대해 C(code)/C(doc)/C(infer)/I/N을 표시한다.
|
|
229
|
+
|
|
230
|
+
### 4-3. 가설 폐기 룰
|
|
231
|
+
|
|
232
|
+
- **I(불일치)** 표시가 있는 가설은 폐기한다 (코드에서 직접 관찰 가능한 모순일 때만)
|
|
233
|
+
- **C(infer)만으로 구성된 가설**은 확정 불가 — 추가 증거 필요 (다음 실험 대상)
|
|
234
|
+
- **C(code) 또는 C(doc)으로 충분히 뒷받침되고 I가 없는 가설**이 살아남은 가설
|
|
235
|
+
|
|
236
|
+
### 4-4. 분석 한계 명시
|
|
237
|
+
|
|
238
|
+
런타임 데이터(API 응답, DB 결과 등)를 직접 확인할 수 없는 경우, 그 한계를 ACH 결과에 명시한다 — "실제 데이터를 확인하지 못했으므로 추정에 기반한 판정"임을 밝힌다.
|
|
239
|
+
|
|
240
|
+
### 4-5. 반복 종료 조건
|
|
45
241
|
|
|
46
|
-
|
|
242
|
+
- 살아남은 가설이 1개로 좁혀지면 Phase 5로 진행
|
|
243
|
+
- 살아남은 가설이 복수면 Phase 5에서 각각 종축 추적
|
|
244
|
+
- 살아남은 가설이 0개면 Phase 1로 돌아가 추가 증거 수집 또는 사용자에게 추가 컨텍스트 요청
|
|
245
|
+
|
|
246
|
+
상세 매트릭스 작성 가이드는 `references/ach-matrix.md` 참조.
|
|
247
|
+
|
|
248
|
+
## Phase 5: 분기형 5 Whys — 인과 종축 추적
|
|
249
|
+
|
|
250
|
+
### 5-1. 적용 대상
|
|
251
|
+
|
|
252
|
+
Phase 4에서 살아남은 각 가설에 대해 "왜?"를 반복하여 표면 원인 → 근본 원인까지 추적한다.
|
|
253
|
+
|
|
254
|
+
### 5-2. 분기 강제
|
|
255
|
+
|
|
256
|
+
매 "왜?" 단계마다 **2개 이상의 분기 후보**를 나열하고, 그중 증거로 뒷받침되는 분기만 채택한다. 단일 인과사슬에 갇히지 않는다.
|
|
47
257
|
|
|
48
|
-
- **방안:** {선택된 방안 이름}
|
|
49
|
-
- **설명:** {구현 방향, 코드 예시 포함}
|
|
50
|
-
- **선택 사유:** {사용자 코멘트 또는 선택 근거}
|
|
51
258
|
```
|
|
259
|
+
증상: null row가 결과에 섞임
|
|
260
|
+
└ 왜? 트랜잭션 격리 위반
|
|
261
|
+
├ 왜? 풀 재사용 시 prepared statement 캐시 공유 ← C(code) 채택
|
|
262
|
+
│ └ 왜? cache key에 connection id 누락 ← ROOT
|
|
263
|
+
└ 왜? isolation level 잘못 설정 ← I 폐기
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 5-3. 종료 조건
|
|
267
|
+
|
|
268
|
+
- 더 이상 "왜?"를 물을 수 없는 지점 = ROOT
|
|
269
|
+
- 또는 코드/설정/외부 의존의 *수정 가능한 지점* 에 도달
|
|
270
|
+
|
|
271
|
+
상세 템플릿은 `references/branching-5whys.md` 참조.
|
|
272
|
+
|
|
273
|
+
## Phase 6: Fault Tree Analysis (조건부)
|
|
274
|
+
|
|
275
|
+
### 6-1. 적용 조건
|
|
276
|
+
|
|
277
|
+
Phase 5에서 단일 ROOT가 아니라 **두 개 이상의 원인이 결합** 되어야 발생하는 경우만 적용한다.
|
|
278
|
+
|
|
279
|
+
- AND 결합: 모든 조건이 동시에 만족되어야 발생
|
|
280
|
+
- OR 결합: 어느 하나라도 만족되면 발생
|
|
281
|
+
|
|
282
|
+
### 6-2. 트리 구조
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
[증상]
|
|
286
|
+
|
|
|
287
|
+
[AND]
|
|
288
|
+
/ \
|
|
289
|
+
[원인1] [원인2]
|
|
290
|
+
| |
|
|
291
|
+
[OR] [...]
|
|
292
|
+
/ \
|
|
293
|
+
[a] [b]
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
단일 원인 케이스에서는 Phase 6을 생략한다.
|
|
297
|
+
|
|
298
|
+
상세는 `references/fta-template.md` 참조.
|
|
299
|
+
|
|
300
|
+
## Phase 7: 보고 & 종료
|
|
301
|
+
|
|
302
|
+
분석 결과를 아래 양식대로 한 번의 응답으로 출력하고 즉시 종료한다. 사용자가 다음 메시지로 후속 작업을 지시하기 전까지 추가 행동을 하지 않는다.
|
|
303
|
+
|
|
304
|
+
### 출력 원칙
|
|
305
|
+
|
|
306
|
+
- **결론 우선**: 첫 줄에 확정된 원인을 한 문장으로 결론짓는다.
|
|
307
|
+
- **분석 메타정보 비출력**: ACH 매트릭스, 5 Whys 트리 전체, 폐기된 가설, 검증 도구 사용 과정은 보고에 포함하지 않는다. 살아남은 원인과 그 근거만 간결하게 노출한다.
|
|
308
|
+
- **근거는 인용으로**: 원인을 뒷받침하는 코드는 `파일경로:라인` 인용 + 코드블록으로 제시한다. 사용자가 원본 파일을 열지 않아도 판단 가능해야 한다.
|
|
309
|
+
- **해결책은 구체적으로**: 어디를(파일·라인·심볼), 어떻게(현재 → 변경 또는 시그니처) 바꿀지 명시한다. 구체화 불가하면 그 이유와 추가로 필요한 정보를 적는다.
|
|
310
|
+
- **반론·위험 명시**: 권장 해결책에도 부작용·놓친 시나리오·반론이 있으면 함께 적는다.
|
|
311
|
+
- **분석 한계 명시**: 런타임 데이터 미확인, 재현 한계, 추정 기반 부분이 있으면 분리해서 적는다.
|
|
312
|
+
- **편법 사용 금지**: 해결책에 위 "편법/우회방법 금지 목록"의 항목을 사용하지 않는다.
|
|
313
|
+
|
|
314
|
+
### 보고 양식
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
## 원인
|
|
318
|
+
{확정 원인 1줄 결론}
|
|
319
|
+
|
|
320
|
+
### 근거
|
|
321
|
+
- {파일:라인 인용 + 관찰 사실}
|
|
322
|
+
- (필요 시 코드블록으로 인용)
|
|
323
|
+
|
|
324
|
+
### 분석 한계
|
|
325
|
+
- {직접 확인 못 한 런타임 데이터 / 재현 한계 / 추정 기반 부분}
|
|
326
|
+
|
|
327
|
+
## 해결책
|
|
328
|
+
|
|
329
|
+
### 권장: {방안명}
|
|
330
|
+
- 위치: {파일:라인 또는 심볼}
|
|
331
|
+
- 변경 방향: {현재 → 변경 (코드블록 권장)}
|
|
332
|
+
- 근거: 왜 이게 근본 해결인가
|
|
333
|
+
- 위험·반론: {부작용·놓친 시나리오}
|
|
334
|
+
|
|
335
|
+
### 대안: {방안명} (필요 시)
|
|
336
|
+
- (권장과 동일 형식)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
원인이 복수로 살아남았다면 `## 원인` 아래에 원인1·원인2를 나란히 배치하고, `## 해결책` 아래에 원인별 권장/대안을 둔다. 분석 한계가 없으면 `### 분석 한계` 섹션은 생략한다.
|
|
340
|
+
|
|
341
|
+
### 종료
|
|
52
342
|
|
|
53
|
-
|
|
343
|
+
보고 출력 후 즉시 종료한다. 사용자 지시 없이 다음을 하지 않는다.
|
|
54
344
|
|
|
55
|
-
|
|
56
|
-
|
|
345
|
+
- 코드 수정
|
|
346
|
+
- 후속 스킬(`/sd-dev`, `/sd-tdd` 등) 자동 호출
|
|
347
|
+
- 별도 파일 생성 (`debug.md` 등)
|