with one click
systematic-type-migration
// Safe refactoring workflow for replacing old types with new type-safe implementations through integration-test-first, file-by-file migration with incremental verification
// Safe refactoring workflow for replacing old types with new type-safe implementations through integration-test-first, file-by-file migration with incremental verification
Use boolean decision trees instead of imperatives for 100% compliance under pressure
Use when creating or developing, before writing code or implementation plans - refines rough ideas into fully-formed designs through collaborative questioning, alternative exploration, and incremental validation. Don't use during clear 'mechanical' processes
Use when completing tasks, implementing major features, or before merging to verify work meets requirements - dispatches cipherpowers:code-review-agent subagent to review implementation against plan or requirements before proceeding
Establish workflow boundary checklists with clear pass/fail criteria and escalation procedures
Use when you've developed a broadly useful skill and want to contribute it upstream via pull request - guides process of branching, committing, pushing, and creating PR to contribute skills back to upstream repository
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
| name | Systematic Type Migration |
| description | Safe refactoring workflow for replacing old types with new type-safe implementations through integration-test-first, file-by-file migration with incremental verification |
| when_to_use | when refactoring to new type-safe implementations, replacing components across codebase, migrating to new domain types |
| version | 1.0.0 |
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.