From cc-arsenal
Safe codebase refactoring with characterization tests, incremental changes, and continuous verification. Automatically activates when users want to refactor code, extract methods/classes, simplify logic, reduce duplication, improve naming, restructure modules, or clean up technical debt.
npx claudepluginhub mgiovani/cc-arsenal --plugin cc-arsenal-teamsThis skill is limited to using the following tools:
Refactor code safely using characterization tests, incremental changes, and continuous verification. Every change preserves existing behavior while improving code structure, readability, and maintainability.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Refactor code safely using characterization tests, incremental changes, and continuous verification. Every change preserves existing behavior while improving code structure, readability, and maintainability.
$ARGUMENTS
CRITICAL: Refactoring changes code structure WITHOUT changing behavior. Every step must be verified against existing tests. If tests break, the refactoring introduced a bug — revert and retry.
This skill includes automatic refactoring verification before completion:
When attempting to stop working, an automated verification agent runs to ensure the refactoring is safe:
Verification Steps:
Behavior:
Example blocked completion:
⚠️ Refactoring verification failed:
Tests: ❌ FAILED (2 tests failing)
- test_calculate_total: Expected 150.0, got 150
- test_format_output: AssertionError: output format changed
Lint: ✅ PASSED
Type Check: ✅ PASSED
🔧 Refactoring introduced behavior changes. Revert the last change and retry
with a smaller step.
This skill uses Claude Code's Task Management System for strict sequential dependency tracking through the refactoring workflow.
When to Use Tasks:
When to Skip Tasks:
Task Structure: Refactoring creates a strict sequential chain where each phase must complete before the next can start, ensuring characterization tests exist before any structural changes begin.
Task tracking replaces TodoWrite. Create task chain at start, update as completing each phase.
Step 0.1: Create Task Dependency Chain
Before refactoring, create the strict sequential task structure:
TaskCreate:
subject: "Phase 0: Discover project workflow"
description: "Identify test, lint, type-check commands from CLAUDE.md and task runners"
activeForm: "Discovering project workflow"
TaskCreate:
subject: "Phase 1: Analyze refactoring scope"
description: "Map dependencies, callers, and test coverage for target code"
activeForm: "Analyzing refactoring scope"
TaskCreate:
subject: "Phase 2: Write characterization tests"
description: "Ensure sufficient test coverage before making structural changes"
activeForm: "Writing characterization tests"
TaskCreate:
subject: "Phase 3: Incremental refactoring"
description: "Apply refactoring in small verified steps"
activeForm: "Refactoring incrementally"
TaskCreate:
subject: "Phase 4: Final verification"
description: "Run full test suite, lint, type-check — confirm behavior preserved"
activeForm: "Verifying refactoring safety"
TaskCreate:
subject: "Phase 5: Final commit"
description: "Create conventional commit with refactoring summary"
activeForm: "Creating final commit"
# Set up strict sequential chain
TaskUpdate: { taskId: "2", addBlockedBy: ["1"] }
TaskUpdate: { taskId: "3", addBlockedBy: ["2"] }
TaskUpdate: { taskId: "4", addBlockedBy: ["3"] }
TaskUpdate: { taskId: "5", addBlockedBy: ["4"] }
TaskUpdate: { taskId: "6", addBlockedBy: ["5"] }
# Start first task
TaskUpdate: { taskId: "1", status: "in_progress" }
Step 0.2: Discover Project Workflow
Use Haiku-powered Explore agent for token-efficient discovery:
Use Task tool with Explore agent:
- prompt: "Discover the development workflow for this project:
1. Read CLAUDE.md if it exists - extract testing and quality conventions
2. Check for task runners: Makefile, justfile, package.json scripts, pyproject.toml scripts
3. Identify the test command (e.g., make test, just test, npm test, pytest, bun test)
4. Identify how to run a single test file or specific test
5. Identify the lint command (e.g., make lint, npm run lint, ruff check)
6. Identify the type-check command if applicable (e.g., pyright, tsc, mypy)
7. Note any pre-commit hooks or quality gates
8. Check for code coverage tooling (e.g., pytest --cov, nyc, c8)
Return a structured summary of all available commands."
- subagent_type: "Explore"
- model: "haiku" # Token-efficient for discovery
Store discovered commands for use in later phases.
Step 0.3: Run Baseline Tests
CRITICAL: Run the full test suite BEFORE making any changes. Record the results as the baseline. Every subsequent test run must match or exceed this baseline.
# Run full test suite and record results
[DISCOVERED_TEST_COMMAND]
If tests already fail before refactoring, document the pre-existing failures. These are not caused by the refactoring and should remain unchanged (same tests fail with same errors).
Step 0.4: Complete Phase 0
TaskUpdate: { taskId: "1", status: "completed" }
TaskList # Check that Task 2 is now unblocked
Goal: Understand the full impact of the refactoring before touching any code.
Step 1.1: Start Phase 1
TaskUpdate: { taskId: "2", status: "in_progress" }
Step 1.2: Parallel Scope Analysis
Spawn two Explore agents in parallel to map the refactoring scope:
Agent 1 - Dependency & Caller Analysis (Explore, Haiku):
prompt: "Analyze dependencies and callers for the refactoring target:
Refactoring target: [DESCRIBE TARGET CODE]
1. Read the target code — understand its current structure and public API
2. Find ALL callers and dependents using Grep:
- Direct function/method calls
- Import statements referencing the target
- Type references (if applicable)
- Configuration or dependency injection references
3. Map the dependency graph:
- What does the target depend on?
- What depends on the target?
- Are there circular dependencies?
4. Identify the public API surface:
- Which functions/methods/classes are called externally?
- Which are internal-only (safe to change freely)?
5. Note any dynamic references (string-based lookups, reflection, decorators)
Return:
- Complete caller list with file:line references
- Dependency graph (what depends on what)
- Public vs internal API surface
- Risks: dynamic references, external consumers, serialization"
subagent_type: "Explore"
model: "haiku"
Agent 2 - Test Coverage Analysis (Explore, Haiku):
prompt: "Analyze test coverage for the refactoring target:
Refactoring target: [DESCRIBE TARGET CODE]
1. Find ALL test files that test the target code:
- Unit tests directly testing target functions/classes
- Integration tests exercising the target indirectly
- E2E tests that flow through the target
2. For each test, note:
- What specific behavior it verifies
- Which code paths it exercises
- Which inputs and edge cases it covers
3. Identify GAPS in test coverage:
- Functions/methods with no tests
- Code branches not exercised (error paths, edge cases)
- Public API methods without direct test coverage
4. Check for test patterns:
- Test fixtures and helpers available
- Mocking patterns used in the project
- Test naming conventions
Return:
- List of test files with what they cover
- Coverage gaps requiring characterization tests
- Test patterns and fixtures available for reuse
- Risk areas: untested code paths that refactoring could break"
subagent_type: "Explore"
model: "haiku"
Step 1.3: Synthesize Analysis
After both agents complete, synthesize findings:
Step 1.4: Get Approval for Large Refactorings
If the refactoring involves: changes to >5 files, modifications to public APIs, moving code between modules, or changes affecting external consumers, use AskUserQuestion to present the scope analysis and get approval before proceeding.
Step 1.5: Complete Phase 1
TaskUpdate: { taskId: "2", status: "completed" }
TaskList # Check that Task 3 is now unblocked
Goal: Ensure sufficient test coverage exists to detect any behavioral change from the refactoring.
Step 2.1: Start Phase 2
TaskUpdate: { taskId: "3", status: "in_progress" }
Step 2.2: Assess Coverage Needs
Based on Phase 1 coverage analysis, determine which characterization tests are needed:
Step 2.3: Write Characterization Tests
For each coverage gap identified:
test_char_ or equivalent to distinguish characterization tests from behavioral testsExample characterization test (Python):
def test_char_calculate_total_with_discount():
"""Characterization: captures current discount calculation behavior."""
result = calculate_total(items=[100, 200], discount=0.1)
assert result == 270.0 # Current behavior: discount applied to sum
def test_char_calculate_total_empty_items():
"""Characterization: captures current behavior with empty input."""
result = calculate_total(items=[], discount=0.1)
assert result == 0.0
IMPORTANT: Characterization tests document CURRENT behavior, not desired behavior. If the current code has a quirk, the test captures that quirk. The refactoring must preserve it.
Step 2.4: Verify Characterization Tests
Run the full test suite (including new characterization tests). All must pass.
[DISCOVERED_TEST_COMMAND]
Step 2.5: Complete Phase 2
TaskUpdate: { taskId: "3", status: "completed" }
TaskList # Check that Task 4 is now unblocked
Goal: Apply the refactoring in small, verified steps. Each step must pass all tests.
Step 3.1: Start Phase 3
TaskUpdate: { taskId: "4", status: "in_progress" }
Step 3.2: Plan Incremental Steps
Break the refactoring into the smallest possible independent steps. Each step should be:
Common refactoring step sequences (see references/patterns.md for details):
| Refactoring Type | Step Sequence |
|---|---|
| Extract method | 1. Create new method with copied code → 2. Test → 3. Replace original with call → 4. Test |
| Extract class | 1. Create class with methods → 2. Test → 3. Delegate from original → 4. Test → 5. Update callers → 6. Test |
| Rename | 1. Add new name alongside old → 2. Test → 3. Update callers → 4. Test → 5. Remove old name → 6. Test |
| Move function | 1. Copy to destination → 2. Test → 3. Re-export from source → 4. Update callers → 5. Test → 6. Remove source → 7. Test |
| Simplify conditional | 1. Extract condition to named variable/method → 2. Test → 3. Simplify logic → 4. Test |
| Remove duplication | 1. Identify shared pattern → 2. Extract shared code → 3. Test → 4. Replace first usage → 5. Test → 6. Replace next usage → 7. Test |
Step 3.3: Execute Each Step
For EACH incremental step:
[DISCOVERED_TEST_COMMAND]
CRITICAL: Never skip the test run between steps. Never batch multiple steps before testing. The discipline of test-after-every-change is what makes refactoring safe.
Step 3.4: Handle Complex Refactorings
For refactorings spanning multiple files:
For refactorings requiring temporary duplication:
Step 3.5: Complete Phase 3
TaskUpdate: { taskId: "4", status: "completed" }
TaskList # Check that Task 5 is now unblocked
Step 4.1: Start Phase 4
TaskUpdate: { taskId: "5", status: "in_progress" }
Step 4.2: Run All Quality Checks
Run all quality checks using discovered commands from Phase 0.
Quality Gates Checklist:
If any check fails: Fix the issue before proceeding. Do not commit broken code. Keep task as in_progress until all gates pass.
Step 4.3: Review the Diff
Read the complete diff to verify only intentional changes exist:
git diff
Look for:
Step 4.4: Complete Phase 4
TaskUpdate: { taskId: "5", status: "completed" }
TaskList # Check that Task 6 is now unblocked
Step 5.1: Start Phase 5
TaskUpdate: { taskId: "6", status: "in_progress" }
Step 5.2: Create Commit
If /cc-arsenal:git:commit skill is available, use it. Otherwise, create a conventional commit manually:
git add [files modified]
git commit -m "refactor: [concise description of structural change]
- [What was restructured and why]
- [Key technique used: extract method, rename, simplify, etc.]
- [Impact: files changed, callers updated]
No behavioral changes."
Commit message guidelines for refactoring:
refactor: (always — this is a structural change, not a fix or feature)Step 5.3: Complete Phase 5 and Refactoring
TaskUpdate: { taskId: "6", status: "completed" }
TaskList # Show final status - all tasks should be completed
Report to the user with:
For detailed refactoring patterns, step sequences, and safety practices, see: