From cipherpowers
Guides safe, file-by-file migration from old types to new type-safe implementations using integration-test-first approach with incremental verification.
npx claudepluginhub cipherstash/cipherpowers --plugin cipherpowersThis skill uses the workspace's default tool permissions.
When refactoring components to new type-safe implementations, use this systematic workflow to prevent "works in isolation but broken integration" bugs.
Safely refactors codebases across multiple files: renames symbols/files/modules, extracts/inlines functions/components, moves/splits/merges files. Establishes type/test baseline, executes changes file-by-file, verifies no regressions, auto-reverts on failure.
Plans multi-file refactors with safe sequencing (types→impl→tests), affected files table, verifications, rollback steps, and risks. For complex codebase changes.
Guides Rust refactoring with diagnostic questions and transformations: simplify code, split large modules, remove forwarded parameters/feature flags, convert optional fields to enums.
Share bugs, ideas, or general feedback.
When refactoring components to new type-safe implementations, use this systematic workflow to prevent "works in isolation but broken integration" bugs.
Core principle: Integration test FIRST → file-by-file migration → incremental verification → cleanup
Recurring issue during major refactoring:
Example: After introducing type-safe MovementState enum, if setup.rs spawns entities with the old MovementState but planning.rs queries for the new MovementState, queries will silently fail.
Step 1: Document the change
docs/work/YYYY-MM-DD-type-safe-X)Step 2: Identify all uses
# Find all references to the type being replaced
grep -r "ComponentName" src/
rg "OldType" --type rust
Step 3: Create integration test FIRST
Step 4: Run baseline tests
Step 1: Create new component
src/components/movement/states.rs)Step 2: Do NOT delete old component yet
For EACH file using the old component:
Step 1: Update imports
// Before
use old_module::OldType;
// After
use new_module::NewType;
Step 2: Update type usage
Step 3: Test after each file
cargo check # Or language-specific quick check
Step 4: Commit atomically
git add path/to/file.rs
git commit -m "refactor: migrate FileX to new ComponentName"
Common file locations to check:
setup.rs, spawners.rs)Step 1: Delete old component definition
Step 2: Remove obsolete imports
# Find unused imports
cargo clippy -- -W unused_imports
Step 3: Remove obsolete helper code
Step 4: Update exports
mod.rs public APIStep 1: Compile clean
cargo check --all-targets
# Or language-specific equivalent
Step 2: Run all tests
Run project test command
Step 3: Verify integration test passes
Step 4: Run checks
Run project check command
Step 5: Manual testing
Step 1: Update pattern docs
Step 2: Document in retrospective
Step 3: Update project docs
| Principle | Rationale |
|---|---|
| Integration test FIRST | Prevents "works in parts, broken as whole" |
| Keep both during migration | Enables atomic commits per file |
| File-by-file, not all-at-once | Easier debugging, clear progress |
| Incremental verification | Catch errors immediately (5 min) vs batch (30+ min) |
| Atomic commits | Easy rollback if specific change breaks something |
The best prevention is integration tests that verify the full user flow, not just isolated system behavior.
Good integration test:
#[test]
fn test_user_can_move_vehicle() {
// Setup: Spawn entities with realistic component combinations
let world = setup_test_world();
let vehicle = spawn_vehicle_with_all_components(&mut world);
// Act: Trigger user action (click → select → move)
click_vehicle(&mut world, vehicle);
issue_move_order(&mut world, target_position);
// Assert: Verify end result, not internal state
run_systems_until_complete(&mut world);
assert!(vehicle_arrived_at_target(&world, vehicle));
}
Bad integration test:
#[test]
fn test_planning_system_queries() {
// Only tests one system in isolation
// Doesn't verify components are actually compatible
}
Integration test should:
Problem: Discover breakage during manual testing (too late) Solution: Write integration test FIRST, watch it pass LAST
Problem: Migrate all files at once, giant debug session when it fails
Solution: File-by-file with cargo check after each
Problem: Can't compile during migration, hard to debug Solution: Keep both until migration complete
Problem: Hard to identify which change broke tests Solution: Atomic commits per file
Problem: Units pass, integration broken (components incompatible) Solution: Integration test MUST exercise full user flow
# Phase 1: Preparation
mkdir -p docs/work/2025-10-23-type-safe-movement-state
grep -r "MovementState" src/ > docs/work/2025-10-23-type-safe-movement-state/references.txt
# Write integration test: tests/movement_integration.rs
# Run project test command to establish baseline
# Phase 2: Implementation
# Create src/components/movement/states.rs with new MovementState
# Keep old src/space/components.rs::MovementState
# Phase 3: Migration (file-by-file)
# File 1: src/space/systems/setup.rs
nvim src/space/systems/setup.rs # Update import, spawning
cargo check # Verify
git add src/space/systems/setup.rs
git commit -m "refactor: migrate setup.rs to new MovementState"
# File 2: src/space/systems/planning.rs
nvim src/space/systems/planning.rs # Update import, queries
cargo check # Verify
git add src/space/systems/planning.rs
git commit -m "refactor: migrate planning.rs to new MovementState"
# ... repeat for each file ...
# Phase 4: Cleanup
# Delete old MovementState from src/space/components.rs
git add src/space/components.rs
git commit -m "refactor: remove old MovementState definition"
# Phase 5: Verification
cargo check --all-targets
# Run project test command - integration test MUST pass
# Run project check command
# Manual testing
# Phase 6: Documentation
# Write docs/work/2025-10-23-type-safe-movement-state/summary.md
Before using this skill:
${CLAUDE_PLUGIN_ROOT}principles/development.md - Development principles (includes testing)After migration:
${CLAUDE_PLUGIN_ROOT}skills/requesting-code-review/SKILL.md - Request code reviewSee test-scenarios.md for pressure tests validating this workflow prevents integration breakage.