From declutter
Core skill for safe refactoring - enforces test-first approach and atomic changes
How this skill is triggered — by the user, by Claude, or both
Slash command
/declutter:declutter-safe-refactoringThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```
╔═══════════════════════════════════════════════════════════════════╗
║ NO STRUCTURAL CHANGE WITHOUT CHARACTERIZATION TEST FIRST ║
║ NO MULTIPLE CHANGES IN ONE COMMIT ║
║ NO PROCEEDING WITHOUT GREEN TESTS ║
╚═══════════════════════════════════════════════════════════════════╝
This is non-negotiable. There are no exceptions.
digraph safe_refactoring {
rankdir=LR;
node [shape=box];
test [label="1. Write/Verify\nCharacterization Test"];
green [label="2. Confirm\nTests Pass" shape=diamond];
change [label="3. Make ONE\nAtomic Change"];
run [label="4. Run Tests"];
pass [label="Tests Pass?" shape=diamond];
commit [label="5. Commit"];
next [label="Next Change?" shape=diamond];
done [label="Complete" shape=ellipse];
test -> green;
green -> change [label="GREEN"];
green -> test [label="RED - Fix first" style=dashed];
change -> run;
run -> pass;
pass -> commit [label="YES"];
pass -> change [label="NO - Revert" style=dashed color=red];
commit -> next;
next -> test [label="YES"];
next -> done [label="NO"];
}
| Excuse | Reality |
|---|---|
| "This code is simple, no test needed" | Simple code still breaks. 30 seconds to write a test. |
| "Multiple changes at once is faster" | Rollback impossible = debugging nightmare = MORE time |
| "I'll write tests after" | You won't. And when it breaks, you won't know why. |
| "The existing tests cover this" | Verify it. Run them. See them pass. Then proceed. |
| "This is just a rename" | Renames break things. Test first. |
| "I'm just moving code" | Moving code breaks imports. Test first. |
| "It's only formatting" | Use formatter. If logic change mixed in, test first. |
If you think any of these, you are about to make a mistake:
An atomic change is:
Examples of atomic changes:
NOT atomic (break these down):
Before ANY change, write a test that captures current behavior:
# Python example
def test_current_behavior_of_target_function():
"""Characterization test - captures current behavior before refactoring."""
# Arrange: Set up the exact state
input_data = create_typical_input()
# Act: Call the function being refactored
result = target_function(input_data)
# Assert: Verify current behavior (even if it seems wrong)
assert result == expected_current_output
# Document any edge cases discovered
assert target_function(edge_case_input) == edge_case_output
// TypeScript example
describe('target_function characterization', () => {
it('captures current behavior before refactoring', () => {
// Arrange
const input = createTypicalInput();
// Act
const result = targetFunction(input);
// Assert current behavior
expect(result).toEqual(expectedCurrentOutput);
});
});
Safe refactorings to apply ONE at a time:
Before committing any change:
- [ ] Characterization test exists for affected code
- [ ] All tests were GREEN before this change
- [ ] Only ONE atomic change was made
- [ ] All tests are GREEN after this change
- [ ] Change is independently revertable
- [ ] Commit message describes the single change
If tests fail after a change:
# Discard all uncommitted changes
git checkout -- .
# If already committed, revert
git revert HEAD
# Never force-push to fix mistakes
# Never --amend to hide failed attempts
Human: Refactor this 200-line function
Guides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
npx claudepluginhub joshuarweaver/cascade-code-general-misc-1 --plugin joowankim-declutter