
systematic-type-migration
by cipherstash
SKILL.md
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
Systematic Type Migration
Overview
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
The Problem
Recurring issue during major refactoring:
- Old component definitions remain in the codebase
- Some files spawn entities with old types
- Other files query for new types
- Systems become disconnected (queries find zero entities)
- User functionality breaks despite all systems being "properly registered"
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.
The Workflow
Phase 1: Preparation
Step 1: Document the change
- Create work directory (e.g.,
docs/work/YYYY-MM-DD-type-safe-X) - Document scope and goals
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
- Write test that exercises full user flow (not just isolated system behavior)
- Test should verify end-to-end functionality
- This test MUST pass before starting AND after completion
Step 4: Run baseline tests
- Run project test command
- Run project check command
- Capture baseline to compare against
Phase 2: Implementation
Step 1: Create new component
- Implement in canonical location (e.g.,
src/components/movement/states.rs) - Include all required derives
Step 2: Do NOT delete old component yet
- Keep both during migration
- Enables gradual migration without breaking everything
- Allows atomic commits per file
Phase 3: Migration (Systematic, File-by-File)
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
- Pattern matching if enum variants changed
- Entity spawning to use new type
- Queries to use new type
Step 3: Test after each file
cargo check # Or language-specific quick check
- Catch type errors immediately
- Don't accumulate errors across files
Step 4: Commit atomically
git add path/to/file.rs
git commit -m "refactor: migrate FileX to new ComponentName"
- One commit per file or logical group
- Enables easy rollback if needed
Common file locations to check:
- Entity spawning files (e.g.,
setup.rs,spawners.rs) - System logic files (business logic using the component)
- UI display files (rendering component state)
- Component definition files
- Integration test files
Phase 4: Cleanup
Step 1: Delete old component definition
- Remove from original module
- Only after ALL references migrated
Step 2: Remove obsolete imports
# Find unused imports
cargo clippy -- -W unused_imports
Step 3: Remove obsolete helper code
- Builder functions
- Conversion utilities
- Deprecated APIs
Step 4: Update exports
- Remove old type from
mod.rspublic API - Ensure new type properly exported
Phase 5: Verification
Step 1: Compile clean
cargo check --all-targets
# Or language-specific equivalent
Step 2: Run all tests
Run project test command
- All unit tests must pass
- All integration tests must pass
Step 3: Verify integration test passes
- The test created in Phase 1 MUST pass
- This verifies end-to-end functionality
Step 4: Run checks
Run project check command
- Linting, formatting, type checking
Step 5: Manual testing
- Test actual user flows
- Verify UI updates correctly
- Check edge cases
Phase 6: Documentation
Step 1: Update pattern docs
- If new pattern emerged, document it
Step 2: Document in retrospective
- Capture lessons learned in work directory
- Note any pitfalls encountered
Step 3: Update project docs
- If pattern is important, reference from CLAUDE.md or README
Key Principles
| 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 |
Prevention: Integration Tests
The best prevention is integration tests that verify the full user flow, not just isolated system behavior.
What Makes a Good Integration Test
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:
- Spawn entities with ALL required components (like real usage)
- Exercise multiple systems together (full pipeline)
- Verify user-visible outcome, not internal state
- Use realistic component combinations
Common Mistakes
Mistake 1: Skipping Integration Test
Problem: Discover breakage during manual testing (too late) Solution: Write integration test FIRST, watch it pass LAST
Mistake 2: Big-Bang Migration
Problem: Migrate all files at once, giant debug session when it fails
Solution: File-by-file with cargo check after each
Mistake 3: Deleting Old Type Too Early
Problem: Can't compile during migration, hard to debug Solution: Keep both until migration complete
Mistake 4: Batching Commits
Problem: Hard to identify which change broke tests Solution: Atomic commits per file
Mistake 5: Testing Only Units
Problem: Units pass, integration broken (components incompatible) Solution: Integration test MUST exercise full user flow
Example Workflow
# 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
Related Practices
Before using this skill:
- Read:
${CLAUDE_PLUGIN_ROOT}principles/development.md- Code structure principles - Read:
${CLAUDE_PLUGIN_ROOT}principles/testing.md- Testing principles
After migration:
- Use:
${CLAUDE_PLUGIN_ROOT}skills/requesting-code-review/SKILL.md- Request code review
Testing This Skill
See test-scenarios.md for pressure tests validating this workflow prevents integration breakage.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon