Asi refactoring-playbook
git clone https://github.com/plurigrid/asi
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/refactoring-playbook" ~/.claude/skills/plurigrid-asi-refactoring-playbook && rm -rf "$T"
skills/refactoring-playbook/SKILL.mdRefactoring & Migration Playbook
This playbook guides missions involving code modernization, architecture migrations, dependency upgrades, or large-scale refactoring. The core challenge: change implementation while preserving behavior.
Key Principle: Tests Before Changes
Refactoring without tests is just changing code and hoping. Before modifying any code:
- If tests exist: ensure they pass and cover the behavior you're changing
- If tests are missing: add characterization tests that capture current behavior first
Milestone Strategy: Incremental Safe Transformation
Structure milestones around safe transformation phases:
- characterization - Add tests capturing current behavior (if missing)
- scaffold - Set up new patterns/infrastructure alongside old (strangler fig)
- migrate-batch-N - Migrate components incrementally, tests pass after each batch
- cutover - Switch to new implementation, remove old code
- cleanup - Remove scaffolding, polish
Each batch is one milestone. Never "big bang" - always small, verifiable steps where tests pass after each commit.
Worker Types
Refactoring missions use workers that coordinate through shared state in
.factory/library/.
characterization-worker
Adds tests for existing behavior before any changes.
- Read
to understand what's being migratedmigration-plan.md - Identify code paths that lack test coverage
- Write characterization tests that capture current behavior (not ideal behavior)
- Update
with test coverage statusmigration-status.md
Tests must pass against current code. These tests become the safety net for migration.
scaffold-worker
Sets up new infrastructure to coexist with old (strangler fig pattern).
- Read
for target architecture/patternsmigration-plan.md - Create new modules/infrastructure alongside existing code
- Set up adapters/facades so old code can gradually switch to new
- Update
with scaffold statusmigration-status.md
Old tests must still pass. New infrastructure should be testable but not yet used.
migration-worker
Migrates specific components from old to new implementation.
- Read
to find next component to migratemigration-status.md - Migrate ONE component/module (keep scope small)
- Update call sites to use new implementation
- Run full test suite - must pass before completing
- Update
marking component as migratedmigration-status.md
Each migration is one atomic commit. If tests fail, fix or revert - never leave broken.
verification-worker
Ensures behavior is preserved across the migration.
- Read
to understand what changedmigration-status.md - Run full test suite including characterization tests
- Perform manual verification of migrated functionality
- Compare old vs new behavior for edge cases
- Document any behavioral differences found
Information Flow
characterization-worker ──writes──▶ migration-status.md (test coverage) │ ▼ reads scaffold-worker ──writes──▶ migration-status.md (scaffold ready) │ ▼ reads migration-worker ──writes──▶ migration-status.md (component X migrated) │ ▼ reads verification-worker ──writes──▶ migration-status.md (batch verified)
Each worker:
- Reads migration-plan.md and migration-status.md before starting
- Ensures all tests pass before marking work complete
- Updates migration-status.md after completing
Orchestrator Setup
Before starting migration, create:
-
:.factory/library/migration-plan.md- Current state (what exists now)
- Target state (what we're migrating to)
- Scope (what's included, what's explicitly excluded)
- Approach (strangler fig, parallel run, etc.)
- Risk areas (complex logic, external dependencies)
-
:.factory/library/migration-status.md- Components list with status (pending, in-progress, migrated, verified)
- Test coverage status
- Scaffold status
- Issues/blockers discovered
-
- Ensure.factory/services.yaml
command runs full suitetest
Feature Structure
Characterization Phase
characterize-<area> (characterization-worker) - Add tests for <area>
Scaffold Phase
scaffold-<component> (scaffold-worker) - Set up new <component> alongside old
Migration Batches
migrate-<component> (migration-worker) - Migrate <component> to new implementation verify-batch-N (verification-worker) - Verify batch N preserves behavior
Cutover & Cleanup
cutover-<area> (migration-worker) - Remove old <area>, switch fully to new cleanup-<area> (migration-worker) - Remove adapters, polish
Example Worker Skill: migration-worker
--- name: migration-worker description: Migrate components from old to new implementation incrementally. --- # Migration Worker ## Procedure 1. **Read status** - Check `migration-plan.md` and `migration-status.md`. Identify your assigned component. Return to orchestrator if scaffold not ready. 2. **Understand the component** - Read current implementation. Identify all call sites. Note edge cases and error handling. 3. **Migrate incrementally**: - Update component to use new patterns/infrastructure - Update call sites one at a time - Run tests after each change - Keep changes in atomic commits 4. **Verify** - Run full test suite. All tests must pass. 5. **Update status** in `migration-status.md`:
UserService
Status: MIGRATED Commit: abc123 Changes: Migrated from class to functional, now uses new data layer Call sites updated: 12 Tests: All 47 tests pass
## Example Handoff
{ "salientSummary": "Migrated UserService to the functional pattern and updated 12 call sites; ran
npm test (47 passing) and updated .factory/library/migration-status.md with the MIGRATED status + commit.",
"whatWasImplemented": "Migrated UserService from class-based to functional pattern. Updated 12 call sites. All 47 existing tests pass.",
"verification": {
"commandsRun": [
{"command": "npm test", "exitCode": 0, "observation": "47 tests pass"},
{"command": "grep 'Status: MIGRATED' .factory/library/migration-status.md", "exitCode": 0, "observation": "Status updated"}
]
}
}
## Return to Orchestrator When - Scaffold not ready for this component - Tests fail and fix is non-trivial - Migration reveals architectural issue requiring plan change - Component has undocumented dependencies
Common Pitfalls
- Changing behavior during migration - Refactoring changes structure, not behavior. Behavior changes are separate features.
- Big bang migrations - Each commit should leave tests passing. Never batch multiple components.
- Skipping characterization - Without tests capturing current behavior, you can't verify preservation.
- Incomplete call site updates - Use grep/find-references to ensure all usages are updated.
- Not updating migration status - Next worker needs to know what's done.
- Mixing refactoring with features - Keep them separate. Refactor first, then add features.
When to Stop
- Complete - All components migrated, verified, old code removed
- Blocked - Discovered issue requiring architectural decision
- Scope change - User decides to adjust what's being migrated