From xpowers
Guides systematic bug fixing: create issue, debug, write failing test, fix, verify, and close. Includes fix status classification.
How this skill is triggered — by the user, by Claude, or both
Slash command
/xpowers:fixing-bugsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<skill_overview>
<skill_overview> Bug fixing is a complete workflow: reproduce, track in bd, debug systematically, write test, fix, verify, close. Every bug gets a bd issue and regression test. </skill_overview>
<rigidity_level> LOW FREEDOM - Follow exact workflow: create bd issue → debug with tools → write failing test → fix → verify → close.
Never skip tracking or regression test. Use debugging-with-tools for investigation, test-driven-development for fix. </rigidity_level>
<quick_reference>
| Step | Action | Command/Skill |
|---|---|---|
| 1. Track | Create bd bug issue | tm create "Bug: [description]" --type bug |
| 2. Debug | Systematic investigation | Use debugging-with-tools skill |
| 3. Test (RED) | Write failing test reproducing bug | Use test-driven-development skill |
| 4. Fix (GREEN) | Implement fix | Minimal code to pass test |
| 5. Verify | Run full test suite | Use verification-before-completion skill |
| 6. Classify | Classify status and close | tm close bd-123 |
FORBIDDEN: Fix without bd issue, fix without regression test REQUIRED: Every bug gets tracked, tested, verified before closing
</quick_reference>
<fix_status_values>
After implementing a fix, classify its status:
| Status | Definition | Next Action |
|---|---|---|
| FIXED | Root cause addressed, regression test passes, full suite passes | Close bd issue |
| PARTIALLY_FIXED | Some aspects addressed, others remain | Document what's left, keep issue open |
| NOT_ADDRESSED | Fix doesn't address the actual bug | Return to debugging phase |
| CANNOT_DETERMINE | Insufficient info to verify fix | Gather more reproduction data |
Evidence required for each status:
<when_to_use> Use when you discover a bug:
Production emergencies: Abbreviated workflow OK (hotfix first), but still create bd issue and add regression tests afterward. </when_to_use>
<the_process>
Track from the start:
tm create "Bug: [Clear description]" --type bug --priority P1
# Returns: bd-123
Document:
tm update bd-123 --design "
## Bug Description
[What's wrong]
## Reproduction Steps
1. Step one
2. Step two
## Expected Behavior
[What should happen]
## Actual Behavior
[What actually happens]
## Environment
[Version, OS, etc.]"
REQUIRED: Use debugging-with-tools skill
Use Skill tool: xpowers:debugging-with-tools
debugging-with-tools will:
Update bd issue with findings:
tm update bd-123 --design "[previous content]
## Investigation
[Root cause found via debugging]
[Tools used: debugger, internet search, etc.]"
REQUIRED: Use test-driven-development skill
Write test that reproduces the bug:
def test_rejects_empty_email():
"""Regression test for bd-123: Empty email accepted"""
with pytest.raises(ValidationError):
create_user(email="") # Should fail, currently passes
Run test, verify it FAILS:
pytest tests/test_user.py::test_rejects_empty_email
# Expected: PASS (bug exists)
# Should fail AFTER fix
Why critical: If test passes before fix, it doesn't test the bug.
Fix the root cause (not symptom):
def create_user(email: str):
if not email or not email.strip(): # Fix
raise ValidationError("Email required")
# ... rest
Run test, verify it now FAILS (test was written backwards by mistake earlier - fix this):
Actually write the test to FAIL first:
def test_rejects_empty_email():
with pytest.raises(ValidationError):
create_user(email="")
Run:
pytest tests/test_user.py::test_rejects_empty_email
# Should FAIL before fix (no validation)
# Should PASS after fix (validation added)
REQUIRED: Use verification-before-completion skill
# Run full test suite (via test-runner agent)
"Run: pytest"
# Agent returns: All tests pass (including regression test)
Verify:
REQUIRED: Classify fix status before closing:
tm update bd-123 --design "[previous content]
## Fix Status: FIXED
**Evidence:**
- Root cause: [explanation of what caused the bug]
- Regression test: tests/test_user.py::test_rejects_empty_email PASSES
- Full suite: 145/145 tests pass
- Fix verified: [specific verification that bug is resolved]
## Fix Implemented
[Description of fix]
[File changed: src/auth/user.py:23]
## Regression Test
[Test added: tests/test_user.py::test_rejects_empty_email]"
tm close bd-123
If status is not FIXED:
Commit with bd reference:
git commit -m "fix(bd-123): Reject empty email in user creation
Adds validation to prevent empty strings.
Regression test: test_rejects_empty_email
Closes bd-123"
</the_process>
Developer fixes bug without creating bd issue or regression test
Developer notices: Empty email accepted in user creation
"Fixes" immediately:
def create_user(email: str):
if not email: # Quick fix
raise ValidationError("Email required")
Commits: "fix: validate email"
[No bd issue, no regression test]
<why_it_fails> No tracking:
No regression test:
Incomplete fix:
email=" " (whitespace)Result: Bug returns when someone changes validation logic. </why_it_fails>
**Complete workflow:**# 1. Track
tm create "Bug: Empty email accepted" --type bug
# Returns: bd-123
# 2. Debug (use debugging-with-tools)
# Investigation reveals: Email validation missing entirely
# Also: Whitespace emails like " " also accepted
# 3. Write failing test (RED)
def test_rejects_empty_email():
with pytest.raises(ValidationError):
create_user(email="")
def test_rejects_whitespace_email():
with pytest.raises(ValidationError):
create_user(email=" ")
# Run: Both PASS (bug exists) - WAIT, test should FAIL before fix!
Actually:
# Test currently PASSES (bug exists - no validation)
# We expect test to FAIL after we add validation
# 4. Fix
def create_user(email: str):
if not email or not email.strip():
raise ValidationError("Email required")
# 5. Verify
pytest # All tests pass now, including regression tests
# 6. Close
tm close bd-123
git commit -m "fix(bd-123): Reject empty/whitespace email"
Result: Bug fixed, tracked, tested, won't regress.
Developer writes test after fix, test passes immediately, doesn't catch regression
Developer fixes validation bug, then writes test:
# Fix first
def validate_email(email):
return "@" in email and len(email) > 0
# Then test
def test_validate_email():
assert validate_email("[email protected]") == True
Test runs: PASS
Commits both together.
Later, someone changes validation:
def validate_email(email):
return True # Breaks validation!
Test still PASSES (only checks happy path).
<why_it_fails> Test written after fix:
validate_email("@@") returns True (bug!)Why it happens: Skipping TDD RED phase. </why_it_fails>
**TDD approach (RED-GREEN):**# 1. Write test FIRST that reproduces the bug
def test_validate_email():
# Happy path
assert validate_email("[email protected]") == True
# Bug case (empty email was accepted)
assert validate_email("") == False
# Edge case discovered during debugging
assert validate_email("@@") == False
# 2. Run test - should FAIL (bug exists)
pytest test_validate_email
# FAIL: validate_email("") returned True, expected False
# 3. Implement fix
def validate_email(email):
if not email or len(email) == 0:
return False
return "@" in email and email.count("@") == 1
# 4. Run test - should PASS
pytest test_validate_email
# PASS: All assertions pass
Later regression:
def validate_email(email):
return True # Someone breaks it
Test catches it:
FAIL: assert validate_email("") == False
Expected False, got True
Result: Regression test actually prevents bug from returning.
Developer fixes symptom without using debugging-with-tools to find root cause
Bug report: "Application crashes when processing user data"
Error:
NullPointerException at UserService.java:45
Developer sees line 45:
String email = user.getEmail().toLowerCase(); // Line 45
"Obvious fix":
String email = user.getEmail() != null ? user.getEmail().toLowerCase() : "";
Bug "fixed"... but crashes continue with different data.
<why_it_fails> Symptom fix:
Actual root cause: User object created without email in registration flow. Email is null for all users created via broken endpoint.
Result: Null-check applied everywhere, root cause (broken registration) unfixed. </why_it_fails>
**Use debugging-with-tools skill:**# Dispatch internet-researcher
"Search for: NullPointerException UserService getEmail
- Common causes of null email in user objects
- User registration validation patterns"
# Dispatch codebase-investigator
"Investigate:
- How is User object created?
- Where is email set?
- Are there paths where email can be null?
- Which endpoints create users?"
# Agent reports:
"Found: POST /register endpoint creates User without validating email field.
Email is optional in UserDTO but required in User domain object."
Root cause found: Registration doesn't validate email.
Proper fix:
// In registration endpoint
@PostMapping("/register")
public User register(@RequestBody UserDTO dto) {
if (dto.getEmail() == null || dto.getEmail().isEmpty()) {
throw new ValidationException("Email required");
}
return userService.create(dto);
}
Regression test:
@Test
void registrationRequiresEmail() {
assertThrows(ValidationException.class, () ->
register(new UserDTO(null, "password")));
}
Result: Root cause fixed, no more null emails created.
<critical_rules>
Every bug gets a bd issue → Track from discovery to closure
Use debugging-with-tools skill → Systematic investigation required
Write failing test first (RED) → Regression prevention
Verify complete fix → Use verification-before-completion
All of these mean: Stop, follow complete workflow:
</critical_rules>
<verification_checklist>
Before claiming bug fixed:
</verification_checklist>
This skill calls:
This skill is called by:
Agents used:
When stuck:
npx claudepluginhub dpolishuk/xpowersCoordinates diagnosis, test-driven reproduction, root-cause analysis, and targeted fixes for bugs with regression testing.
Root cause based one-shot bug fix. Runs a full investigation pipeline: debugger diagnosis, gap analysis, requirements generation, execution, and verification. Includes QA suggestions after successful fix.