This is a strict debugging workflow. Use it when dealing with bugs, test failures, or unexpected behavior.
There are three core objectives.
- Fix the cause, not the symptom.
- Prevent guess-based fixes.
- Pin down the failure with a test, then fix it.
Hard Gates
Follow the following rules without exception.
- Do not fix anything before creating a reproducible or observable state.
- Do not fix anything before stating a hypothesis about the cause.
- Do not fix anything before creating a failing test or an equivalent reproduction device.
- Verify only one hypothesis at a time.
- When fixing, "while I'm here" refactoring is prohibited.
- If a fix attempt fails 3 times, suspect a structural problem before applying additional patches.
Violating this process is considered a debugging failure.
When To Use
Use this skill in the following situations.
- When a test fails
- When a bug occurs in production or locally
- When responses, states, rendering, or query results differ from expectations
- When investigating performance degradation, timeouts, race conditions, or intermittent failures
- When something has already been fixed one or more times but broke again
The following excuses are not allowed.
- "It looks simple, so I can just fix it right away"
- "There's no time, so let's just patch it for now"
- "It seems like this, so let's just try changing it"
Required Output Contract
When using this skill, internally always pin down the following items.
- Problem statement: Define in one sentence what is wrong
- Reproduction path: How to reproduce or observe the failure
- Evidence: Actual observed result
- Root-cause hypothesis: Why you think this problem occurs
- Failing guard: One of a failing test, reproduction script, or log verification
- Fix: A single fix for the cause
- Verification: The reproduction path and related test results after the fix
If any of these 7 items is missing, the work is not finished yet.
Workflow
Always proceed in the following order.
Phase 1. Define The Problem
First, narrow down the problem.
- What is the actual expected behavior
- What is the actual observed behavior
- What is the scope of impact
- Does it always reproduce, or is it intermittent
Output format:
Problem: <expected> but got <actual> under <condition>
Do not mix symptoms and guesses.
Good: Product detail API returns 500 when brand is null.
Bad: Serializer is broken because brand mapping seems wrong.
Phase 2. Reproduce Or Instrument
You must be able to see the failure again before fixing it.
Priority:
- Reproduce with an existing test
- Reproduce with a minimal integration test
- Reproduce with a unit test
- Observe with a reproduction script or command
- Observe after adding logs/instrumentation
Rules:
- Make the reproduction path as small as possible.
- Even if a bug is visible only in the UI, prefer reproducing it at a lower layer if possible.
- For intermittent failures, add logs, inputs, time, and concurrency conditions to increase observability.
- If it is not reproduced, do not move on to a fix; increase the means of observation.
What to do in a non-reproducible state:
- Record input values
- Check environment differences
- Check recent changes
- Add logs at each boundary point
- Search for a smaller condition that produces the same symptom
Phase 3. Gather Evidence
Gather only observable facts.
Always check:
- Full error message and stack trace
- Failing input values
- Recently changed files or commits
- Environment/configuration differences
- Call path and data flow
For multi-component problems, check at each boundary.
Example:
- controller -> application -> service -> repository
- client -> API -> external service
- scheduler -> batch service -> database
At each boundary, check:
- What came in
- What went out
- Which value was transformed
- Under which conditions only does it break
Do not fix before pinpointing the problem location.
Phase 4. Isolate Root Cause
Establish only one candidate cause.
Format:
Hypothesis: <root cause> because <evidence>
Conditions for a good hypothesis:
- Points to a single cause
- Connects to observed evidence
- Can be disproven by a small experiment
Examples of bad hypotheses:
- "There seems to be some kind of async problem somewhere"
- "The entire serialization side seems unstable"
Trace the cause back to the source. If the error appears deep in the stack, trace the origin of the input, not the symptom.
Phase 5. Lock The Failure
Pin down the failure before fixing.
Priority:
- Automated failing test
- Add a regression case to existing tests
- Minimal reproduction script
- Temporary verification mechanism based on logs/assertions
Rules:
- Create an automated test if possible.
- It must fail before the fix.
- After the fix, it must pass on the same path.
- The test name must reveal what broke.
If an automated test can be used, test-driven-development use the skill together.
Phase 6. Implement A Single Fix
A fix addresses only one hypothesis.
Allowed:
- Minimal code change that directly addresses the cause
- Minimal auxiliary fix needed for verification
Forbidden:
- Bundling multiple seemingly related fixes
- Refactoring combined with a fix
- Inserting formatting/cleanup/renaming
- Adding unfounded null-guard
- Swallowing exceptions
If it fails, immediately return to Phase 1 or Phase 3. This means the previous hypothesis was wrong.
Phase 7. Verify And Close
You may finish only when all of the following are satisfied.
- The original reproduction path no longer fails.
- The new failing guard passes.
- Related tests do not break.
- It is possible to explain that the fix blocks the cause, not the symptom.
If it is an intermittent bug, do not finish after a single pass. Verification under repeated execution or changed conditions is necessary.
Stop Conditions
If the following situation occurs, stop and reframe.
1. Reproduction Failed
If it cannot be reproduced even after several attempts:
- Check whether observation means are insufficient.
- Check whether there is an environmental difference.
- Check whether the problem definition is wrong.
Changing code when it cannot be reproduced is forbidden.
2. Three Failed Fixes
If fixes miss three times in a row, judge as follows.
- The current understanding is wrong, or
- the problem is highly likely a structural problem such as shared state, boundary design, or separation of responsibilities
From this point on, structural discussion is needed, not a "fourth patch."
3. No Failing Guard
If you cannot create a failing test or an equivalent reproduction device, do not declare completion. At minimum, leave the reproduction command and observation results.
Red Flags
If the following thought occurs, stop immediately and return to the previous step.
- "It seems like it would work if I just change this line"
- "Let's look at the logs later and just try fixing it for now"
- "I'll just add the test later"
- "Let's fix this and that together at once"
- "The error disappeared, so it's fine even if I don't know the cause"
Minimal Checklist
During execution, verify yourself based on the checklist below.
- Defined the problem in one sentence
- Reproduced the failure or made it observable
- Collected evidence
- Created a single-cause hypothesis
- Created a failure guard before the fix
- Applied only a single fix
- Verified after the fix through the same path
Completion Standard
The completion criterion of this skill is not "the code changed."
Completion criteria:
- The problem definition is clear
- The failure was pinned down before the fix
- The fix is connected to the cause
- Verification results remain
Without these four, debugging is not finished.