omgkit 2.2.0 → 2.3.0
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/package.json +1 -1
- package/plugin/skills/databases/mongodb/SKILL.md +60 -776
- package/plugin/skills/databases/prisma/SKILL.md +53 -744
- package/plugin/skills/databases/redis/SKILL.md +53 -860
- package/plugin/skills/devops/aws/SKILL.md +68 -672
- package/plugin/skills/devops/github-actions/SKILL.md +54 -657
- package/plugin/skills/devops/kubernetes/SKILL.md +67 -602
- package/plugin/skills/devops/performance-profiling/SKILL.md +59 -863
- package/plugin/skills/frameworks/django/SKILL.md +87 -853
- package/plugin/skills/frameworks/express/SKILL.md +95 -1301
- package/plugin/skills/frameworks/fastapi/SKILL.md +90 -1198
- package/plugin/skills/frameworks/laravel/SKILL.md +87 -1187
- package/plugin/skills/frameworks/nestjs/SKILL.md +106 -973
- package/plugin/skills/frameworks/react/SKILL.md +94 -962
- package/plugin/skills/frameworks/vue/SKILL.md +95 -1242
- package/plugin/skills/frontend/accessibility/SKILL.md +91 -1056
- package/plugin/skills/frontend/frontend-design/SKILL.md +69 -1262
- package/plugin/skills/frontend/responsive/SKILL.md +76 -799
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +73 -921
- package/plugin/skills/frontend/tailwindcss/SKILL.md +60 -788
- package/plugin/skills/frontend/threejs/SKILL.md +72 -1266
- package/plugin/skills/languages/javascript/SKILL.md +106 -849
- package/plugin/skills/methodology/brainstorming/SKILL.md +70 -576
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +79 -831
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +81 -654
- package/plugin/skills/methodology/executing-plans/SKILL.md +86 -529
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +95 -586
- package/plugin/skills/methodology/problem-solving/SKILL.md +67 -681
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +70 -533
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +70 -610
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +70 -646
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +70 -478
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +66 -559
- package/plugin/skills/methodology/test-driven-development/SKILL.md +91 -752
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +78 -687
- package/plugin/skills/methodology/token-optimization/SKILL.md +72 -602
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +108 -529
- package/plugin/skills/methodology/writing-plans/SKILL.md +79 -566
- package/plugin/skills/omega/omega-architecture/SKILL.md +91 -752
- package/plugin/skills/omega/omega-coding/SKILL.md +161 -552
- package/plugin/skills/omega/omega-sprint/SKILL.md +132 -777
- package/plugin/skills/omega/omega-testing/SKILL.md +157 -845
- package/plugin/skills/omega/omega-thinking/SKILL.md +165 -606
- package/plugin/skills/security/better-auth/SKILL.md +46 -1034
- package/plugin/skills/security/oauth/SKILL.md +80 -934
- package/plugin/skills/security/owasp/SKILL.md +78 -862
- package/plugin/skills/testing/playwright/SKILL.md +77 -700
- package/plugin/skills/testing/pytest/SKILL.md +73 -811
- package/plugin/skills/testing/vitest/SKILL.md +60 -920
- package/plugin/skills/tools/document-processing/SKILL.md +111 -838
- package/plugin/skills/tools/image-processing/SKILL.md +126 -659
- package/plugin/skills/tools/mcp-development/SKILL.md +85 -758
- package/plugin/skills/tools/media-processing/SKILL.md +118 -735
- package/plugin/stdrules/SKILL_STANDARDS.md +490 -0
- package/plugin/skills/SKILL_STANDARDS.md +0 -743
|
@@ -1,589 +1,96 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
4
|
-
category: methodology
|
|
5
|
-
triggers:
|
|
6
|
-
- debugging
|
|
7
|
-
- bug investigation
|
|
8
|
-
- troubleshooting
|
|
9
|
-
- finding bugs
|
|
10
|
-
- fixing issues
|
|
11
|
-
- error analysis
|
|
12
|
-
- bug hunting
|
|
2
|
+
name: debugging-systematically
|
|
3
|
+
description: AI agent follows a 5-phase debugging process with reproduction, isolation, hypothesis testing, and root cause resolution. Use when investigating bugs, troubleshooting issues, or hunting errors.
|
|
13
4
|
---
|
|
14
5
|
|
|
15
|
-
#
|
|
6
|
+
# Debugging Systematically
|
|
16
7
|
|
|
17
|
-
|
|
8
|
+
## Quick Start
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
- Isolate the problem scope
|
|
25
|
-
- Generate and test hypotheses systematically
|
|
26
|
-
- Find root causes, not just symptoms
|
|
27
|
-
- Fix with confidence
|
|
28
|
-
- Prevent regression through tests
|
|
29
|
-
- Document for future reference
|
|
10
|
+
1. **Reproduce** - Create reliable reproduction steps, document environment
|
|
11
|
+
2. **Isolate** - Binary search to narrow down, create minimal repro case
|
|
12
|
+
3. **Hypothesize** - Generate 3+ theories with evidence and test cost
|
|
13
|
+
4. **Test** - Design tests to prove/disprove each hypothesis
|
|
14
|
+
5. **Fix & Verify** - Write failing test first, implement fix, verify green
|
|
30
15
|
|
|
31
16
|
## Features
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
│ Goal: Consistently trigger the bug │
|
|
42
|
-
│ │
|
|
43
|
-
│ Questions: │
|
|
44
|
-
│ • What are the exact steps to reproduce? │
|
|
45
|
-
│ • What environment? (OS, browser, version) │
|
|
46
|
-
│ • Is it 100% reproducible or intermittent? │
|
|
47
|
-
│ • When did it start happening? │
|
|
48
|
-
│ • What changed recently? │
|
|
49
|
-
│ │
|
|
50
|
-
│ Output: Reliable reproduction steps │
|
|
51
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
52
|
-
│
|
|
53
|
-
▼
|
|
54
|
-
┌────────────────────────────────────────────────────────────────┐
|
|
55
|
-
│ PHASE 2: ISOLATE │
|
|
56
|
-
│ ═══════════════════ │
|
|
57
|
-
│ Goal: Narrow down the problem area │
|
|
58
|
-
│ │
|
|
59
|
-
│ Techniques: │
|
|
60
|
-
│ • Binary search: Disable half the code │
|
|
61
|
-
│ • Minimal repro: Simplest case that fails │
|
|
62
|
-
│ • Environment isolation: Local vs staging vs prod │
|
|
63
|
-
│ • Component isolation: Which module/service? │
|
|
64
|
-
│ • Time isolation: When did it start? │
|
|
65
|
-
│ │
|
|
66
|
-
│ Output: Specific file(s)/line(s) of interest │
|
|
67
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
68
|
-
│
|
|
69
|
-
▼
|
|
70
|
-
┌────────────────────────────────────────────────────────────────┐
|
|
71
|
-
│ PHASE 3: HYPOTHESIZE │
|
|
72
|
-
│ ═══════════════════ │
|
|
73
|
-
│ Goal: Form theories about the cause │
|
|
74
|
-
│ │
|
|
75
|
-
│ Generate at least 3 hypotheses: │
|
|
76
|
-
│ H1: [Most likely cause] - Evidence: ___ │
|
|
77
|
-
│ H2: [Second possibility] - Evidence: ___ │
|
|
78
|
-
│ H3: [Less likely but possible] - Evidence: ___ │
|
|
79
|
-
│ │
|
|
80
|
-
│ Prioritize by: │
|
|
81
|
-
│ • Evidence strength (what points to this?) │
|
|
82
|
-
│ • Test cost (how easy to verify?) │
|
|
83
|
-
│ • Likelihood (gut feeling + data) │
|
|
84
|
-
│ │
|
|
85
|
-
│ Output: Ranked list of hypotheses │
|
|
86
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
87
|
-
│
|
|
88
|
-
▼
|
|
89
|
-
┌────────────────────────────────────────────────────────────────┐
|
|
90
|
-
│ PHASE 4: TEST │
|
|
91
|
-
│ ═══════════════════ │
|
|
92
|
-
│ Goal: Verify or eliminate hypotheses │
|
|
93
|
-
│ │
|
|
94
|
-
│ For each hypothesis: │
|
|
95
|
-
│ 1. Design a test that would PROVE it │
|
|
96
|
-
│ 2. Design a test that would DISPROVE it │
|
|
97
|
-
│ 3. Run tests, record results │
|
|
98
|
-
│ 4. Move to next hypothesis or dig deeper │
|
|
99
|
-
│ │
|
|
100
|
-
│ Tools: Logging, debugger, profiler, tests │
|
|
101
|
-
│ │
|
|
102
|
-
│ Output: Confirmed root cause │
|
|
103
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
104
|
-
│
|
|
105
|
-
▼
|
|
106
|
-
┌────────────────────────────────────────────────────────────────┐
|
|
107
|
-
│ PHASE 5: FIX & VERIFY │
|
|
108
|
-
│ ═══════════════════ │
|
|
109
|
-
│ Goal: Fix correctly and prevent recurrence │
|
|
110
|
-
│ │
|
|
111
|
-
│ Steps: │
|
|
112
|
-
│ 1. Write failing test that reproduces the bug │
|
|
113
|
-
│ 2. Implement minimal fix │
|
|
114
|
-
│ 3. Verify test passes │
|
|
115
|
-
│ 4. Check for related issues │
|
|
116
|
-
│ 5. Document the fix │
|
|
117
|
-
│ │
|
|
118
|
-
│ Output: Fixed code + regression test + documentation │
|
|
119
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### 2. Reproduction Techniques
|
|
123
|
-
|
|
124
|
-
```markdown
|
|
125
|
-
## Reproduction Strategies
|
|
126
|
-
|
|
127
|
-
### Creating Minimal Reproduction
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
// Original complex scenario
|
|
131
|
-
async function complexUserFlow() {
|
|
132
|
-
const user = await login('admin@test.com', 'password');
|
|
133
|
-
await navigateToSettings();
|
|
134
|
-
await clickTheme('dark');
|
|
135
|
-
await clickSave();
|
|
136
|
-
await navigateToProfile();
|
|
137
|
-
await uploadAvatar(largeImage);
|
|
138
|
-
await clickSave(); // Bug occurs here
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Minimal reproduction - strip away unrelated steps
|
|
142
|
-
async function minimalRepro() {
|
|
143
|
-
// Does uploading any image fail?
|
|
144
|
-
await uploadAvatar(largeImage); // Yes, bug here!
|
|
18
|
+
| Feature | Description | Guide |
|
|
19
|
+
|---------|-------------|-------|
|
|
20
|
+
| Reproduction | Consistent steps to trigger bug | Exact steps, environment, frequency |
|
|
21
|
+
| Isolation | Narrow down problem area | Binary search code, git bisect |
|
|
22
|
+
| Hypothesis Ranking | Prioritize theories to test | Evidence strength x (1/test cost) |
|
|
23
|
+
| Strategic Logging | Add targeted debug output | `[DEBUG][Service][method]` format |
|
|
24
|
+
| Git Bisect | Find regression commit | `git bisect start`, mark good/bad |
|
|
25
|
+
| Regression Tests | Prevent bug from returning | Write failing test before fixing |
|
|
145
26
|
|
|
146
|
-
|
|
147
|
-
await uploadAvatar(smallImage); // Works fine
|
|
27
|
+
## Common Patterns
|
|
148
28
|
|
|
149
|
-
// Root cause: Large file handling bug
|
|
150
|
-
}
|
|
151
29
|
```
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
6. Navigate to /users
|
|
170
|
-
7. Click "Export" button
|
|
171
|
-
8. Observe: Error "Maximum call stack size exceeded"
|
|
172
|
-
|
|
173
|
-
frequency: 100% reproducible
|
|
174
|
-
first_observed: 2024-01-15
|
|
175
|
-
last_known_good: commit def456 (2024-01-14)
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Intermittent Bug Reproduction
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
// For race conditions and intermittent bugs
|
|
182
|
-
async function stressTest() {
|
|
183
|
-
const results = [];
|
|
184
|
-
|
|
185
|
-
// Run many times to catch intermittent failures
|
|
186
|
-
for (let i = 0; i < 100; i++) {
|
|
187
|
-
try {
|
|
188
|
-
await performAction();
|
|
189
|
-
results.push({ iteration: i, status: 'success' });
|
|
190
|
-
} catch (error) {
|
|
191
|
-
results.push({ iteration: i, status: 'failure', error });
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Analyze failure rate
|
|
196
|
-
const failures = results.filter((r) => r.status === 'failure');
|
|
197
|
-
console.log(`Failure rate: ${failures.length}%`);
|
|
198
|
-
console.log('Failure details:', failures);
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### 3. Isolation Techniques
|
|
203
|
-
|
|
204
|
-
```markdown
|
|
205
|
-
## Binary Search Debugging
|
|
206
|
-
|
|
207
|
-
### Git Bisect for Regression Finding
|
|
208
|
-
```bash
|
|
209
|
-
# Start bisect session
|
|
210
|
-
git bisect start
|
|
211
|
-
|
|
212
|
-
# Mark current (broken) as bad
|
|
213
|
-
git bisect bad HEAD
|
|
214
|
-
|
|
215
|
-
# Mark last known good commit
|
|
216
|
-
git bisect good v2.0.0
|
|
217
|
-
|
|
218
|
-
# Git checks out middle commit
|
|
219
|
-
# Test and mark as good or bad
|
|
220
|
-
git bisect good # or: git bisect bad
|
|
221
|
-
|
|
222
|
-
# Repeat until culprit found
|
|
223
|
-
# Git will report: "abc123 is the first bad commit"
|
|
224
|
-
|
|
225
|
-
# Automate with a test script
|
|
226
|
-
git bisect run npm test
|
|
227
|
-
|
|
228
|
-
# Clean up
|
|
229
|
-
git bisect reset
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Code Section Isolation
|
|
233
|
-
```typescript
|
|
234
|
-
// Technique: Comment out half the code at a time
|
|
235
|
-
|
|
236
|
-
async function problematicFunction() {
|
|
30
|
+
# Reproduction Template
|
|
31
|
+
Environment:
|
|
32
|
+
OS: [version]
|
|
33
|
+
Node: [version]
|
|
34
|
+
Browser: [version]
|
|
35
|
+
|
|
36
|
+
Steps:
|
|
37
|
+
1. [Step 1]
|
|
38
|
+
2. [Step 2]
|
|
39
|
+
3. Observe: [Error]
|
|
40
|
+
|
|
41
|
+
Frequency: 100% | Intermittent (~50%)
|
|
42
|
+
First observed: [date]
|
|
43
|
+
Last known good: [commit/version]
|
|
44
|
+
|
|
45
|
+
# Isolation via Binary Search
|
|
46
|
+
function problematic() {
|
|
237
47
|
// BLOCK A
|
|
238
48
|
await stepA1();
|
|
239
49
|
await stepA2();
|
|
240
|
-
await stepA3();
|
|
241
50
|
|
|
242
51
|
// BLOCK B
|
|
243
52
|
await stepB1();
|
|
244
53
|
await stepB2();
|
|
245
|
-
await stepB3();
|
|
246
|
-
|
|
247
|
-
// Test: Comment out BLOCK B
|
|
248
|
-
// Still fails? Bug is in BLOCK A
|
|
249
|
-
// Works now? Bug is in BLOCK B
|
|
250
|
-
// Repeat binary search within the failing block
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Component Isolation
|
|
255
|
-
```typescript
|
|
256
|
-
// Test components in isolation
|
|
257
|
-
|
|
258
|
-
// Instead of testing full flow:
|
|
259
|
-
const result = await fullApiFlow(request);
|
|
260
|
-
|
|
261
|
-
// Test each component separately:
|
|
262
|
-
const validated = await validateRequest(request);
|
|
263
|
-
console.log('Validation:', validated); // Check here
|
|
264
|
-
|
|
265
|
-
const processed = await processData(validated);
|
|
266
|
-
console.log('Processing:', processed); // Check here
|
|
267
|
-
|
|
268
|
-
const stored = await saveToDatabase(processed);
|
|
269
|
-
console.log('Storage:', stored); // Check here
|
|
270
|
-
|
|
271
|
-
const response = await formatResponse(stored);
|
|
272
|
-
console.log('Response:', response); // Check here
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### 4. Hypothesis Generation
|
|
276
|
-
|
|
277
|
-
```markdown
|
|
278
|
-
## Hypothesis Categories
|
|
279
|
-
|
|
280
|
-
### Data Issues
|
|
281
|
-
- Invalid input data
|
|
282
|
-
- Missing required fields
|
|
283
|
-
- Type mismatches
|
|
284
|
-
- Encoding problems (UTF-8, etc.)
|
|
285
|
-
- Stale/cached data
|
|
286
|
-
- Data corruption
|
|
287
|
-
|
|
288
|
-
### Configuration Issues
|
|
289
|
-
- Wrong environment variables
|
|
290
|
-
- Missing config values
|
|
291
|
-
- Incorrect settings
|
|
292
|
-
- Feature flags
|
|
293
|
-
- Permission misconfig
|
|
294
|
-
|
|
295
|
-
### Timing Issues
|
|
296
|
-
- Race conditions
|
|
297
|
-
- Timeout too short/long
|
|
298
|
-
- Order of operations
|
|
299
|
-
- Async/await bugs
|
|
300
|
-
- Deadlocks
|
|
301
|
-
- Event loop blocking
|
|
302
|
-
|
|
303
|
-
### Resource Issues
|
|
304
|
-
- Memory exhaustion
|
|
305
|
-
- Disk space
|
|
306
|
-
- Connection pool exhausted
|
|
307
|
-
- File handles
|
|
308
|
-
- Network limits
|
|
309
|
-
- CPU throttling
|
|
310
|
-
|
|
311
|
-
### External Dependencies
|
|
312
|
-
- API changes
|
|
313
|
-
- Service downtime
|
|
314
|
-
- Network issues
|
|
315
|
-
- DNS problems
|
|
316
|
-
- Certificate expiry
|
|
317
|
-
- Rate limiting
|
|
318
|
-
|
|
319
|
-
### Code Logic
|
|
320
|
-
- Off-by-one errors
|
|
321
|
-
- Null pointer
|
|
322
|
-
- Wrong operator
|
|
323
|
-
- Missing edge case
|
|
324
|
-
- Incorrect algorithm
|
|
325
|
-
- State management bug
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
### Hypothesis Template
|
|
329
|
-
```markdown
|
|
330
|
-
## Hypothesis: Race Condition in User Update
|
|
331
|
-
|
|
332
|
-
### Evidence For
|
|
333
|
-
- Bug is intermittent (50% reproduction rate)
|
|
334
|
-
- Multiple async operations on same resource
|
|
335
|
-
- Logs show overlapping requests
|
|
336
|
-
|
|
337
|
-
### Evidence Against
|
|
338
|
-
- Works in single-user testing
|
|
339
|
-
- No obvious shared state
|
|
340
|
-
|
|
341
|
-
### Test Plan
|
|
342
|
-
1. Add mutex/lock around update
|
|
343
|
-
2. If fixes: Confirms race condition
|
|
344
|
-
3. If not: Eliminate hypothesis
|
|
345
|
-
|
|
346
|
-
### Test Cost: Low (30 min)
|
|
347
|
-
### Likelihood: High (70%)
|
|
348
|
-
### Priority: Test First
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
### 5. Debugging Tools Usage
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
// Strategic Logging
|
|
355
|
-
function debugWithLogging(data: unknown) {
|
|
356
|
-
// Use structured logging with context
|
|
357
|
-
console.log('[DEBUG][UserService][updateProfile]', {
|
|
358
|
-
timestamp: new Date().toISOString(),
|
|
359
|
-
userId: data.userId,
|
|
360
|
-
action: 'start',
|
|
361
|
-
data: sanitize(data), // Remove sensitive info
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
try {
|
|
365
|
-
const result = performUpdate(data);
|
|
366
54
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
action: 'success',
|
|
371
|
-
result: summarize(result),
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
return result;
|
|
375
|
-
} catch (error) {
|
|
376
|
-
console.log('[DEBUG][UserService][updateProfile]', {
|
|
377
|
-
timestamp: new Date().toISOString(),
|
|
378
|
-
userId: data.userId,
|
|
379
|
-
action: 'error',
|
|
380
|
-
error: error.message,
|
|
381
|
-
stack: error.stack,
|
|
382
|
-
});
|
|
383
|
-
throw error;
|
|
384
|
-
}
|
|
55
|
+
// Comment out BLOCK B
|
|
56
|
+
// Still fails? Bug in BLOCK A
|
|
57
|
+
// Works now? Bug in BLOCK B
|
|
385
58
|
}
|
|
386
59
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
console.time('step1');
|
|
396
|
-
await step1();
|
|
397
|
-
console.timeEnd('step1');
|
|
398
|
-
|
|
399
|
-
console.time('step2');
|
|
400
|
-
await step2();
|
|
401
|
-
console.timeEnd('step2');
|
|
402
|
-
|
|
403
|
-
console.time('step3');
|
|
404
|
-
await step3();
|
|
405
|
-
console.timeEnd('step3');
|
|
406
|
-
|
|
407
|
-
console.timeEnd('fullOperation');
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Memory Leak Detection
|
|
411
|
-
function checkForLeaks() {
|
|
412
|
-
const initialMemory = process.memoryUsage().heapUsed;
|
|
413
|
-
|
|
414
|
-
for (let i = 0; i < 10000; i++) {
|
|
415
|
-
performOperation();
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Force garbage collection (run with --expose-gc)
|
|
419
|
-
global.gc?.();
|
|
420
|
-
|
|
421
|
-
const finalMemory = process.memoryUsage().heapUsed;
|
|
422
|
-
const leaked = finalMemory - initialMemory;
|
|
423
|
-
|
|
424
|
-
console.log(`Memory difference: ${(leaked / 1024 / 1024).toFixed(2)} MB`);
|
|
425
|
-
}
|
|
60
|
+
# Git Bisect
|
|
61
|
+
git bisect start
|
|
62
|
+
git bisect bad HEAD
|
|
63
|
+
git bisect good v2.0.0
|
|
64
|
+
# Git checks out middle, test and mark
|
|
65
|
+
git bisect good # or: git bisect bad
|
|
66
|
+
# Repeat until culprit found
|
|
67
|
+
git bisect reset
|
|
426
68
|
```
|
|
427
69
|
|
|
428
|
-
### 6. Fix Verification
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
// Write the failing test FIRST
|
|
432
|
-
describe('User Profile Update', () => {
|
|
433
|
-
it('should handle large avatar uploads', async () => {
|
|
434
|
-
// This test should FAIL before the fix
|
|
435
|
-
const largeImage = generateLargeImage(10_000_000); // 10MB
|
|
436
|
-
|
|
437
|
-
const result = await uploadAvatar(userId, largeImage);
|
|
438
|
-
|
|
439
|
-
expect(result.success).toBe(true);
|
|
440
|
-
expect(result.url).toBeDefined();
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
it('should show error for files exceeding limit', async () => {
|
|
444
|
-
const tooLargeImage = generateLargeImage(50_000_000); // 50MB
|
|
445
|
-
|
|
446
|
-
await expect(uploadAvatar(userId, tooLargeImage)).rejects.toThrow(
|
|
447
|
-
'File size exceeds 20MB limit'
|
|
448
|
-
);
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
// After implementing fix, tests should pass
|
|
453
70
|
```
|
|
454
|
-
|
|
455
|
-
## Use Cases
|
|
456
|
-
|
|
457
|
-
### Debugging Session Log
|
|
458
|
-
|
|
459
|
-
```markdown
|
|
460
|
-
## Debug Session: API Timeout Error
|
|
461
|
-
|
|
462
|
-
### Problem Report
|
|
463
|
-
- Error: "Request timeout after 30000ms"
|
|
464
|
-
- Endpoint: POST /api/reports/generate
|
|
465
|
-
- Frequency: 60% of requests
|
|
466
|
-
- First reported: 2024-01-15
|
|
467
|
-
|
|
468
|
-
---
|
|
469
|
-
|
|
470
|
-
### Phase 1: Reproduce
|
|
471
|
-
**Steps to reproduce:**
|
|
472
|
-
1. Login as admin
|
|
473
|
-
2. Navigate to Reports
|
|
474
|
-
3. Select "Full Export" with date range > 1 year
|
|
475
|
-
4. Click Generate
|
|
476
|
-
|
|
477
|
-
**Result:** Timeout error after 30s
|
|
478
|
-
|
|
479
|
-
**Reproducibility:** 100% with > 1 year data
|
|
480
|
-
|
|
481
|
-
---
|
|
482
|
-
|
|
483
|
-
### Phase 2: Isolate
|
|
484
|
-
|
|
485
|
-
**Binary search results:**
|
|
486
|
-
- With 1 month data: Works (2s)
|
|
487
|
-
- With 6 months data: Works (15s)
|
|
488
|
-
- With 1 year data: Timeout (>30s)
|
|
489
|
-
|
|
490
|
-
**Component isolation:**
|
|
491
|
-
- API handler: Fast
|
|
492
|
-
- Database query: SLOW (found bottleneck!)
|
|
493
|
-
- Report generation: Not reached
|
|
494
|
-
|
|
495
|
-
**Identified:** Database query taking too long
|
|
496
|
-
|
|
497
|
-
---
|
|
498
|
-
|
|
499
|
-
### Phase 3: Hypothesize
|
|
500
|
-
|
|
71
|
+
# Hypothesis Template
|
|
501
72
|
| # | Hypothesis | Evidence | Test Cost | Priority |
|
|
502
73
|
|---|------------|----------|-----------|----------|
|
|
503
|
-
| H1 | Missing index
|
|
504
|
-
| H2 | N+1 query
|
|
505
|
-
| H3 |
|
|
506
|
-
|
|
507
|
-
---
|
|
508
|
-
|
|
509
|
-
### Phase 4: Test
|
|
510
|
-
|
|
511
|
-
**H1 Test: Check for missing index**
|
|
512
|
-
```sql
|
|
513
|
-
EXPLAIN ANALYZE SELECT * FROM transactions
|
|
514
|
-
WHERE created_at BETWEEN '2023-01-01' AND '2024-01-01';
|
|
515
|
-
|
|
516
|
-
-- Result: Seq Scan on transactions (cost=0.00..25432.00)
|
|
517
|
-
-- Sequential scan = No index being used!
|
|
518
|
-
```
|
|
519
|
-
**Result:** CONFIRMED - Missing index
|
|
520
|
-
|
|
521
|
-
**Solution identified:** Add index on created_at
|
|
522
|
-
|
|
523
|
-
---
|
|
524
|
-
|
|
525
|
-
### Phase 5: Fix & Verify
|
|
526
|
-
|
|
527
|
-
**Fix:**
|
|
528
|
-
```sql
|
|
529
|
-
CREATE INDEX idx_transactions_created_at ON transactions(created_at);
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
**Verification:**
|
|
533
|
-
```sql
|
|
534
|
-
EXPLAIN ANALYZE SELECT * FROM transactions
|
|
535
|
-
WHERE created_at BETWEEN '2023-01-01' AND '2024-01-01';
|
|
536
|
-
|
|
537
|
-
-- Result: Index Scan using idx_transactions_created_at (cost=0.29..8.53)
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
**Test results:**
|
|
541
|
-
- 1 year report: 3s (was >30s) ✅
|
|
542
|
-
- 2 year report: 6s ✅
|
|
543
|
-
- Full history: 12s ✅
|
|
544
|
-
|
|
545
|
-
**Regression test added:** ✅
|
|
546
|
-
|
|
547
|
-
---
|
|
548
|
-
|
|
549
|
-
### Summary
|
|
550
|
-
- **Root cause:** Missing database index on transactions.created_at
|
|
551
|
-
- **Fix:** Added index
|
|
552
|
-
- **Time to fix:** 2 hours
|
|
553
|
-
- **Prevention:** Add query performance tests to CI
|
|
74
|
+
| H1 | Missing index | Seq scan in EXPLAIN | Low | 1st |
|
|
75
|
+
| H2 | N+1 query | Loop in code | Low | 2nd |
|
|
76
|
+
| H3 | Memory leak | Gradual increase | High | 3rd |
|
|
554
77
|
```
|
|
555
78
|
|
|
556
79
|
## Best Practices
|
|
557
80
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
-
|
|
574
|
-
- Don't skip the reproduction step
|
|
575
|
-
- Don't test multiple hypotheses at once
|
|
576
|
-
- Don't ignore intermittent bugs
|
|
577
|
-
- Don't fix symptoms instead of root cause
|
|
578
|
-
- Don't forget to remove debug code
|
|
579
|
-
- Don't skip the verification step
|
|
580
|
-
- Don't assume cause without evidence
|
|
581
|
-
- Don't keep debugging if stuck (escalate)
|
|
582
|
-
- Don't forget to document the fix
|
|
583
|
-
|
|
584
|
-
## References
|
|
585
|
-
|
|
586
|
-
- [Debugging: The 9 Indispensable Rules](https://www.amazon.com/Debugging-Indispensable-Software-Hardware-Problems/dp/0814474578)
|
|
587
|
-
- [Why Programs Fail](https://www.whyprogramsfail.com/)
|
|
588
|
-
- [Chrome DevTools Documentation](https://developer.chrome.com/docs/devtools/)
|
|
589
|
-
- [Git Bisect](https://git-scm.com/docs/git-bisect)
|
|
81
|
+
| Do | Avoid |
|
|
82
|
+
|----|-------|
|
|
83
|
+
| Always reproduce before debugging | Debugging without reproduction |
|
|
84
|
+
| Write down hypotheses before testing | Testing multiple hypotheses at once |
|
|
85
|
+
| Use binary search for large codebases | Random code changes |
|
|
86
|
+
| Write failing test before fixing | Assuming cause without evidence |
|
|
87
|
+
| Document the debugging session | Ignoring intermittent bugs |
|
|
88
|
+
| Add logging strategically | Keeping debug code in production |
|
|
89
|
+
| Check for related issues | Fixing symptoms instead of root cause |
|
|
90
|
+
|
|
91
|
+
## Related Skills
|
|
92
|
+
|
|
93
|
+
- `solving-problems` - 5-phase problem-solving framework
|
|
94
|
+
- `tracing-root-causes` - 5 Whys and Fishbone analysis
|
|
95
|
+
- `avoiding-testing-anti-patterns` - Prevent flaky tests
|
|
96
|
+
- `verifying-before-completion` - Ensure fix is complete
|