@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.
Files changed (33) hide show
  1. package/claude/references/sd-simplysm-v14/sd-claude/assets.md +2 -4
  2. package/claude/rules/sd-claude-rules.md +29 -0
  3. package/claude/rules/sd-options.md +19 -22
  4. package/claude/rules/sd-response-format.md +35 -0
  5. package/claude/settings.json +2 -0
  6. package/claude/skills/sd-check/SKILL.md +30 -3
  7. package/claude/skills/sd-claude-docs/SKILL.md +62 -29
  8. package/claude/skills/sd-claude-docs/merge-source.py +47 -0
  9. package/claude/skills/sd-debug/SKILL.md +322 -31
  10. package/claude/skills/sd-debug/references/ach-matrix.md +154 -0
  11. package/claude/skills/sd-debug/references/branching-5whys.md +126 -0
  12. package/claude/skills/sd-debug/references/fishbone-categories.md +142 -0
  13. package/claude/skills/sd-debug/references/fta-template.md +176 -0
  14. package/claude/skills/sd-debug/references/repro-collab.md +159 -0
  15. package/claude/skills/sd-debug/references/repro-minimize.md +107 -0
  16. package/claude/skills/sd-debug/references/verification-tools.md +204 -0
  17. package/claude/skills/sd-deliverable/SKILL.md +1 -1
  18. package/claude/skills/sd-dev/SKILL.md +22 -71
  19. package/claude/skills/sd-inner-clarify/SKILL.md +24 -9
  20. package/claude/skills/sd-plan/SKILL.md +82 -21
  21. package/claude/skills/sd-prompt/SKILL.md +66 -23
  22. package/claude/skills/sd-prompt/references/eval-runner.md +2 -2
  23. package/claude/skills/sd-review/SKILL.md +201 -25
  24. package/claude/skills/sd-review/merge-source.py +66 -0
  25. package/claude/skills/sd-tdd/SKILL.md +2 -2
  26. package/claude/skills/sd-use/SKILL.md +5 -8
  27. package/claude/skills/sd-wbs/SKILL.md +90 -12
  28. package/package.json +1 -1
  29. package/claude/skills/sd-claude-docs/merge-source.sh +0 -23
  30. package/claude/skills/sd-dev/subagent-preamble.md +0 -22
  31. package/claude/skills/sd-inner-debug/SKILL.md +0 -145
  32. package/claude/skills/sd-inner-review/SKILL.md +0 -173
  33. package/claude/skills/sd-inner-review/merge-source.sh +0 -41
@@ -0,0 +1,142 @@
1
+ # Fishbone 6축 카테고리 — 가설 분기 가이드
2
+
3
+ Phase 3에서 가설을 발산할 때 사용한다. 각 축마다 가설을 1개 이상 생성하여 전체 ≥3개를 확보한다.
4
+
5
+ ## 6축 정의
6
+
7
+ ### 1. 코드
8
+
9
+ 로직 자체의 오류.
10
+
11
+ - 조건문 오류 (`>` vs `>=`, AND/OR 혼동)
12
+ - 순서 오류 (정렬, 처리 단계)
13
+ - 타입 불일치 (string ↔ number)
14
+ - 알고리즘 결함
15
+
16
+ 예시 가설:
17
+
18
+ - "sortByAge가 number 비교 대신 string 비교를 한다"
19
+ - "for 루프의 종료 조건이 `<` 대신 `<=`이다"
20
+
21
+ ### 2. 입력·데이터
22
+
23
+ 함수에 들어오는 값의 문제.
24
+
25
+ - 예상 못 한 값 (NaN, Infinity, 음수)
26
+ - NULL/빈 값/빈 배열
27
+ - 인코딩 (UTF-8 vs CP949)
28
+ - 경계값 (0, MAX_INT, 빈 문자열)
29
+
30
+ 예시 가설:
31
+
32
+ - "users 배열에 roles가 undefined인 항목이 있다"
33
+ - "입력 CSV의 BOM이 첫 컬럼명에 섞인다"
34
+
35
+ ### 3. 환경·설정
36
+
37
+ 런타임 환경의 문제.
38
+
39
+ - 환경변수 미설정/잘못 설정
40
+ - 설정 파일 (sd.config.ts, tsconfig.json)
41
+ - 의존성 버전 불일치
42
+ - 빌드 타겟 (브라우저, Node 버전)
43
+
44
+ 예시 가설:
45
+
46
+ - "프로덕션 환경에서 NODE_ENV가 development로 빌드됐다"
47
+ - "esbuild target이 Chrome 61이라 WeakRef 폴리필 누락"
48
+
49
+ ### 4. 타이밍·동시성
50
+
51
+ 순서·동시성의 문제.
52
+
53
+ - async 순서 (await 누락, Promise 체인)
54
+ - race condition (동시 쓰기/읽기)
55
+ - 트랜잭션 격리 (커밋 전 읽기, 락 충돌)
56
+ - 이벤트 루프 차단
57
+
58
+ 예시 가설:
59
+
60
+ - "두 useEffect가 동시 실행되어 state가 덮어써진다"
61
+ - "DB 트랜잭션 isolation level이 낮아 dirty read 발생"
62
+
63
+ ### 5. 외부 의존
64
+
65
+ 외부 라이브러리·API·서비스의 문제.
66
+
67
+ - 라이브러리 버그/변경 (changelog 확인 필수)
68
+ - API 응답 형식 변경
69
+ - DB 스키마 변경
70
+ - 외부 서비스 가용성
71
+
72
+ 예시 가설:
73
+
74
+ - "Angular 21로 업그레이드 후 ChangeDetectorRef 동작 변경"
75
+ - "외부 API가 ISO 8601 대신 Unix timestamp 반환"
76
+
77
+ **주의**: 외부 의존 가설은 `C(doc)` 이상의 근거 (GitHub 이슈, changelog, 소스코드 직접 확인) 없이 채택할 수 없다. 추정만으로 외부 탓 금지.
78
+
79
+ ### 6. 상태 관리
80
+
81
+ 캐시·메모리·세션 등 잔존 상태의 문제.
82
+
83
+ - 캐시 무효화 누락
84
+ - 메모리 누수 (잔존 참조)
85
+ - 세션 데이터 stale
86
+ - 잘못된 초기화 순서
87
+
88
+ 예시 가설:
89
+
90
+ - "service worker가 이전 버전 응답을 캐싱"
91
+ - "Redux store 초기화 전에 selector가 호출됨"
92
+
93
+ ## 축 간 경계 — 헷갈릴 때
94
+
95
+ | 헷갈림 | 어디로 분류? |
96
+ | ------------------------------- | ----------------------------------------- |
97
+ | 코드가 race condition을 만듦 | 타이밍·동시성 (4) |
98
+ | 라이브러리 *사용법*이 틀림 | 코드 (1) — 외부 의존 아님 |
99
+ | 환경변수 못 읽음 | 환경·설정 (3) — 코드 아님 |
100
+ | 캐시된 잘못된 응답 | 상태 관리 (6) |
101
+ | API *응답 형식이 변함* | 외부 의존 (5) |
102
+ | 외부 API 응답이 늦어 타임아웃 | 외부 의존 (5) + 타이밍·동시성 (4) 양쪽 |
103
+ | 잘못된 마이그레이션으로 NULL | 입력·데이터 (2) + 환경·설정 (3) 양쪽 |
104
+
105
+ 원칙: **가장 직접적인 원인** 으로 분류. 한 가설이 두 축에 걸치면 더 명확한 쪽 선택. 모호하면 양쪽 모두에 중복 등록 (다른 ID로) 후 ACH로 수렴.
106
+
107
+ ## 가설 작성 형식
108
+
109
+ 각 가설은 다음 형식으로 명시.
110
+
111
+ ```
112
+ H<번호> (<카테고리>)
113
+ 주장: <X가 Y이다 / X가 Y하기 때문에 Z가 발생한다>
114
+ 검증: <어떤 실험/관찰로 입증·반증할 수 있는가>
115
+ ```
116
+
117
+ ### 예시
118
+
119
+ ```
120
+ H1 (코드)
121
+ 주장: sortByAge가 String.localeCompare로 비교하므로 숫자가 사전식으로 정렬된다
122
+ 검증: src/sorter.ts:N의 비교 함수 확인 + 테스트 입력으로 출력 확인 (역추적/데이터 흐름 추적)
123
+
124
+ H2 (입력·데이터)
125
+ 주장: items 배열의 age 필드가 string으로 들어온다
126
+ 검증: 호출 지점의 typeof 확인 (역추적)
127
+
128
+ H3 (외부 의존)
129
+ 주장: localeCompare가 브라우저별로 숫자 비교 동작이 다르다
130
+ 검증: 공식 문서·MDN 확인 (외부 의존 가설은 C(doc) 이상 필수)
131
+ ```
132
+
133
+ ## 가설 수와 균형
134
+
135
+ - 전체 가설 수: 최소 3개, 권장 4~6개
136
+ - 6축 모두에 가설을 만들 필요는 없음 — 증거가 가리키는 방향에 무게 둠
137
+ - 단, *한 축에만 가설이 몰리면 anchor bias 위험* — 다른 축에서도 최소 1개 추가 시도
138
+
139
+ ## 사용자 출력 vs 내부 작업
140
+
141
+ 생성된 가설 목록은 **내부 작업**으로 유지한다. 사용자에게 출력하지 않는다.
142
+ Phase 7 보고에는 ACH/5 Whys로 살아남은 *원인*만 노출.
@@ -0,0 +1,176 @@
1
+ # Fault Tree Analysis (FTA) — Phase 6 적용 가이드
2
+
3
+ 복합 인과 케이스에서만 적용. 단일 원인이면 Phase 6 생략.
4
+
5
+ FTA는 안전공학에서 출발한 RCA 기법으로, 복수의 원인이 *논리 게이트(AND/OR)* 로 결합되어 증상을 만들어내는 구조를 표현한다.
6
+
7
+ ## 적용 조건
8
+
9
+ Phase 5의 분기형 5 Whys가 다음 중 하나로 끝났을 때.
10
+
11
+ - **AND 결합**: 두 개 이상의 조건이 동시에 만족되어야 발생
12
+ - **OR 결합**: 어느 하나라도 만족되면 발생
13
+ - **혼합**: AND와 OR이 중첩
14
+
15
+ 5 Whys가 단일 ROOT로 끝나면 Phase 6 생략.
16
+
17
+ ## 게이트 종류
18
+
19
+ ### AND 게이트
20
+
21
+ ```
22
+ [증상]
23
+ |
24
+ [AND]
25
+ / \
26
+ [원인1] [원인2]
27
+ ```
28
+
29
+ 해석: 원인1 *그리고* 원인2가 모두 참일 때만 증상 발생.
30
+
31
+ 예시:
32
+
33
+ ```
34
+ null row 결과
35
+ |
36
+ [AND]
37
+ |
38
+ ├─ 풀 사이즈 ≥ 2
39
+ └─ 동시 트랜잭션 ≥ 2
40
+ ```
41
+
42
+ → 풀 사이즈 1이거나 동시 트랜잭션 1이면 발생 안 함. 둘 다여야 발생.
43
+
44
+ ### OR 게이트
45
+
46
+ ```
47
+ [증상]
48
+ |
49
+ [OR]
50
+ / \
51
+ [원인1] [원인2]
52
+ ```
53
+
54
+ 해석: 원인1 *또는* 원인2 중 하나라도 참이면 증상 발생.
55
+
56
+ 예시:
57
+
58
+ ```
59
+ 로그인 실패
60
+ |
61
+ [OR]
62
+ |
63
+ ├─ 비밀번호 만료
64
+ └─ 계정 잠금
65
+ ```
66
+
67
+ → 둘 중 하나만 참이어도 발생.
68
+
69
+ ## 다층 트리
70
+
71
+ 게이트는 중첩 가능.
72
+
73
+ ```
74
+ [증상]
75
+ |
76
+ [AND]
77
+ / \
78
+ [원인1] [원인2]
79
+ |
80
+ [OR]
81
+ / \
82
+ [a] [b]
83
+ ```
84
+
85
+ 해석: 원인1 AND (원인2-a OR 원인2-b)
86
+
87
+ ## 적용 절차
88
+
89
+ 1. Phase 5의 ROOT들을 수집
90
+ 2. 각 ROOT가 단독으로 증상을 일으키는지 확인 → OR 후보
91
+ 3. 두 ROOT가 동시에 있어야 증상이 발생하는지 확인 → AND 후보
92
+ 4. 검증: ROOT 중 하나만 제거했을 때 증상이 사라지는가?
93
+ - 사라지면 → AND (그 ROOT가 필수 조건)
94
+ - 안 사라지면 → OR (다른 ROOT가 단독으로도 발생시킴)
95
+ 5. 트리 작성
96
+
97
+ ## ACH 등록
98
+
99
+ 각 ROOT는 이미 Phase 4에서 ACH 등급을 받음 (C(code)/C(doc)). FTA는 *게이트 결합 자체* 를 새 가설로 등록하지 않고, 기존 ROOT들의 *결합 형태* 를 도출하는 것.
100
+
101
+ 게이트 결합의 검증은 다음으로 수행:
102
+
103
+ - ROOT 한 쪽만 제거 후 재현 시도 (검증 도구의 *제약 조건 추론* 활용)
104
+ - L2~L5 모드에서는 사용자에게 "ROOT-A만 해결했을 때 증상 사라지는가?" 추가 질문
105
+
106
+ ## 보고 형식
107
+
108
+ Phase 7 보고에서 다음 형식으로 노출.
109
+
110
+ ### AND 결합인 경우
111
+
112
+ ```
113
+ ## 원인 (복합)
114
+
115
+ 증상은 다음 두 조건이 동시에 만족될 때 발생한다 (AND 결합):
116
+
117
+ 1. ROOT-A: ...
118
+ 2. ROOT-B: ...
119
+
120
+ → ROOT-A 또는 ROOT-B 중 *하나만* 해결해도 증상 사라짐 (해결책 선택 가능)
121
+ ```
122
+
123
+ ### OR 결합인 경우
124
+
125
+ ```
126
+ ## 원인 (복합)
127
+
128
+ 증상은 다음 중 어느 하나라도 만족되면 발생한다 (OR 결합):
129
+
130
+ 1. ROOT-A: ...
131
+ 2. ROOT-B: ...
132
+
133
+ → *모든 ROOT* 를 해결해야 증상 완전 제거
134
+ ```
135
+
136
+ ### 혼합인 경우
137
+
138
+ ```
139
+ ## 원인 (복합)
140
+
141
+ 증상은 다음 결합 시 발생:
142
+
143
+ ROOT-A AND (ROOT-B OR ROOT-C)
144
+
145
+ - ROOT-A: ...
146
+ - ROOT-B: ...
147
+ - ROOT-C: ...
148
+
149
+ → ROOT-A를 해결하거나, ROOT-B와 ROOT-C를 *모두* 해결하면 증상 사라짐
150
+ ```
151
+
152
+ ## 해결책 우선순위
153
+
154
+ 복합 원인에서 해결책 우선순위 결정:
155
+
156
+ - **AND 결합**: 가장 cheap-to-fix한 ROOT 한 쪽만 제거 (다른 ROOT는 보존 가능)
157
+ - **OR 결합**: 모든 ROOT를 제거해야 함. 하나만 고치면 다른 경로로 재발
158
+ - **혼합**: 트리 구조에 따라 *최소 cut set* 분석
159
+
160
+ ## 함정
161
+
162
+ ### 가짜 AND
163
+
164
+ "두 조건이 동시에 있어야 발생"으로 보였지만 사실 한쪽이 다른 쪽의 *원인* 인 경우.
165
+
166
+ 예: "메모리 압력 + 캐시 무효화 누락" → 메모리 압력 때문에 캐시 무효화가 누락된 것이라면 AND가 아니라 단일 사슬 (5 Whys로 처리).
167
+
168
+ ### 가짜 OR
169
+
170
+ "둘 중 하나만 있어도 발생"으로 보였지만 사실 *공통 상위 원인* 이 있는 경우.
171
+
172
+ 예: "ROOT-A 또는 ROOT-B" → 둘 다 ROOT-C가 만든 증상이라면 ROOT-C가 진짜 ROOT.
173
+
174
+ ### 검증 부족
175
+
176
+ "AND/OR 결합으로 보인다"는 추정만으로 결정하지 말 것. 실제 ROOT 한쪽 제거 시 재현 여부 확인 (제약 조건 추론).
@@ -0,0 +1,159 @@
1
+ # L2~L5 사용자 협업 정보 수집
2
+
3
+ Phase 2-3에서 사용한다. LLM이 직접 재현할 수 없는 케이스(L2 사용자 환경 / L3 하드웨어 / L4 간헐 / L5 프로덕션 데이터)에서 사용자에게 정보 수집을 요청하는 절차.
4
+
5
+ ## 공통 원칙
6
+
7
+ - **단일 질문으로 묶기**: 사용자 부담을 줄이기 위해 여러 항목을 하나의 질문으로 묶는다
8
+ - **민감 정보 제거**: PII, 비밀번호, 토큰 등은 익명화하여 제출하도록 안내
9
+ - **수집 형식 명시**: 텍스트/스크린샷/파일 첨부 중 어떤 형식인지 명확히
10
+ - **ACH 등록**: 수집된 정보는 Phase 4 ACH 매트릭스의 증거(E_n)로 등록
11
+
12
+ ## L2 — 사용자 환경 의존
13
+
14
+ 특정 OS/브라우저/사용자 설정/시점에서만 발생.
15
+
16
+ ### 수집 항목
17
+
18
+ | 항목 | 수집 방법 |
19
+ | ----------------- | --------------------------------------------------------------- |
20
+ | 정확한 재현 절차 | 클릭 순서·입력값을 단계별로 |
21
+ | 콘솔 로그 | 브라우저 DevTools → Console → 우클릭 → Save as |
22
+ | 네트워크 캡처 | DevTools → Network → 우클릭 → Save all as HAR |
23
+ | 스크린샷/영상 | 발생 직전~직후 |
24
+ | 환경 정보 | OS, 브라우저, 버전, 로케일, 시간대 |
25
+ | 사용자 설정 | 관련 설정 화면의 현재 상태 (스크린샷 또는 설정 export) |
26
+
27
+ ### 사용자 요청 템플릿
28
+
29
+ > 다음 정보를 수집해주세요:
30
+ > 1. 재현 절차 (단계별)
31
+ > 2. 브라우저 콘솔 로그 (DevTools → Console → Save as)
32
+ > 3. HAR 파일 (DevTools → Network → 우클릭 → Save all as HAR)
33
+ > 4. OS / 브라우저 / 버전
34
+ > 5. 발생 시점의 스크린샷 (선택)
35
+
36
+ ## L3 — 하드웨어 의존
37
+
38
+ 디바이스/주변기기에서만 발생. simplysm의 capacitor-plugin-* (auto-update / intent / file-system / usb-storage)이 대표적.
39
+
40
+ ### 수집 항목
41
+
42
+ | 항목 | 수집 방법 |
43
+ | ----------------- | --------------------------------------------------------------- |
44
+ | 디바이스 모델 | 설정 → 정보 |
45
+ | OS 버전 | 설정 → 정보 |
46
+ | 디바이스 로그 | Android: `adb logcat`, iOS: Xcode console, 시리얼: 터미널 dump |
47
+ | 주변기기 사양 | USB·시리얼·카메라 등 정확한 모델명·VID/PID |
48
+ | 연결 상태 | 발생 시점의 연결 상태 (유선/무선, 충전/방전, 포트 번호) |
49
+ | 앱 버전 | Capacitor 버전, 플러그인 버전, 빌드 번호 |
50
+
51
+ ### Android 디바이스 로그 수집
52
+
53
+ ```bash
54
+ # 발생 직전부터 기록
55
+ adb logcat -c # 기존 로그 클리어
56
+ adb logcat | tee debug.log # 새 로그 기록 시작
57
+ # (사용자가 재현 절차 수행)
58
+ # Ctrl+C로 종료, debug.log 제출
59
+ ```
60
+
61
+ 특정 태그만 필터링:
62
+
63
+ ```bash
64
+ adb logcat *:E Capacitor:V # 에러 + Capacitor 관련 verbose
65
+ ```
66
+
67
+ ### iOS 디바이스 로그 수집
68
+
69
+ Xcode → Window → Devices and Simulators → 디바이스 선택 → Open Console.
70
+
71
+ ### 사용자 요청 템플릿
72
+
73
+ > 다음 정보를 수집해주세요:
74
+ > 1. 디바이스 모델 / OS 버전 / 앱 버전
75
+ > 2. 디바이스 로그 (Android: `adb logcat -c && adb logcat > debug.log` 후 재현, iOS: Xcode Console)
76
+ > 3. 주변기기 모델명 (해당 시)
77
+ > 4. 발생 시점의 연결 상태
78
+
79
+ ## L4 — 간헐 발생
80
+
81
+ race condition, 메모리 압력, 타이밍 의존.
82
+
83
+ ### 수집 항목
84
+
85
+ | 항목 | 수집 방법 |
86
+ | ----------------- | --------------------------------------------------------------- |
87
+ | 재현 빈도 | "10회 시도 중 N회 발생" |
88
+ | 발생 시점 패턴 | 시작 직후 / 일정 시간 후 / 특정 부하 시 |
89
+ | 발생 직전 상태 | 직전에 어떤 조작/요청이 있었는지 |
90
+ | 동시성 조건 | 동시 사용자 수, 동시 요청 수, 트랜잭션 활성 수 |
91
+ | 시스템 리소스 | 발생 시점의 메모리/CPU/디스크 사용률 |
92
+
93
+ ### 추가 진단 요청
94
+
95
+ - 로그 레벨을 DEBUG로 올려 발생 시점 캡처 요청
96
+ - 메모리/CPU 사용률 모니터링 (발생 직전·직후)
97
+ - race condition 의심 시 단일 스레드/단일 워커로 변경 시 재현 여부 확인 요청
98
+ - 트랜잭션 격리 의심 시 isolation level을 SERIALIZABLE로 올려 재현 여부 확인
99
+
100
+ ### 사용자 요청 템플릿
101
+
102
+ > 다음 정보를 수집해주세요:
103
+ > 1. 재현 빈도 (10회 시도 중 N회)
104
+ > 2. 발생 시점 패턴 (시작 직후 / 부하 시 / 특정 조작 후 등)
105
+ > 3. 발생 직전 마지막 조작/요청
106
+ > 4. 동시 사용자 수 또는 동시 요청 수
107
+ > 5. (가능하면) 발생 시점의 메모리/CPU 사용률
108
+
109
+ ## L5 — 프로덕션 데이터 의존
110
+
111
+ 실제 DB 상태, 외부 API 응답, 사용자별 데이터에서만 발생.
112
+
113
+ ### 수집 항목
114
+
115
+ | 항목 | 수집 방법 |
116
+ | ------------------- | -------------------------------------------------------------- |
117
+ | 익명화된 페이로드 | 요청/응답 본문에서 PII 제거 후 제출 |
118
+ | DB 스키마 | `\d+ <table>` 또는 ORM 정의 |
119
+ | 샘플 row | 깨뜨리는 row만 (PII 익명화) |
120
+ | 외부 API 응답 | 발생 시점의 응답 본문·헤더·시각 |
121
+ | 데이터 버전·시점 | 마이그레이션 버전, 데이터 적재 시점 |
122
+
123
+ ### 익명화 가이드
124
+
125
+ - **PII** (이름, 주소, 전화, 이메일): `[REDACTED-NAME]`, `[REDACTED-EMAIL]` 등 토큰 치환
126
+ - **식별자** (사용자 ID, 주문 번호): 일관된 별칭 사용 (예: `user_001`, `order_001`)
127
+ - **토큰/비밀번호**: 절대 제출 금지. 형식만 알려달라고 요청 (예: "JWT, 길이 약 200자")
128
+ - **날짜·시각**: 포맷·시간대만 유지하고 실제 값은 마스킹 또는 상대 시각으로 변환 ("발생 시점 -5분")
129
+
130
+ ### 사용자 요청 템플릿
131
+
132
+ > 다음 정보를 수집해주세요 (PII는 반드시 익명화):
133
+ > 1. 깨뜨리는 입력 페이로드 (요청 본문)
134
+ > 2. 외부 API 응답 본문 (해당 시)
135
+ > 3. DB 샘플 row (관련 테이블만)
136
+ > 4. 데이터 시점 (적재 일시, 마이그레이션 버전)
137
+ > ⚠ 토큰·비밀번호는 절대 포함 금지. 형식만 알려주세요.
138
+
139
+ ## ACH 매트릭스 등록 형식
140
+
141
+ 수집된 정보는 다음 형식으로 ACH 증거로 등록.
142
+
143
+ ```
144
+ E_n: [출처: L3 디바이스 로그 (Android 14, Pixel 7)]
145
+ "E/Capacitor: USB device detached during transfer at line 234"
146
+
147
+ → 가설 H1 (USB 분리 처리 누락): C(code)
148
+ → 가설 H2 (드라이버 호환성): C(infer) — 디바이스/OS 한정 정보 부족
149
+ ```
150
+
151
+ 사용자 환경 로그는 일반적으로 C(code) 또는 C(doc) 등급. 단, 사용자가 잘못 수집했을 가능성이 있으면 C(infer)로 표기.
152
+
153
+ ## 분석 한계 명시
154
+
155
+ L2~L5 모드에서 수집한 정보는 LLM이 직접 *실행* 으로 검증하지 못한다. Phase 7 보고의 "분석 한계" 섹션에 다음을 분리해 적는다.
156
+
157
+ - 직접 재현 못 한 부분
158
+ - 사용자 보고에만 의존한 증거
159
+ - 추정 기반 결론 (C(infer)으로만 뒷받침된 결론)
@@ -0,0 +1,107 @@
1
+ # Delta Debugging — 1-minimal 케이스 축소
2
+
3
+ Phase 2-2 (L1 재현 가능 케이스)에서 사용한다. 재현된 실패 케이스를 최소화하여 가설 검증 비용을 낮추고 원인 식별 정확도를 높인다.
4
+
5
+ Andreas Zeller(1999)의 Delta Debugging 알고리즘 기반.
6
+
7
+ ## 알고리즘
8
+
9
+ ```
10
+ function dd(D):
11
+ # D: 실패하는 입력/변경 집합
12
+ if |D| == 1:
13
+ return D # 1-minimal 도달
14
+ D1, D2 = split(D, 2)
15
+ if test(D1) == FAIL:
16
+ return dd(D1) # D1로 좁힘
17
+ if test(D2) == FAIL:
18
+ return dd(D2) # D2로 좁힘
19
+ return dd_with_complement(D, D1, D2) # 양쪽 다 PASS면 더 작게 쪼개기
20
+
21
+ function dd_with_complement(D, D1, D2):
22
+ # n등분으로 더 작게 쪼개고 보수 집합(complement) 테스트
23
+ for n = 2, 4, 8, ...:
24
+ parts = split(D, n)
25
+ for each part p in parts:
26
+ complement = D - p
27
+ if test(complement) == FAIL:
28
+ return dd(complement)
29
+ return D # 더 줄일 수 없음
30
+ ```
31
+
32
+ ## 적용 대상별 예시
33
+
34
+ ### 1. 입력 데이터
35
+
36
+ 10000행 CSV가 깨뜨림 → 어떤 행이 원인?
37
+
38
+ 1. 5000행 / 5000행 분할 → 첫 5000행에서 실패 재현
39
+ 2. 2500행 / 2500행 분할 → 두 번째 2500행에서 실패 재현
40
+ 3. 반복하여 단일 row까지 좁힘
41
+
42
+ ### 2. 코드 변경 (`git bisect`)
43
+
44
+ 100 commit 사이에서 회귀 도입 → 어떤 커밋이 원인?
45
+
46
+ ```bash
47
+ git bisect start
48
+ git bisect bad HEAD
49
+ git bisect good <known-good-commit>
50
+ # 자동으로 중간 커밋 체크아웃
51
+ git bisect run pnpm test # 자동화: 테스트 결과로 good/bad 판정
52
+ git bisect reset # 종료
53
+ ```
54
+
55
+ ### 3. 파일/함수
56
+
57
+ 테스트가 깨졌는데 어떤 import가 원인?
58
+
59
+ 1. import의 절반을 주석 처리 → 깨짐 여부 확인
60
+ 2. 깨진 절반을 다시 절반으로 → 반복
61
+ 3. 단일 import까지 좁힘
62
+
63
+ ### 4. 코드 라인
64
+
65
+ 수십 줄 변경 후 회귀 → 어느 라인이 깨뜨리는가?
66
+
67
+ `git diff`로 변경 라인 집합을 만든 뒤, 라인 단위로 dd 알고리즘 적용.
68
+
69
+ ## 종료 조건
70
+
71
+ - 한 글자/한 줄/한 커밋도 빼지 못하면 minimal
72
+ - 시간 제한 (사용자 부담 고려) — 상한선 설정 (예: 10분 또는 20회 반복)
73
+
74
+ ## 함정과 주의사항
75
+
76
+ ### 1-minimal은 globally minimal이 아니다
77
+
78
+ 서로 다른 시작점에서 더 작은 케이스가 가능할 수 있음. 단, 가설 식별 목적에는 1-minimal로 충분.
79
+
80
+ ### Non-deterministic 테스트
81
+
82
+ 결과가 매번 달라지면 Delta Debugging이 작동 불가.
83
+
84
+ → L4(간헐 발생)로 분류 후 `references/repro-collab.md`의 L4 절차 적용. Delta Debugging은 deterministic 케이스에서만 사용.
85
+
86
+ ### Side effect
87
+
88
+ 테스트 간 상태가 영향 미치면 매번 clean state로 시작.
89
+
90
+ - DB: 테스트 시작 시 초기화
91
+ - 파일 시스템: 임시 디렉토리 사용
92
+ - 네트워크: 모킹 또는 격리된 환경
93
+
94
+ ### Bisect 중 빌드 실패
95
+
96
+ `git bisect run` 중 빌드 자체가 깨지는 커밋이 있으면 `git bisect skip`으로 건너뛰기.
97
+
98
+ ## ACH 등록
99
+
100
+ 축소된 1-minimal 케이스를 Phase 4 ACH 매트릭스의 증거로 등록.
101
+
102
+ ```
103
+ E_n: [출처: Delta Debugging 결과]
104
+ "입력 [{age: 10}, {age: 2}] (2개 row)에서만 실패. 1개 row로는 재현 안 됨."
105
+ ```
106
+
107
+ 이 증거는 가설(예: "정렬 비교 함수 오류")의 C(code) 등급으로 표시.