Expert Debugging & Lint Fixing
Overview
This skill provides a systematic debugging playbook for extremely hard bugs that teams struggle to fix. It focuses on reproducing and isolating bugs through hypothesis-driven experiments, fixing root causes, explicitly resolving lint issues and static analysis findings in touched code, and adding tests and guardrails to prevent regressions.
When to Use This Skill
Use this skill for:
- Complex bugs that were not solved by normal debugging approaches
- Flaky or intermittent failures that are difficult to reproduce
- Production-only or environment-specific bugs
- Cases where code changes also need to be lint-clean and align with project lint rules
- Bugs requiring systematic investigation with measurable progress
- Heisenbugs that change behavior when being debugged
- Performance issues, race conditions, or data corruption bugs
Core Principles
Follow these principles throughout the debugging process:
- Always define a precise bug contract: "Given X, expect A, got B"
- Prioritize reproducibility before attempting to fix: If it cannot be reproduced, the current task is to make it reproducible
- Use hypothesis-driven debugging, not random code edits: Each change must test a specific hypothesis
- Aggressively shrink the search space: Use divide-and-conquer to isolate the failure
- Treat lint and static analysis violations as bugs: These must be resolved in changed areas
- Finish with root-cause prevention, not just symptom fixes: Add systemic guardrails to prevent recurrence
Step-by-Step Debugging Protocol
1. Frame the Problem Precisely
Convert vague bug reports into a precise bug contract that can be verified.
Actions:
- State the bug as: "Given state X and input Y, expected A, got B"
- Capture all relevant context:
- Who: Which user/role/environment
- What: Exact behavior observed
- When: Timing/frequency/conditions
- Where: Component/service/layer
- How often: Always/intermittent/once
- Since when: Recent change or longstanding issue
- Identify the primary symptom and impact (user-visible, data corruption, performance degradation, security risk)
- Write one precise sentence describing the bug
Gate: If the bug cannot be stated in one precise sentence, do not touch code yet. Continue refining the problem statement.
2. Make It Reproducible (or Tightest Approximation)
Create the smallest, fastest, most reliable reproduction case possible.
Actions:
- Start from the real failing path (same API/UI/job and environment if possible)
- Strip down to the smallest input + environment that still fails
- Turn this into a script, unit test, or integration test that can be re-run
- For flaky bugs:
- Run in a loop (100+ iterations)
- Log every run with timestamps and relevant state
- Capture failing cases for analysis
- Look for patterns (timing, resource usage, specific inputs)
- Document the repro steps clearly
Gate: If the bug is not reproducible, the current task is: make it reproducible. Do not proceed until there is a way to trigger the failure on demand or with high probability.
3. Add/Improve Observability
Ensure logs, metrics, and traces illuminate the failing path.
What to log:
- Key parameters and branch decisions at each step
- External calls (database, cache, HTTP, queue operations)
- Concurrency boundaries (locks acquired/released, queues, async operations)
- State transitions and invariant checks
- Timing information (timestamps, durations)
Logging quality:
- Each log should answer: "What did we know? What did we decide? What happened next?"
- If logs are noisy and uninformative, refine them as part of the fix
- Use structured logging with correlation IDs to track requests through the system
- Include context that helps differentiate between different executions
4. Shrink the Search Space
Use systematic techniques to narrow down where the bug occurs.
Binary search on time:
- Use
git bisect between known-good and known-bad commits
- Identify the exact commit that introduced the bug
Binary search on code path:
- Temporarily short-circuit sections or use feature flags to disable blocks
- See if the bug disappears when specific code paths are bypassed
Isolate layers:
- Replace real dependencies with fakes/mocks
- Try in-process vs over-the-network variants
- Test with minimal/maximal configurations
Evaluation criteria:
- Each step must move the bug closer or farther
- Avoid inconclusive changes that provide no information
- Document what each experiment revealed
5. Classify the Bug Type
Understanding the bug category dictates which tools and experiments to run next.
Bug categories:
- Logic: Wrong condition, off-by-one error, incorrect algorithm
- Data: Bad/inconsistent records, violated invariants, corrupted state
- Environment/config: Environment variables, version mismatches, feature flags
- Concurrency/race: Shared mutable state, timing-dependent behavior, deadlocks
- Performance: Memory leaks, excessive CPU usage, inefficient algorithms
- Integration: API contract violations, dependency issues, protocol errors
Actions:
- Identify the most likely category based on symptoms
- Select appropriate debugging tools for that category
- Prepare specific experiments to confirm or rule out the classification
6. Hypothesis-Driven Experiments
Conduct systematic experiments to identify the root cause.
Process:
- List top hypotheses (3–5 most likely causes)
- For each hypothesis, define:
- "If this is the cause, then doing X should produce observable Y"
- How to test it (minimal change, log addition, config tweak)
- What outcome would falsify it
- Run minimal, fast experiments to falsify hypotheses
- Discard falsified hypotheses quickly; don't cling to favorite theories
- After each experiment, explicitly state:
- What was tested
- What was observed
- What was learned
- Which hypotheses remain viable
Avoid:
- Testing multiple hypotheses at once (confounds results)
- Making large changes without clear predictions
- Confirmation bias (looking only for evidence that supports preferred theory)
7. Use the Right Tools (Including Linters)
Select debugging tools appropriate for the bug type.
For logic bugs:
- Debuggers with breakpoints, conditional breakpoints, watchpoints
- Print debugging with strategic log placement
- Unit tests that isolate specific functions
For performance/leak issues:
- Profilers (CPU, memory, I/O)
- Memory leak detectors
- Performance monitoring tools
For concurrency issues:
- Thread sanitizers
- Race condition detectors
- Stress testing with high parallelism
For all bugs:
- Run all relevant linter and static analysis tools on:
- The changed files
- Ideally the impacted module/package
- Tools include: ESLint, Flake8, mypy, Pylint, go vet, clippy, custom linters
- Treat new or existing lint violations in the changed area as part of the work to fix
8. Handle Flaky and Heisenbugs
For bugs that appear/disappear unpredictably, use amplification techniques.
Amplify the bug:
- Run repro in tight loops (1000+ iterations)
- Run in parallel with multiple processes
- Run under stress (high CPU/memory/disk usage)
- Introduce jitter and delays to surface race conditions
- Use chaos engineering techniques (network delays, packet loss, resource constraints)
Capture evidence:
- Take snapshots/dumps on detected bad states if tools allow
- Correlate logs/traces/metrics with unique request or correlation ID
- Record timing information to identify patterns
- Save state before/after failure for comparison
Reduce noise:
- Disable unrelated jobs/traffic/features to simplify
- Use minimal test data
- Isolate the system under test from external dependencies
9. Implement the Fix
Make the smallest, clearest change that eliminates the failing behavior.
Fix quality criteria:
- Eliminates the failing behavior in the repro case
- Respects the system's invariants and constraints
- Maintains or improves code clarity
- Does not introduce new bugs or performance issues
- Aligns with team coding standards
Approach:
- Prefer refactors that increase clarity over patchy hacks
- Keep commits focused and well-described for easy review
- Include comments explaining non-obvious aspects
- Consider edge cases and boundary conditions
- Update any affected documentation
Before committing:
- Verify the fix resolves the original bug
- Check for unintended side effects
- Ensure the fix doesn't just move the problem elsewhere
10. Validation: Tests, Lint, and CI
Ensure the fix is complete and won't regress.
Test the fix:
- Turn the repro into an automated test that fails on the old code
- Confirm:
- The new test fails on the pre-fix commit
- The new test passes on the fix
- Add negative/edge-case tests around the bug
- Test related functionality for regressions
Lint and static analysis:
- Run the full lint suite relevant to the project
- Fix all lint issues in the changed files
- Do not ignore or suppress lint errors unless there is a clear, documented reason
- Ensure static analysis tools pass (type checkers, security scanners)
CI validation:
- Run the existing test suite (or at least impacted subset)
- Ensure all CI checks pass (build, tests, linting, security scans)
- Verify no new warnings are introduced
- Check that code coverage hasn't decreased
11. Root Cause Analysis & Systemic Prevention
Prevent similar bugs from occurring in the future.
Write a root cause summary:
- When was the bug introduced? (specific commit/release)
- When was it detected? (how long did it exist?)
- Why was it not caught earlier? (gaps in testing, code review, monitoring)
- What was the underlying cause? (not just the symptom)
Conduct "5 Whys" analysis:
- Why did the bug occur? (immediate cause)
- Why did that happen? (contributing factor)
- Why was that possible? (system weakness)
- Why wasn't this caught? (process gap)
- Why does this pattern exist? (root cause)
Add systemic guardrails:
- New tests (unit, integration, property-based, regression)
- Stronger validation and type checks
- Runtime invariant assertions
- Lint rules or static checks that catch similar issues early (when possible)
- Monitoring/alerting to detect similar failures
- Documentation updates (architecture docs, code comments, runbooks)
- Code review checklist items for this module
Share learnings:
- Update team documentation
- Present findings in team meetings
- Add to incident postmortem if applicable
12. Team Protocol for "Impossible Bugs"
When escalating difficult bugs to the team, provide comprehensive context.
Required information:
- One-sentence bug contract ("Given X, expect A, got B")
- Repro script or test that demonstrates the failure
- Logs/metrics/traces for a failing run
- Top hypotheses and experiments tried with outcomes
- Relevant commit range and config/environment diffs
- Impact assessment (severity, affected users, workarounds)
Escalation gate:
- Use this checklist as a gate before escalating to senior engineers
- Ensures sufficient investigation has been done
- Provides context for effective collaboration
Linting and Static Analysis Protocol
Linting and static analysis are integral to the debugging process, not optional cleanup.
Always Run Relevant Tools
For every file modified during debugging:
- Run all relevant linters (language-specific and project-specific)
- Run static analyzers (type checkers, security scanners)
- Run code formatters if the project uses them
Common tools by language:
- JavaScript/TypeScript: ESLint, Prettier, TSLint
- Python: Flake8, Pylint, Black, mypy, Bandit
- Go: go vet, golint, staticcheck
- Rust: clippy, rustfmt
- Java: CheckStyle, SpotBugs, PMD
- Ruby: RuboCop
- C/C++: clang-tidy, cppcheck
Fix Lint Issues
What to fix:
- All newly introduced lint issues (from the changes made)
- Existing lint issues in the touched code region (where feasible)
- Critical security or correctness issues flagged by static analysis
When to suppress:
Only suppress or relax lint rules when:
- There is a clear, written justification
- The justification is documented in a code comment
- Preferable to update configuration rather than scattered inline disables
- The team agrees this is an appropriate exception
Never:
- Ignore lint errors by disabling the linter
- Commit code with unresolved lint violations without justification
- Suppress entire categories of checks without review
Treat Passing Lint as Part of "Done"
A bug fix is not complete until:
- The bug is fixed
- Tests are added
- All lint checks pass
- CI pipeline is green
Example Usage
Example 1: Flaky CI Test
User prompt: "We have a flaky test in our CI that fails randomly on our Node service. Help us track it down and fix it."
How this skill applies:
- Frame the problem: Identify which test fails, under what conditions, and how frequently
- Make it reproducible: Run the test in a loop locally (1000+ iterations), capture failing cases
- Add observability: Add detailed logging around the failing assertions, log timing information
- Shrink search space: Isolate the test from others, run with minimal fixtures
- Classify: Likely a race condition or timing issue
- Hypothesize: Test hypotheses like "async operation not awaited", "shared state between tests", "timing-dependent assertion"
- Use tools: Run with stress testing, check for race conditions
- Fix: Add proper awaits, isolate test state, or fix timing assumptions
- Validate: Ensure test passes 10,000+ times in a row, run ESLint/Prettier on changed files
- Prevent: Add test isolation guards, document async patterns
Example 2: Production 500 Errors
User prompt: "Production is throwing intermittent 500s on checkout; logs are unclear. Guide me through reproducing and fixing this."
How this skill applies:
- Frame the problem: "Given checkout request with cart X, expect 200 OK, got 500 Internal Server Error"
- Make it reproducible:
- Gather production logs with correlation IDs
- Identify common patterns in failing requests
- Create test with similar cart composition/state
- Add observability:
- Enhance logging in checkout flow
- Log all external service calls (payment, inventory)
- Log state transitions
- Shrink search space:
- Test each checkout step in isolation
- Mock external services to identify which dependency causes failures
- Classify: Likely an integration issue (external service) or data issue (bad cart state)
- Hypothesize: Test theories like "payment service timeout", "inventory service race condition", "invalid cart state"
- Fix: Add proper error handling, validate cart state earlier, implement retry logic
- Validate: Run lint tools on modified files, add integration tests for edge cases
- Prevent: Add input validation, monitoring alerts for 500s, circuit breakers for external services
Example 3: Lint Violations After Quick Patch
User prompt: "I applied a quick patch to stop a crash, but now our linter is complaining all over that file."
How this skill applies:
- Re-evaluate the patch: Check if the quick fix actually addresses the root cause or just the symptom
- Frame the original problem: Define what crash was occurring and why
- Improve the implementation:
- Refactor the patch to follow code standards
- Address the root cause properly, not just the symptom
- Fix lint issues:
- Run linter and address all violations in the file
- Do not suppress the linter without justification
- Ensure the fix follows team coding standards
- Validate: Add tests that prove the crash is fixed, ensure lint passes
- Prevent: Add guardrails to prevent similar crashes, document the fix
Example 4: Memory Leak in Long-Running Service
User prompt: "Our API service's memory usage grows unbounded over days. Find and fix the leak."
How this skill applies:
- Frame the problem: "After X hours of operation, memory usage reaches Y GB and service crashes"
- Make it reproducible:
- Create load test that simulates days of traffic in minutes
- Monitor memory usage during test
- Add observability:
- Add memory profiling
- Log object creation/destruction for suspected components
- Classify: Memory leak (performance bug)
- Use tools:
- Memory profilers (heapdump, valgrind, etc.)
- Analyze heap snapshots over time
- Hypothesize: Test theories like "event listeners not removed", "cache growing unbounded", "circular references"
- Fix: Remove event listeners, add cache eviction, break circular references
- Validate:
- Run extended load test, verify memory stays stable
- Run linter on changed files
- Add regression test that monitors memory growth
- Prevent: Add memory monitoring alerts, document lifecycle management patterns
Related Skills
This skill focuses on systematically debugging hard bugs. For related tasks, use:
- test-specialist: Writing comprehensive tests after fixing bugs (TDD approach, test coverage analysis)
- code-validation: Validating fixes don't introduce red flags (secrets, test disabling, security issues)
- test-quality-audit: Auditing test quality after adding regression tests
- test-standards: Ensuring test code follows project standards
- webapp-testing: Browser-based debugging and E2E test creation for web applications
- chrome-devtools: Browser performance debugging and Core Web Vitals measurement
Resources
This skill does not require bundled scripts, references, or assets. The debugging protocol is entirely procedural and can be applied to any programming language, framework, or bug type.
If language-specific debugging scripts or checklists would be helpful for your team's common debugging scenarios, they can be added to the scripts/ directory. Similarly, team-specific debugging runbooks or reference materials can be added to references/.
1---2name: expert-debugging-and-lint-fixing3description: Systematic debugging workflow to reproduce, isolate, and fix hard software bugs, resolve related lint issues, and add tests and guardrails to prevent regressions. This skill should be used for complex bugs that teams struggle to fix, flaky/intermittent failures, production-only bugs, and environment-specific issues where code changes must be lint-clean.4---5
6# Expert Debugging & Lint Fixing
7
8## Overview
9
10This skill provides a systematic debugging playbook for extremely hard bugs that teams struggle to fix. It focuses on reproducing and isolating bugs through hypothesis-driven experiments, fixing root causes, explicitly resolving lint issues and static analysis findings in touched code, and adding tests and guardrails to prevent regressions.
11
12## When to Use This Skill
13
14Use this skill for:
15
16- Complex bugs that were not solved by normal debugging approaches
17- Flaky or intermittent failures that are difficult to reproduce
18- Production-only or environment-specific bugs
19- Cases where code changes also need to be lint-clean and align with project lint rules
20- Bugs requiring systematic investigation with measurable progress
21- Heisenbugs that change behavior when being debugged
22- Performance issues, race conditions, or data corruption bugs
23
24## Core Principles
25
26Follow these principles throughout the debugging process:
27
28- **Always define a precise bug contract**: "Given X, expect A, got B"
29- **Prioritize reproducibility before attempting to fix**: If it cannot be reproduced, the current task is to make it reproducible
30- **Use hypothesis-driven debugging, not random code edits**: Each change must test a specific hypothesis
31- **Aggressively shrink the search space**: Use divide-and-conquer to isolate the failure
32- **Treat lint and static analysis violations as bugs**: These must be resolved in changed areas
33- **Finish with root-cause prevention, not just symptom fixes**: Add systemic guardrails to prevent recurrence
34
35## Step-by-Step Debugging Protocol
36
37### 1. Frame the Problem Precisely
38
39Convert vague bug reports into a precise bug contract that can be verified.
40
41**Actions:**
42- State the bug as: "Given state X and input Y, expected A, got B"
43- Capture all relevant context:
44 - Who: Which user/role/environment
45 - What: Exact behavior observed
46 - When: Timing/frequency/conditions
47 - Where: Component/service/layer
48 - How often: Always/intermittent/once
49 - Since when: Recent change or longstanding issue
50- Identify the primary symptom and impact (user-visible, data corruption, performance degradation, security risk)
51- Write one precise sentence describing the bug
52
53**Gate:** If the bug cannot be stated in one precise sentence, do not touch code yet. Continue refining the problem statement.
54
55### 2. Make It Reproducible (or Tightest Approximation)
56
57Create the smallest, fastest, most reliable reproduction case possible.
58
59**Actions:**
60- Start from the real failing path (same API/UI/job and environment if possible)
61- Strip down to the smallest input + environment that still fails
62- Turn this into a script, unit test, or integration test that can be re-run
63- For flaky bugs:
64 - Run in a loop (100+ iterations)
65 - Log every run with timestamps and relevant state
66 - Capture failing cases for analysis
67 - Look for patterns (timing, resource usage, specific inputs)
68- Document the repro steps clearly
69
70**Gate:** If the bug is not reproducible, the current task is: make it reproducible. Do not proceed until there is a way to trigger the failure on demand or with high probability.
71
72### 3. Add/Improve Observability
73
74Ensure logs, metrics, and traces illuminate the failing path.
75
76**What to log:**
77- Key parameters and branch decisions at each step
78- External calls (database, cache, HTTP, queue operations)
79- Concurrency boundaries (locks acquired/released, queues, async operations)
80- State transitions and invariant checks
81- Timing information (timestamps, durations)
82
83**Logging quality:**
84- Each log should answer: "What did we know? What did we decide? What happened next?"
85- If logs are noisy and uninformative, refine them as part of the fix
86- Use structured logging with correlation IDs to track requests through the system
87- Include context that helps differentiate between different executions
88
89### 4. Shrink the Search Space
90
91Use systematic techniques to narrow down where the bug occurs.
92
93**Binary search on time:**
94- Use `git bisect` between known-good and known-bad commits
95- Identify the exact commit that introduced the bug
96
97**Binary search on code path:**
98- Temporarily short-circuit sections or use feature flags to disable blocks
99- See if the bug disappears when specific code paths are bypassed
100
101**Isolate layers:**
102- Replace real dependencies with fakes/mocks
103- Try in-process vs over-the-network variants
104- Test with minimal/maximal configurations
105
106**Evaluation criteria:**
107- Each step must move the bug closer or farther
108- Avoid inconclusive changes that provide no information
109- Document what each experiment revealed
110
111### 5. Classify the Bug Type
112
113Understanding the bug category dictates which tools and experiments to run next.
114
115**Bug categories:**
116- **Logic**: Wrong condition, off-by-one error, incorrect algorithm
117- **Data**: Bad/inconsistent records, violated invariants, corrupted state
118- **Environment/config**: Environment variables, version mismatches, feature flags
119- **Concurrency/race**: Shared mutable state, timing-dependent behavior, deadlocks
120- **Performance**: Memory leaks, excessive CPU usage, inefficient algorithms
121- **Integration**: API contract violations, dependency issues, protocol errors
122
123**Actions:**
124- Identify the most likely category based on symptoms
125- Select appropriate debugging tools for that category
126- Prepare specific experiments to confirm or rule out the classification
127
128### 6. Hypothesis-Driven Experiments
129
130Conduct systematic experiments to identify the root cause.
131
132**Process:**
1331. List top hypotheses (3–5 most likely causes)
1342. For each hypothesis, define:
135 - "If this is the cause, then doing X should produce observable Y"
136 - How to test it (minimal change, log addition, config tweak)
137 - What outcome would falsify it
1383. Run minimal, fast experiments to falsify hypotheses
1394. Discard falsified hypotheses quickly; don't cling to favorite theories
1405. After each experiment, explicitly state:
141 - What was tested
142 - What was observed
143 - What was learned
144 - Which hypotheses remain viable
145
146**Avoid:**
147- Testing multiple hypotheses at once (confounds results)
148- Making large changes without clear predictions
149- Confirmation bias (looking only for evidence that supports preferred theory)
150
151### 7. Use the Right Tools (Including Linters)
152
153Select debugging tools appropriate for the bug type.
154
155**For logic bugs:**
156- Debuggers with breakpoints, conditional breakpoints, watchpoints
157- Print debugging with strategic log placement
158- Unit tests that isolate specific functions
159
160**For performance/leak issues:**
161- Profilers (CPU, memory, I/O)
162- Memory leak detectors
163- Performance monitoring tools
164
165**For concurrency issues:**
166- Thread sanitizers
167- Race condition detectors
168- Stress testing with high parallelism
169
170**For all bugs:**
171- Run all relevant linter and static analysis tools on:
172 - The changed files
173 - Ideally the impacted module/package
174- Tools include: ESLint, Flake8, mypy, Pylint, go vet, clippy, custom linters
175- **Treat new or existing lint violations in the changed area as part of the work to fix**
176
177### 8. Handle Flaky and Heisenbugs
178
179For bugs that appear/disappear unpredictably, use amplification techniques.
180
181**Amplify the bug:**
182- Run repro in tight loops (1000+ iterations)
183- Run in parallel with multiple processes
184- Run under stress (high CPU/memory/disk usage)
185- Introduce jitter and delays to surface race conditions
186- Use chaos engineering techniques (network delays, packet loss, resource constraints)
187
188**Capture evidence:**
189- Take snapshots/dumps on detected bad states if tools allow
190- Correlate logs/traces/metrics with unique request or correlation ID
191- Record timing information to identify patterns
192- Save state before/after failure for comparison
193
194**Reduce noise:**
195- Disable unrelated jobs/traffic/features to simplify
196- Use minimal test data
197- Isolate the system under test from external dependencies
198
199### 9. Implement the Fix
200
201Make the smallest, clearest change that eliminates the failing behavior.
202
203**Fix quality criteria:**
204- Eliminates the failing behavior in the repro case
205- Respects the system's invariants and constraints
206- Maintains or improves code clarity
207- Does not introduce new bugs or performance issues
208- Aligns with team coding standards
209
210**Approach:**
211- Prefer refactors that increase clarity over patchy hacks
212- Keep commits focused and well-described for easy review
213- Include comments explaining non-obvious aspects
214- Consider edge cases and boundary conditions
215- Update any affected documentation
216
217**Before committing:**
218- Verify the fix resolves the original bug
219- Check for unintended side effects
220- Ensure the fix doesn't just move the problem elsewhere
221
222### 10. Validation: Tests, Lint, and CI
223
224Ensure the fix is complete and won't regress.
225
226**Test the fix:**
227- Turn the repro into an automated test that fails on the old code
228- Confirm:
229 - The new test fails on the pre-fix commit
230 - The new test passes on the fix
231- Add negative/edge-case tests around the bug
232- Test related functionality for regressions
233
234**Lint and static analysis:**
235- Run the full lint suite relevant to the project
236- Fix all lint issues in the changed files
237- Do not ignore or suppress lint errors unless there is a clear, documented reason
238- Ensure static analysis tools pass (type checkers, security scanners)
239
240**CI validation:**
241- Run the existing test suite (or at least impacted subset)
242- Ensure all CI checks pass (build, tests, linting, security scans)
243- Verify no new warnings are introduced
244- Check that code coverage hasn't decreased
245
246### 11. Root Cause Analysis & Systemic Prevention
247
248Prevent similar bugs from occurring in the future.
249
250**Write a root cause summary:**
251- When was the bug introduced? (specific commit/release)
252- When was it detected? (how long did it exist?)
253- Why was it not caught earlier? (gaps in testing, code review, monitoring)
254- What was the underlying cause? (not just the symptom)
255
256**Conduct "5 Whys" analysis:**
2571. Why did the bug occur? (immediate cause)
2582. Why did that happen? (contributing factor)
2593. Why was that possible? (system weakness)
2604. Why wasn't this caught? (process gap)
2615. Why does this pattern exist? (root cause)
262
263**Add systemic guardrails:**
264- New tests (unit, integration, property-based, regression)
265- Stronger validation and type checks
266- Runtime invariant assertions
267- Lint rules or static checks that catch similar issues early (when possible)
268- Monitoring/alerting to detect similar failures
269- Documentation updates (architecture docs, code comments, runbooks)
270- Code review checklist items for this module
271
272**Share learnings:**
273- Update team documentation
274- Present findings in team meetings
275- Add to incident postmortem if applicable
276
277### 12. Team Protocol for "Impossible Bugs"
278
279When escalating difficult bugs to the team, provide comprehensive context.
280
281**Required information:**
2821. One-sentence bug contract ("Given X, expect A, got B")
2832. Repro script or test that demonstrates the failure
2843. Logs/metrics/traces for a failing run
2854. Top hypotheses and experiments tried with outcomes
2865. Relevant commit range and config/environment diffs
2876. Impact assessment (severity, affected users, workarounds)
288
289**Escalation gate:**
290- Use this checklist as a gate before escalating to senior engineers
291- Ensures sufficient investigation has been done
292- Provides context for effective collaboration
293
294## Linting and Static Analysis Protocol
295
296Linting and static analysis are integral to the debugging process, not optional cleanup.
297
298### Always Run Relevant Tools
299
300For every file modified during debugging:
301- Run all relevant linters (language-specific and project-specific)
302- Run static analyzers (type checkers, security scanners)
303- Run code formatters if the project uses them
304
305**Common tools by language:**
306- **JavaScript/TypeScript**: ESLint, Prettier, TSLint
307- **Python**: Flake8, Pylint, Black, mypy, Bandit
308- **Go**: go vet, golint, staticcheck
309- **Rust**: clippy, rustfmt
310- **Java**: CheckStyle, SpotBugs, PMD
311- **Ruby**: RuboCop
312- **C/C++**: clang-tidy, cppcheck
313
314### Fix Lint Issues
315
316**What to fix:**
317- All newly introduced lint issues (from the changes made)
318- Existing lint issues in the touched code region (where feasible)
319- Critical security or correctness issues flagged by static analysis
320
321**When to suppress:**
322Only suppress or relax lint rules when:
323- There is a clear, written justification
324- The justification is documented in a code comment
325- Preferable to update configuration rather than scattered inline disables
326- The team agrees this is an appropriate exception
327
328**Never:**
329- Ignore lint errors by disabling the linter
330- Commit code with unresolved lint violations without justification
331- Suppress entire categories of checks without review
332
333### Treat Passing Lint as Part of "Done"
334
335A bug fix is not complete until:
336- The bug is fixed
337- Tests are added
338- All lint checks pass
339- CI pipeline is green
340
341## Example Usage
342
343### Example 1: Flaky CI Test
344
345**User prompt:** "We have a flaky test in our CI that fails randomly on our Node service. Help us track it down and fix it."
346
347**How this skill applies:**
348
3491. **Frame the problem**: Identify which test fails, under what conditions, and how frequently
3502. **Make it reproducible**: Run the test in a loop locally (1000+ iterations), capture failing cases
3513. **Add observability**: Add detailed logging around the failing assertions, log timing information
3524. **Shrink search space**: Isolate the test from others, run with minimal fixtures
3535. **Classify**: Likely a race condition or timing issue
3546. **Hypothesize**: Test hypotheses like "async operation not awaited", "shared state between tests", "timing-dependent assertion"
3557. **Use tools**: Run with stress testing, check for race conditions
3568. **Fix**: Add proper awaits, isolate test state, or fix timing assumptions
3579. **Validate**: Ensure test passes 10,000+ times in a row, run ESLint/Prettier on changed files
35810. **Prevent**: Add test isolation guards, document async patterns
359
360### Example 2: Production 500 Errors
361
362**User prompt:** "Production is throwing intermittent 500s on checkout; logs are unclear. Guide me through reproducing and fixing this."
363
364**How this skill applies:**
365
3661. **Frame the problem**: "Given checkout request with cart X, expect 200 OK, got 500 Internal Server Error"
3672. **Make it reproducible**:
368 - Gather production logs with correlation IDs
369 - Identify common patterns in failing requests
370 - Create test with similar cart composition/state
3713. **Add observability**:
372 - Enhance logging in checkout flow
373 - Log all external service calls (payment, inventory)
374 - Log state transitions
3754. **Shrink search space**:
376 - Test each checkout step in isolation
377 - Mock external services to identify which dependency causes failures
3785. **Classify**: Likely an integration issue (external service) or data issue (bad cart state)
3796. **Hypothesize**: Test theories like "payment service timeout", "inventory service race condition", "invalid cart state"
3807. **Fix**: Add proper error handling, validate cart state earlier, implement retry logic
3818. **Validate**: Run lint tools on modified files, add integration tests for edge cases
3829. **Prevent**: Add input validation, monitoring alerts for 500s, circuit breakers for external services
383
384### Example 3: Lint Violations After Quick Patch
385
386**User prompt:** "I applied a quick patch to stop a crash, but now our linter is complaining all over that file."
387
388**How this skill applies:**
389
3901. **Re-evaluate the patch**: Check if the quick fix actually addresses the root cause or just the symptom
3912. **Frame the original problem**: Define what crash was occurring and why
3923. **Improve the implementation**:
393 - Refactor the patch to follow code standards
394 - Address the root cause properly, not just the symptom
3954. **Fix lint issues**:
396 - Run linter and address all violations in the file
397 - Do not suppress the linter without justification
398 - Ensure the fix follows team coding standards
3995. **Validate**: Add tests that prove the crash is fixed, ensure lint passes
4006. **Prevent**: Add guardrails to prevent similar crashes, document the fix
401
402### Example 4: Memory Leak in Long-Running Service
403
404**User prompt:** "Our API service's memory usage grows unbounded over days. Find and fix the leak."
405
406**How this skill applies:**
407
4081. **Frame the problem**: "After X hours of operation, memory usage reaches Y GB and service crashes"
4092. **Make it reproducible**:
410 - Create load test that simulates days of traffic in minutes
411 - Monitor memory usage during test
4123. **Add observability**:
413 - Add memory profiling
414 - Log object creation/destruction for suspected components
4154. **Classify**: Memory leak (performance bug)
4165. **Use tools**:
417 - Memory profilers (heapdump, valgrind, etc.)
418 - Analyze heap snapshots over time
4196. **Hypothesize**: Test theories like "event listeners not removed", "cache growing unbounded", "circular references"
4207. **Fix**: Remove event listeners, add cache eviction, break circular references
4218. **Validate**:
422 - Run extended load test, verify memory stays stable
423 - Run linter on changed files
424 - Add regression test that monitors memory growth
4259. **Prevent**: Add memory monitoring alerts, document lifecycle management patterns
426
427## Related Skills
428
429This skill focuses on systematically debugging hard bugs. For related tasks, use:
430
431- **test-specialist**: Writing comprehensive tests after fixing bugs (TDD approach, test coverage analysis)
432- **code-validation**: Validating fixes don't introduce red flags (secrets, test disabling, security issues)
433- **test-quality-audit**: Auditing test quality after adding regression tests
434- **test-standards**: Ensuring test code follows project standards
435- **webapp-testing**: Browser-based debugging and E2E test creation for web applications
436- **chrome-devtools**: Browser performance debugging and Core Web Vitals measurement
437
438## Resources
439
440This skill does not require bundled scripts, references, or assets. The debugging protocol is entirely procedural and can be applied to any programming language, framework, or bug type.
441
442If language-specific debugging scripts or checklists would be helpful for your team's common debugging scenarios, they can be added to the `scripts/` directory. Similarly, team-specific debugging runbooks or reference materials can be added to `references/`.