claude-mpm 4.17.0__py3-none-any.whl → 4.18.0__py3-none-any.whl
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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +48 -17
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/mcp_config_manager.py +2 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/utils/agent_dependency_loader.py +2 -2
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/METADATA +68 -1
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/RECORD +47 -24
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill_id: systematic-debugging
|
|
3
|
+
skill_version: 0.1.0
|
|
4
|
+
description: Structured approach to identifying and fixing bugs efficiently, eliminating redundant debugging guidance per agent.
|
|
5
|
+
updated_at: 2025-10-30T17:00:00Z
|
|
6
|
+
tags: [debugging, troubleshooting, problem-solving, best-practices]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Systematic Debugging
|
|
10
|
+
|
|
11
|
+
Structured approach to identifying and fixing bugs efficiently. Eliminates ~300-400 lines of redundant debugging guidance per agent.
|
|
12
|
+
|
|
13
|
+
## Core Debugging Principles
|
|
14
|
+
|
|
15
|
+
### 1. Debug First Protocol (MANDATORY)
|
|
16
|
+
|
|
17
|
+
Before writing ANY fix or optimization:
|
|
18
|
+
1. **Check System Outputs:** Review logs, network requests, error messages
|
|
19
|
+
2. **Identify Root Cause:** Investigate actual failure point, not symptoms
|
|
20
|
+
3. **Implement Simplest Fix:** Solve root cause with minimal code change
|
|
21
|
+
4. **Test Core Functionality:** Verify fix works WITHOUT optimization layers
|
|
22
|
+
5. **Optimize If Measured:** Add performance improvements only after metrics prove need
|
|
23
|
+
|
|
24
|
+
### 2. Root Cause Over Symptoms
|
|
25
|
+
|
|
26
|
+
- Debug the actual failing operation, not its side effects
|
|
27
|
+
- Trace errors to their source before adding workarounds
|
|
28
|
+
- Question whether the problem is where you think it is
|
|
29
|
+
|
|
30
|
+
### 3. Simplicity Before Complexity
|
|
31
|
+
|
|
32
|
+
- Start with the simplest solution that correctly solves the problem
|
|
33
|
+
- Advanced patterns/libraries are rarely the answer to basic problems
|
|
34
|
+
- If a solution seems complex, you probably haven't found the root cause
|
|
35
|
+
|
|
36
|
+
## The Debugging Process
|
|
37
|
+
|
|
38
|
+
### Step 1: Reproduce Reliably
|
|
39
|
+
|
|
40
|
+
**Goal:** Create a minimal, reproducible test case
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Questions to answer:
|
|
44
|
+
- Does it happen every time or intermittently?
|
|
45
|
+
- What are the exact steps to reproduce?
|
|
46
|
+
- What is the minimal input that triggers it?
|
|
47
|
+
- Which environment variables matter?
|
|
48
|
+
- What's the smallest code example that shows the bug?
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Example:**
|
|
52
|
+
```python
|
|
53
|
+
# Minimal reproduction
|
|
54
|
+
def test_bug_reproduction():
|
|
55
|
+
# Simplest case that demonstrates the bug
|
|
56
|
+
result = problematic_function(edge_case_input)
|
|
57
|
+
assert result == expected_output # Currently fails
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Step 2: Isolate the Problem
|
|
61
|
+
|
|
62
|
+
**Strategy:** Binary search through code/data
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Isolation techniques:
|
|
66
|
+
1. Comment out half the code - does bug persist?
|
|
67
|
+
2. Add logging at midpoints to narrow down location
|
|
68
|
+
3. Test with minimal data set
|
|
69
|
+
4. Remove external dependencies one by one
|
|
70
|
+
5. Test in clean environment (new VM, fresh install)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Example:**
|
|
74
|
+
```python
|
|
75
|
+
# Add strategic logging to isolate
|
|
76
|
+
def complex_operation(data):
|
|
77
|
+
logger.debug(f"Input: {data}") # Checkpoint 1
|
|
78
|
+
|
|
79
|
+
processed = process_step_1(data)
|
|
80
|
+
logger.debug(f"After step 1: {processed}") # Checkpoint 2
|
|
81
|
+
|
|
82
|
+
validated = validate_step_2(processed)
|
|
83
|
+
logger.debug(f"After step 2: {validated}") # Checkpoint 3
|
|
84
|
+
|
|
85
|
+
return finalize_step_3(validated)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 3: Form and Test Hypotheses
|
|
89
|
+
|
|
90
|
+
**Process:** Scientific method for debugging
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
For each hypothesis:
|
|
94
|
+
1. State clearly: "I believe X is causing Y because Z"
|
|
95
|
+
2. Predict: "If my hypothesis is true, then..."
|
|
96
|
+
3. Test: Design experiment to confirm/refute
|
|
97
|
+
4. Observe: Record actual results
|
|
98
|
+
5. Conclude: Was hypothesis correct?
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Example:**
|
|
102
|
+
```python
|
|
103
|
+
# Hypothesis: The bug is caused by integer overflow
|
|
104
|
+
|
|
105
|
+
# Prediction: Using larger integer type will fix it
|
|
106
|
+
# Test:
|
|
107
|
+
def test_hypothesis_integer_overflow():
|
|
108
|
+
# Original (fails)
|
|
109
|
+
result_int32 = calculate_with_int32(large_number)
|
|
110
|
+
|
|
111
|
+
# Modified (should work if hypothesis correct)
|
|
112
|
+
result_int64 = calculate_with_int64(large_number)
|
|
113
|
+
|
|
114
|
+
# Compare
|
|
115
|
+
print(f"Int32 result: {result_int32}") # Overflowed?
|
|
116
|
+
print(f"Int64 result: {result_int64}") # Correct?
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Step 4: Verify the Fix
|
|
120
|
+
|
|
121
|
+
**Checklist before committing:**
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
✓ Original bug is fixed
|
|
125
|
+
✓ No new bugs introduced
|
|
126
|
+
✓ Edge cases handled
|
|
127
|
+
✓ Tests added to prevent regression
|
|
128
|
+
✓ Code is simpler, not more complex
|
|
129
|
+
✓ Performance is acceptable
|
|
130
|
+
✓ Documentation updated if needed
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Debugging Tools and Techniques
|
|
134
|
+
|
|
135
|
+
### Print Debugging (Strategic Logging)
|
|
136
|
+
|
|
137
|
+
**When to use:** Quick investigation, unfamiliar codebase
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
# Strategic logging points
|
|
141
|
+
def complex_algorithm(data):
|
|
142
|
+
# 1. Input validation
|
|
143
|
+
logger.debug(f"Input received: {data}")
|
|
144
|
+
|
|
145
|
+
# 2. Before transformation
|
|
146
|
+
logger.debug(f"Before processing: {data}")
|
|
147
|
+
|
|
148
|
+
result = expensive_operation(data)
|
|
149
|
+
|
|
150
|
+
# 3. After transformation
|
|
151
|
+
logger.debug(f"After processing: {result}")
|
|
152
|
+
|
|
153
|
+
# 4. Before return
|
|
154
|
+
logger.debug(f"Returning: {result}")
|
|
155
|
+
|
|
156
|
+
return result
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Best practices:**
|
|
160
|
+
- Include variable names and values
|
|
161
|
+
- Log at decision points (if/else branches)
|
|
162
|
+
- Use structured logging for filtering
|
|
163
|
+
- Remove debugging logs after fixing
|
|
164
|
+
|
|
165
|
+
### Interactive Debugging (Debugger)
|
|
166
|
+
|
|
167
|
+
**When to use:** Complex bugs, need to inspect state
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
# Python (pdb)
|
|
171
|
+
import pdb
|
|
172
|
+
|
|
173
|
+
def problematic_function(x, y):
|
|
174
|
+
result = x + y
|
|
175
|
+
pdb.set_trace() # Execution pauses here
|
|
176
|
+
return result * 2
|
|
177
|
+
|
|
178
|
+
# Commands:
|
|
179
|
+
# n - next line
|
|
180
|
+
# s - step into function
|
|
181
|
+
# c - continue execution
|
|
182
|
+
# p variable - print variable
|
|
183
|
+
# l - list code around current line
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
// JavaScript (Node.js)
|
|
188
|
+
function problematicFunction(x, y) {
|
|
189
|
+
const result = x + y;
|
|
190
|
+
debugger; // Execution pauses here when DevTools open
|
|
191
|
+
return result * 2;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Error Message Analysis
|
|
196
|
+
|
|
197
|
+
**Read error messages carefully - they tell you exactly what's wrong**
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
Example error:
|
|
201
|
+
TypeError: Cannot read property 'name' of undefined
|
|
202
|
+
at getUserName (user.js:15:20)
|
|
203
|
+
at processUser (app.js:42:10)
|
|
204
|
+
|
|
205
|
+
Information extracted:
|
|
206
|
+
1. Error type: TypeError (type-related issue)
|
|
207
|
+
2. Specific problem: accessing 'name' property
|
|
208
|
+
3. Root cause: object is undefined
|
|
209
|
+
4. Location: user.js line 15, column 20
|
|
210
|
+
5. Call stack: originated in processUser()
|
|
211
|
+
|
|
212
|
+
Next steps:
|
|
213
|
+
- Check why object is undefined at that point
|
|
214
|
+
- Add null check or ensure object exists
|
|
215
|
+
- Trace back to where object should be created
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Binary Search Through Code
|
|
219
|
+
|
|
220
|
+
**For intermittent bugs or "it stopped working"**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Git bisect - find commit that introduced bug
|
|
224
|
+
git bisect start
|
|
225
|
+
git bisect bad # Current version has bug
|
|
226
|
+
git bisect good v1.2.0 # This version was working
|
|
227
|
+
# Git checks out middle commit
|
|
228
|
+
# Test if bug exists
|
|
229
|
+
git bisect bad # if bug exists
|
|
230
|
+
git bisect good # if bug doesn't exist
|
|
231
|
+
# Repeat until bug commit found
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Rubber Duck Debugging
|
|
235
|
+
|
|
236
|
+
**Explain the problem out loud (to a rubber duck, colleague, or yourself)**
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
Process:
|
|
240
|
+
1. State what the code is supposed to do
|
|
241
|
+
2. Explain what it actually does
|
|
242
|
+
3. Walk through the code line by line
|
|
243
|
+
4. Often, the act of explaining reveals the bug
|
|
244
|
+
|
|
245
|
+
Why it works:
|
|
246
|
+
- Forces you to be precise
|
|
247
|
+
- Reveals assumptions
|
|
248
|
+
- Highlights inconsistencies
|
|
249
|
+
- Activates different brain regions
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Common Bug Categories and Solutions
|
|
253
|
+
|
|
254
|
+
### Null/Undefined Reference Errors
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
# Problem: Accessing property of None/null/undefined
|
|
258
|
+
user.name # Crashes if user is None
|
|
259
|
+
|
|
260
|
+
# Solutions:
|
|
261
|
+
# 1. Guard clause
|
|
262
|
+
if user is None:
|
|
263
|
+
return default_name
|
|
264
|
+
return user.name
|
|
265
|
+
|
|
266
|
+
# 2. Optional chaining (languages that support it)
|
|
267
|
+
return user?.name ?? default_name
|
|
268
|
+
|
|
269
|
+
# 3. Early validation
|
|
270
|
+
def process_user(user):
|
|
271
|
+
if user is None:
|
|
272
|
+
raise ValueError("User cannot be None")
|
|
273
|
+
return user.name
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Off-by-One Errors
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
# Problem: Loop runs one too many or too few times
|
|
280
|
+
for i in range(len(array)):
|
|
281
|
+
process(array[i+1]) # IndexError on last iteration!
|
|
282
|
+
|
|
283
|
+
# Solutions:
|
|
284
|
+
# 1. Adjust range
|
|
285
|
+
for i in range(len(array) - 1):
|
|
286
|
+
process(array[i+1])
|
|
287
|
+
|
|
288
|
+
# 2. Better iteration
|
|
289
|
+
for current, next_item in zip(array, array[1:]):
|
|
290
|
+
process(next_item)
|
|
291
|
+
|
|
292
|
+
# 3. Test boundaries explicitly
|
|
293
|
+
def test_boundary_conditions():
|
|
294
|
+
assert process_array([]) == expected_empty
|
|
295
|
+
assert process_array([1]) == expected_single
|
|
296
|
+
assert process_array([1, 2]) == expected_pair
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Race Conditions
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
# Problem: Order of operations matters
|
|
303
|
+
shared_counter = 0
|
|
304
|
+
|
|
305
|
+
def increment():
|
|
306
|
+
# Read-modify-write is not atomic!
|
|
307
|
+
temp = shared_counter
|
|
308
|
+
temp += 1
|
|
309
|
+
shared_counter = temp
|
|
310
|
+
|
|
311
|
+
# Solutions:
|
|
312
|
+
# 1. Use locks
|
|
313
|
+
import threading
|
|
314
|
+
lock = threading.Lock()
|
|
315
|
+
|
|
316
|
+
def increment():
|
|
317
|
+
with lock:
|
|
318
|
+
shared_counter += 1
|
|
319
|
+
|
|
320
|
+
# 2. Use atomic operations
|
|
321
|
+
from threading import atomic
|
|
322
|
+
counter = atomic.AtomicInteger(0)
|
|
323
|
+
counter.increment()
|
|
324
|
+
|
|
325
|
+
# 3. Avoid shared state
|
|
326
|
+
def increment(counter):
|
|
327
|
+
return counter + 1 # Pure function
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Memory Leaks
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
# Problem: Objects not being garbage collected
|
|
334
|
+
class Cache:
|
|
335
|
+
def __init__(self):
|
|
336
|
+
self.data = {}
|
|
337
|
+
|
|
338
|
+
def store(self, key, value):
|
|
339
|
+
self.data[key] = value # Never removed!
|
|
340
|
+
|
|
341
|
+
# Solutions:
|
|
342
|
+
# 1. Explicit cleanup
|
|
343
|
+
def store(self, key, value, ttl=3600):
|
|
344
|
+
self.data[key] = (value, time.time() + ttl)
|
|
345
|
+
self._cleanup_expired()
|
|
346
|
+
|
|
347
|
+
# 2. Use weak references
|
|
348
|
+
import weakref
|
|
349
|
+
self.data = weakref.WeakValueDictionary()
|
|
350
|
+
|
|
351
|
+
# 3. Limit cache size
|
|
352
|
+
from functools import lru_cache
|
|
353
|
+
@lru_cache(maxsize=128)
|
|
354
|
+
def expensive_function(arg):
|
|
355
|
+
pass
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Debugging Anti-Patterns
|
|
359
|
+
|
|
360
|
+
### ❌ Random Changes (Hope-Driven Debugging)
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
# Bad: Changing things randomly
|
|
364
|
+
try:
|
|
365
|
+
result = function(x) # Doesn't work
|
|
366
|
+
# Try adding +1? Maybe that helps?
|
|
367
|
+
result = function(x + 1) # Still doesn't work
|
|
368
|
+
# Try multiplying by 2?
|
|
369
|
+
result = function(x * 2)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Better:** Understand why it's failing first, then make targeted fix.
|
|
373
|
+
|
|
374
|
+
### ❌ Cargo Cult Fixes
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
# Bad: Copying solutions without understanding
|
|
378
|
+
# "I found this on Stack Overflow"
|
|
379
|
+
time.sleep(0.1) # "Fixes" race condition by accident
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Better:** Understand the root cause and fix it properly.
|
|
383
|
+
|
|
384
|
+
### ❌ Debugging in Production
|
|
385
|
+
|
|
386
|
+
```python
|
|
387
|
+
# Bad: Testing theories on live system
|
|
388
|
+
if user.is_admin:
|
|
389
|
+
print("DEBUG: Admin access granted") # Left in production!
|
|
390
|
+
grant_access()
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Better:** Reproduce locally, fix, test, then deploy.
|
|
394
|
+
|
|
395
|
+
### ❌ Ignoring Warnings
|
|
396
|
+
|
|
397
|
+
```python
|
|
398
|
+
# Bad: Suppressing warnings without investigation
|
|
399
|
+
import warnings
|
|
400
|
+
warnings.filterwarnings("ignore") # What could go wrong?
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Better:** Address the root cause of warnings.
|
|
404
|
+
|
|
405
|
+
## Advanced Debugging Techniques
|
|
406
|
+
|
|
407
|
+
### Time-Travel Debugging
|
|
408
|
+
|
|
409
|
+
Record execution and replay it:
|
|
410
|
+
```python
|
|
411
|
+
# Python: Use `python -m pdb -cc script.py` for post-mortem debugging
|
|
412
|
+
# JavaScript: Use Chrome DevTools recording
|
|
413
|
+
# Rust: Use rr (record and replay)
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Performance Profiling for Bug-Finding
|
|
417
|
+
|
|
418
|
+
```python
|
|
419
|
+
import cProfile
|
|
420
|
+
import pstats
|
|
421
|
+
|
|
422
|
+
# Profile code to find bottlenecks
|
|
423
|
+
profiler = cProfile.Profile()
|
|
424
|
+
profiler.enable()
|
|
425
|
+
|
|
426
|
+
slow_function()
|
|
427
|
+
|
|
428
|
+
profiler.disable()
|
|
429
|
+
stats = pstats.Stats(profiler)
|
|
430
|
+
stats.sort_stats('cumtime')
|
|
431
|
+
stats.print_stats(10) # Top 10 slowest functions
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Memory Profiling
|
|
435
|
+
|
|
436
|
+
```python
|
|
437
|
+
# Python: memory_profiler
|
|
438
|
+
from memory_profiler import profile
|
|
439
|
+
|
|
440
|
+
@profile
|
|
441
|
+
def memory_intensive_function():
|
|
442
|
+
large_list = [i for i in range(1000000)]
|
|
443
|
+
return sum(large_list)
|
|
444
|
+
|
|
445
|
+
# Run: python -m memory_profiler script.py
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## Quick Debugging Checklist
|
|
449
|
+
|
|
450
|
+
When you encounter a bug:
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
□ Can you reproduce it reliably?
|
|
454
|
+
□ Have you read the error message completely?
|
|
455
|
+
□ Have you checked the logs?
|
|
456
|
+
□ Is it the code or the data?
|
|
457
|
+
□ Have you tested with minimal input?
|
|
458
|
+
□ Have you isolated the failing component?
|
|
459
|
+
□ Have you checked recent changes (git log)?
|
|
460
|
+
□ Have you verified your assumptions?
|
|
461
|
+
□ Have you tried explaining it out loud?
|
|
462
|
+
□ Have you checked for common issues (null, off-by-one, race condition)?
|
|
463
|
+
□ Have you written a test that demonstrates the bug?
|
|
464
|
+
□ Does the fix address the root cause, not the symptom?
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Remember
|
|
468
|
+
|
|
469
|
+
- **Correctness before performance** - Fast but wrong is always worse than slow but correct
|
|
470
|
+
- **Simplest fix first** - Complex solutions are often solving the wrong problem
|
|
471
|
+
- **Test your assumptions** - The bug is usually in code you're "sure" is correct
|
|
472
|
+
- **Read the error message** - It tells you exactly what's wrong
|
|
473
|
+
- **One change at a time** - Change multiple things and you won't know what fixed it
|