Migrate Operations
Comprehensive migration skill covering framework upgrades, language version bumps, dependency auditing, breaking change detection, codemods, and rollback strategies.
Ecosystem facts verified as of 2026-07-05.
Migration Strategy Decision Tree
What kind of migration are you performing?
│
├─ Small library update (patch/minor version)
│ └─ In-place upgrade
│ Update dependency, run tests, deploy
│
├─ Major framework version (React 18→19, Vue 2→3, Laravel 12→13)
│ │
│ ├─ Codebase < 50k LOC, good test coverage (>70%)
│ │ └─ Big Bang Migration
│ │ Upgrade everything at once in a feature branch
│ │ Pros: clean cutover, no dual-version complexity
│ │ Cons: high risk, long branch life, merge conflicts
│ │
│ ├─ Codebase > 50k LOC, partial test coverage
│ │ └─ Incremental Migration
│ │ Upgrade module by module, use compatibility layers
│ │ Pros: lower risk per step, continuous delivery
│ │ Cons: dual-version code, longer total duration
│ │
│ ├─ Monolith → microservice or complete architecture shift
│ │ └─ Strangler Fig Pattern
│ │ Route new features to new system, migrate old features gradually
│ │ Pros: zero-downtime, reversible, production-validated
│ │ Cons: routing complexity, data sync challenges
│ │
│ └─ High-risk data pipeline or financial system
│ └─ Parallel Run
│ Run old and new systems simultaneously, compare outputs
│ Pros: highest confidence, catch subtle differences
│ Cons: double infrastructure cost, comparison logic
│
└─ Language version upgrade (Python 3.12→3.14, Node 22→26)
└─ In-place upgrade with CI matrix
Test against both old and new versions in CI
Drop old version support once all tests pass
Framework Upgrade Decision Tree
Which framework are you upgrading?
│
├─ React 18 → 19
│ ├─ Check: Remove forwardRef wrappers (ref is now a regular prop)
│ ├─ Check: Replace <Context.Provider> with <Context>
│ ├─ Check: Adopt useActionState / useFormStatus for forms
│ ├─ Check: Replace manual memoization if using React Compiler
│ ├─ Codemod: npx codemod@latest react/19/migration-recipe
│ └─ Load: ./references/framework-upgrades.md
│
├─ Next.js Pages Router → App Router
│ ├─ Check: Move pages/ to app/ with new file conventions
│ ├─ Check: Replace getServerSideProps/getStaticProps with async components
│ ├─ Check: Convert _app.tsx and _document.tsx to layout.tsx
│ ├─ Check: Update data fetching to use fetch() with caching options
│ ├─ Codemod: npx @next/codemod@latest
│ └─ Load: ./references/framework-upgrades.md
│
├─ Vue 2 → 3
│ ├─ Check: Replace Options API with Composition API (optional but recommended)
│ ├─ Check: Replace Vuex with Pinia
│ ├─ Check: Replace event bus with mitt or provide/inject
│ ├─ Check: Update v-model syntax (modelValue prop)
│ ├─ Tool: Migration build (@vue/compat) for incremental migration
│ └─ Load: ./references/framework-upgrades.md
│
├─ Laravel 12 → 13
│ ├─ Check: PHP 8.3 is now the minimum (8.5 supported)
│ ├─ Check: Cache/Redis key prefixes now use hyphenated suffixes
│ ├─ Check: Adopt native PHP attributes (models, jobs, controllers) — optional
│ ├─ Check: Queue routing by class via Queue::route(...) — optional
│ ├─ Tool: laravel shift (automated upgrade service)
│ └─ Load: ./references/framework-upgrades.md (covers 10→11 in depth; 12→13 is near zero-break)
│
├─ Angular (any major version)
│ ├─ Check: Run ng update for guided migration
│ ├─ Check: Review Angular Update Guide (update.angular.io)
│ ├─ Tool: ng update @angular/core @angular/cli
│ └─ Load: ./references/framework-upgrades.md
│
└─ Django (any major version)
├─ Check: Run python -Wd manage.py test for deprecation warnings
├─ Check: Review Django release notes for removals
├─ Tool: django-upgrade (automatic fixer)
└─ Load: ./references/framework-upgrades.md
Dependency Audit Workflow
Ecosystem?
│
├─ JavaScript / Node.js
│ ├─ npm audit / npm audit fix
│ ├─ npx audit-ci --moderate (CI integration)
│ └─ Socket.dev for supply chain analysis
│
├─ Python
│ ├─ pip-audit
│ ├─ safety check
│ └─ pip-audit --fix (auto-update vulnerable packages)
│
├─ Rust
│ ├─ cargo audit
│ └─ cargo deny check advisories
│
├─ Go
│ ├─ govulncheck ./...
│ └─ go list -m -u all (list available updates)
│
├─ PHP
│ ├─ composer audit
│ └─ composer outdated --direct
│
└─ Multi-ecosystem
└─ Trivy, Snyk, or Dependabot across all
Pre-Migration Checklist
[ ] Test coverage measured and documented (target: >70% for critical paths)
[ ] CI pipeline green on current version
[ ] All dependencies up to date (or pinned with rationale)
[ ] Database backup taken (if applicable)
[ ] Git state clean — migration branch created from latest main
[ ] Rollback plan documented and tested
[ ] Breaking change list reviewed from upstream changelog
[ ] Team notified of migration window
[ ] Feature flags in place for gradual rollout (if applicable)
[ ] Monitoring and alerting configured for regression detection
[ ] Performance baseline captured (response times, memory, CPU)
[ ] Lock file committed (package-lock.json, yarn.lock, Cargo.lock, etc.)
Breaking Change Detection Patterns
How do you detect breaking changes?
│
├─ Semver Analysis
│ ├─ Major version bump → breaking changes guaranteed
│ ├─ Check CHANGELOG.md or BREAKING_CHANGES.md in repo
│ └─ npm: npx npm-check-updates --target major
│
├─ Changelog Parsing
│ ├─ Search for: "BREAKING", "removed", "deprecated", "renamed"
│ ├─ GitHub: compare releases page between versions
│ └─ Read migration guide if one exists
│
├─ Compiler / Runtime Warnings
│ ├─ Enable all deprecation warnings before upgrading
│ ├─ Python: python -Wd (turn deprecation warnings to errors)
│ ├─ Node: node --throw-deprecation
│ └─ TypeScript: strict mode catches type-level breaks
│
├─ Codemods (automated detection + fix)
│ ├─ jscodeshift — JavaScript/TypeScript AST transforms
│ ├─ ast-grep — language-agnostic structural search/replace
│ ├─ rector — PHP automated refactoring
│ ├─ gofmt / gofumpt — Go formatting changes
│ └─ 2to3 — Python 2 to 3 (legacy)
│
└─ Type Checking
├─ TypeScript: tsc --noEmit catches API shape changes
├─ Python: mypy / pyright after upgrade
└─ Go: go vet ./... after upgrade
Codemod Quick Reference
| Ecosystem |
Tool |
Command |
Use Case |
| JS/TS |
jscodeshift |
npx jscodeshift -t transform.ts src/ |
Custom AST transforms |
| JS/TS |
ast-grep |
sg --pattern 'old($$$)' --rewrite 'new($$$)' |
Structural find/replace |
| React |
react-codemod |
npx codemod@latest react/19/migration-recipe |
React version upgrades |
| Next.js |
next-codemod |
npx @next/codemod@latest |
Next.js version upgrades |
| Vue |
vue-codemod |
npx @vue/codemod src/ |
Vue 2 to 3 transforms |
| PHP |
Rector |
vendor/bin/rector process src |
PHP version + framework upgrades |
| Python |
pyupgrade |
pyupgrade --py314-plus *.py |
Python version syntax upgrades |
| Python |
django-upgrade |
django-upgrade --target-version 5.0 *.py |
Django version upgrades |
| Go |
gofmt |
gofmt -w . |
Go formatting updates |
| Go |
gofix |
go fix ./... |
Go API changes |
| Rust |
cargo fix |
cargo fix --edition |
Rust edition migration |
| Multi |
ast-grep |
sg scan --rule rules.yml |
Any language with custom rules |
Rollback Strategy Decision Tree
Migration failed or caused issues — how to roll back?
│
├─ Code-only change, no data migration
│ ├─ Small number of commits
│ │ └─ Git Revert
│ │ git revert --no-commit HEAD~N..HEAD && git commit
│ │ Pros: clean history, safe for shared branches
│ │ Cons: merge conflicts if code has diverged
│ │
│ └─ Entire feature branch
│ └─ Revert merge commit
│ git revert -m 1 <merge-commit-sha>
│
├─ Feature flag controlled
│ └─ Toggle flag off
│ Instant rollback, no deployment needed
│ Keep old code path until new path is proven
│
├─ Database schema changed
│ ├─ Reversible migration exists
│ │ └─ Run down migration
│ │ rails db:rollback / php artisan migrate:rollback / alembic downgrade
│ │
│ └─ Irreversible migration (dropped column, changed type)
│ └─ Restore from backup + replay write-ahead log
│ This is why you take backups BEFORE migration
│
└─ Infrastructure / deployment
├─ Blue-Green deployment
│ └─ Switch traffic back to blue (old) environment
│
├─ Canary deployment
│ └─ Route 100% traffic back to stable version
│
└─ Container orchestration (K8s)
└─ kubectl rollout undo deployment/app
Common Gotchas
| Gotcha |
Why It Happens |
Prevention |
| Upgrading multiple major versions at once |
Each major version may have sequential breaking changes that compound |
Upgrade one major version at a time, verify, then proceed |
| Lock file not committed before migration |
Cannot reproduce pre-migration dependency state |
Always commit lock files; take a snapshot branch before starting |
| Running codemods without committing first |
Cannot diff what the codemod changed vs your manual changes |
Commit clean state, run codemod, commit codemod changes separately |
| Ignoring deprecation warnings in current version |
Deprecated APIs are removed in next major version |
Fix all deprecation warnings BEFORE upgrading |
| Testing only happy paths after migration |
Edge cases and error paths are most likely to break |
Run full test suite plus manual exploratory testing |
| Not checking transitive dependencies |
A direct dep upgrade may pull in incompatible transitive deps |
Use npm ls, pip show, cargo tree to inspect dependency tree |
| Assuming codemods catch everything |
Codemods handle common patterns, not all patterns |
Review codemod output manually; check for skipped files |
| Skipping the migration guide |
Framework authors document known pitfalls and workarounds |
Read the official migration guide end-to-end before starting |
| Migrating in a long-lived branch |
Main branch diverges, causing painful merge conflicts |
Use feature flags for incremental migration on main |
| Not updating CI to test both versions |
CI passes on old version but new version has failures |
Add matrix testing for both versions during transition |
| Database migration without backup |
Irreversible schema changes with no recovery path |
Always backup before migration; test rollback procedure |
| Forgetting to update Docker/CI base images |
Code upgraded but runtime is still old version |
Update Dockerfile FROM, CI config, and deployment manifests |
Reference Files
| File |
Contents |
Lines |
references/framework-upgrades.md |
React 18→19, Next.js Pages→App Router, Vue 2→3, Laravel 10→13, Angular, Django upgrade paths |
~700 |
references/language-upgrades.md |
Python 3.9→3.14, Node 18→26, TypeScript 4→6, Go 1.20→1.26, Rust 2021→2024, PHP 8.1→8.5 |
~650 |
references/dependency-management.md |
Audit tools, update strategies, lock files, monorepo deps, supply chain security |
~550 |
Staleness verifier
This skill hardcodes specific framework/language target versions (React 19, Laravel 13, Python 3.14, Node 26, TypeScript 6, Go 1.26, Rust 2024, PHP 8.5). scripts/check-migrate-facts.py guards them against silent drift:
# Structural (PR CI, no network): every catalogued target version still appears
# where it is recorded (description vs body), and the currency note carries a year.
python scripts/check-migrate-facts.py --offline # exit 0 consistent, 10 drift
# Live (freshness job, never blocks a PR): each target is resolved against
# endoflife.date (python/nodejs/laravel/php/go) and npm (react/typescript).
python scripts/check-migrate-facts.py --live # exit 10 a target lags latest, 7 unreachable
The canonical target-version list lives in assets/migrate-facts.json; when you change a recommended target, update it to match or --offline fails CI. A --live drift means the skill is naming an older target than the ecosystem's current stable — review, don't auto-rewrite.
See Also
| Skill |
When to Combine |
testing-ops |
Ensuring test coverage before migration, writing regression tests after |
debug-ops |
Diagnosing failures introduced by migration, bisecting breaking commits |
git-ops |
Branch strategy for migration, git bisect to find breaking change |
refactor-ops |
Code transformations that often accompany version upgrades |
ci-cd-ops |
Updating CI pipelines to test against new versions, matrix builds |
container-orchestration |
Updating base images, Dockerfile changes for new runtime versions |
security-ops |
Vulnerability remediation that triggers dependency upgrades |
1---2name: migrate-ops3description: "Framework and language migration patterns - version upgrades, breaking changes, dependency audit, safe rollback. Use for: migrate, migration, upgrade, version bump, breaking changes, deprecation, dependency audit, npm audit, pip-audit, codemod, jscodeshift, rector, rollback, semver, changelog, framework upgrade, language upgrade, React 19, Vue 3, Next.js App Router, Laravel 13, Angular, Python 3.14, Node 26, TypeScript 6, Go 1.26, Rust 2024, PHP 8.5."4license: MIT5allowed-tools: "Read Edit Write Bash Glob Grep Agent"6metadata:7 author: claude-mods8 related-skills: testing-ops, debug-ops, git-ops, refactor-ops9---1011# Migrate Operations1213Comprehensive migration skill covering framework upgrades, language version bumps, dependency auditing, breaking change detection, codemods, and rollback strategies.1415> Ecosystem facts verified as of 2026-07-05.1617## Migration Strategy Decision Tree1819```20What kind of migration are you performing?21│22├─ Small library update (patch/minor version)23│ └─ In-place upgrade24│ Update dependency, run tests, deploy25│26├─ Major framework version (React 18→19, Vue 2→3, Laravel 12→13)27│ │28│ ├─ Codebase < 50k LOC, good test coverage (>70%)29│ │ └─ Big Bang Migration30│ │ Upgrade everything at once in a feature branch31│ │ Pros: clean cutover, no dual-version complexity32│ │ Cons: high risk, long branch life, merge conflicts33│ │34│ ├─ Codebase > 50k LOC, partial test coverage35│ │ └─ Incremental Migration36│ │ Upgrade module by module, use compatibility layers37│ │ Pros: lower risk per step, continuous delivery38│ │ Cons: dual-version code, longer total duration39│ │40│ ├─ Monolith → microservice or complete architecture shift41│ │ └─ Strangler Fig Pattern42│ │ Route new features to new system, migrate old features gradually43│ │ Pros: zero-downtime, reversible, production-validated44│ │ Cons: routing complexity, data sync challenges45│ │46│ └─ High-risk data pipeline or financial system47│ └─ Parallel Run48│ Run old and new systems simultaneously, compare outputs49│ Pros: highest confidence, catch subtle differences50│ Cons: double infrastructure cost, comparison logic51│52└─ Language version upgrade (Python 3.12→3.14, Node 22→26)53 └─ In-place upgrade with CI matrix54 Test against both old and new versions in CI55 Drop old version support once all tests pass56```5758## Framework Upgrade Decision Tree5960```61Which framework are you upgrading?62│63├─ React 18 → 1964│ ├─ Check: Remove forwardRef wrappers (ref is now a regular prop)65│ ├─ Check: Replace <Context.Provider> with <Context>66│ ├─ Check: Adopt useActionState / useFormStatus for forms67│ ├─ Check: Replace manual memoization if using React Compiler68│ ├─ Codemod: npx codemod@latest react/19/migration-recipe69│ └─ Load: ./references/framework-upgrades.md70│71├─ Next.js Pages Router → App Router72│ ├─ Check: Move pages/ to app/ with new file conventions73│ ├─ Check: Replace getServerSideProps/getStaticProps with async components74│ ├─ Check: Convert _app.tsx and _document.tsx to layout.tsx75│ ├─ Check: Update data fetching to use fetch() with caching options76│ ├─ Codemod: npx @next/codemod@latest77│ └─ Load: ./references/framework-upgrades.md78│79├─ Vue 2 → 380│ ├─ Check: Replace Options API with Composition API (optional but recommended)81│ ├─ Check: Replace Vuex with Pinia82│ ├─ Check: Replace event bus with mitt or provide/inject83│ ├─ Check: Update v-model syntax (modelValue prop)84│ ├─ Tool: Migration build (@vue/compat) for incremental migration85│ └─ Load: ./references/framework-upgrades.md86│87├─ Laravel 12 → 1388│ ├─ Check: PHP 8.3 is now the minimum (8.5 supported)89│ ├─ Check: Cache/Redis key prefixes now use hyphenated suffixes90│ ├─ Check: Adopt native PHP attributes (models, jobs, controllers) — optional91│ ├─ Check: Queue routing by class via Queue::route(...) — optional92│ ├─ Tool: laravel shift (automated upgrade service)93│ └─ Load: ./references/framework-upgrades.md (covers 10→11 in depth; 12→13 is near zero-break)94│95├─ Angular (any major version)96│ ├─ Check: Run ng update for guided migration97│ ├─ Check: Review Angular Update Guide (update.angular.io)98│ ├─ Tool: ng update @angular/core @angular/cli99│ └─ Load: ./references/framework-upgrades.md100│101└─ Django (any major version)102 ├─ Check: Run python -Wd manage.py test for deprecation warnings103 ├─ Check: Review Django release notes for removals104 ├─ Tool: django-upgrade (automatic fixer)105 └─ Load: ./references/framework-upgrades.md106```107108## Dependency Audit Workflow109110```111Ecosystem?112│113├─ JavaScript / Node.js114│ ├─ npm audit / npm audit fix115│ ├─ npx audit-ci --moderate (CI integration)116│ └─ Socket.dev for supply chain analysis117│118├─ Python119│ ├─ pip-audit120│ ├─ safety check121│ └─ pip-audit --fix (auto-update vulnerable packages)122│123├─ Rust124│ ├─ cargo audit125│ └─ cargo deny check advisories126│127├─ Go128│ ├─ govulncheck ./...129│ └─ go list -m -u all (list available updates)130│131├─ PHP132│ ├─ composer audit133│ └─ composer outdated --direct134│135└─ Multi-ecosystem136 └─ Trivy, Snyk, or Dependabot across all137```138139## Pre-Migration Checklist140141```142[ ] Test coverage measured and documented (target: >70% for critical paths)143[ ] CI pipeline green on current version144[ ] All dependencies up to date (or pinned with rationale)145[ ] Database backup taken (if applicable)146[ ] Git state clean — migration branch created from latest main147[ ] Rollback plan documented and tested148[ ] Breaking change list reviewed from upstream changelog149[ ] Team notified of migration window150[ ] Feature flags in place for gradual rollout (if applicable)151[ ] Monitoring and alerting configured for regression detection152[ ] Performance baseline captured (response times, memory, CPU)153[ ] Lock file committed (package-lock.json, yarn.lock, Cargo.lock, etc.)154```155156## Breaking Change Detection Patterns157158```159How do you detect breaking changes?160│161├─ Semver Analysis162│ ├─ Major version bump → breaking changes guaranteed163│ ├─ Check CHANGELOG.md or BREAKING_CHANGES.md in repo164│ └─ npm: npx npm-check-updates --target major165│166├─ Changelog Parsing167│ ├─ Search for: "BREAKING", "removed", "deprecated", "renamed"168│ ├─ GitHub: compare releases page between versions169│ └─ Read migration guide if one exists170│171├─ Compiler / Runtime Warnings172│ ├─ Enable all deprecation warnings before upgrading173│ ├─ Python: python -Wd (turn deprecation warnings to errors)174│ ├─ Node: node --throw-deprecation175│ └─ TypeScript: strict mode catches type-level breaks176│177├─ Codemods (automated detection + fix)178│ ├─ jscodeshift — JavaScript/TypeScript AST transforms179│ ├─ ast-grep — language-agnostic structural search/replace180│ ├─ rector — PHP automated refactoring181│ ├─ gofmt / gofumpt — Go formatting changes182│ └─ 2to3 — Python 2 to 3 (legacy)183│184└─ Type Checking185 ├─ TypeScript: tsc --noEmit catches API shape changes186 ├─ Python: mypy / pyright after upgrade187 └─ Go: go vet ./... after upgrade188```189190## Codemod Quick Reference191192| Ecosystem | Tool | Command | Use Case |193|-----------|------|---------|----------|194| **JS/TS** | jscodeshift | `npx jscodeshift -t transform.ts src/` | Custom AST transforms |195| **JS/TS** | ast-grep | `sg --pattern 'old($$$)' --rewrite 'new($$$)'` | Structural find/replace |196| **React** | react-codemod | `npx codemod@latest react/19/migration-recipe` | React version upgrades |197| **Next.js** | next-codemod | `npx @next/codemod@latest` | Next.js version upgrades |198| **Vue** | vue-codemod | `npx @vue/codemod src/` | Vue 2 to 3 transforms |199| **PHP** | Rector | `vendor/bin/rector process src` | PHP version + framework upgrades |200| **Python** | pyupgrade | `pyupgrade --py314-plus *.py` | Python version syntax upgrades |201| **Python** | django-upgrade | `django-upgrade --target-version 5.0 *.py` | Django version upgrades |202| **Go** | gofmt | `gofmt -w .` | Go formatting updates |203| **Go** | gofix | `go fix ./...` | Go API changes |204| **Rust** | cargo fix | `cargo fix --edition` | Rust edition migration |205| **Multi** | ast-grep | `sg scan --rule rules.yml` | Any language with custom rules |206207## Rollback Strategy Decision Tree208209```210Migration failed or caused issues — how to roll back?211│212├─ Code-only change, no data migration213│ ├─ Small number of commits214│ │ └─ Git Revert215│ │ git revert --no-commit HEAD~N..HEAD && git commit216│ │ Pros: clean history, safe for shared branches217│ │ Cons: merge conflicts if code has diverged218│ │219│ └─ Entire feature branch220│ └─ Revert merge commit221│ git revert -m 1 <merge-commit-sha>222│223├─ Feature flag controlled224│ └─ Toggle flag off225│ Instant rollback, no deployment needed226│ Keep old code path until new path is proven227│228├─ Database schema changed229│ ├─ Reversible migration exists230│ │ └─ Run down migration231│ │ rails db:rollback / php artisan migrate:rollback / alembic downgrade232│ │233│ └─ Irreversible migration (dropped column, changed type)234│ └─ Restore from backup + replay write-ahead log235│ This is why you take backups BEFORE migration236│237└─ Infrastructure / deployment238 ├─ Blue-Green deployment239 │ └─ Switch traffic back to blue (old) environment240 │241 ├─ Canary deployment242 │ └─ Route 100% traffic back to stable version243 │244 └─ Container orchestration (K8s)245 └─ kubectl rollout undo deployment/app246```247248## Common Gotchas249250| Gotcha | Why It Happens | Prevention |251|--------|---------------|------------|252| Upgrading multiple major versions at once | Each major version may have sequential breaking changes that compound | Upgrade one major version at a time, verify, then proceed |253| Lock file not committed before migration | Cannot reproduce pre-migration dependency state | Always commit lock files; take a snapshot branch before starting |254| Running codemods without committing first | Cannot diff what the codemod changed vs your manual changes | Commit clean state, run codemod, commit codemod changes separately |255| Ignoring deprecation warnings in current version | Deprecated APIs are removed in next major version | Fix all deprecation warnings BEFORE upgrading |256| Testing only happy paths after migration | Edge cases and error paths are most likely to break | Run full test suite plus manual exploratory testing |257| Not checking transitive dependencies | A direct dep upgrade may pull in incompatible transitive deps | Use `npm ls`, `pip show`, `cargo tree` to inspect dependency tree |258| Assuming codemods catch everything | Codemods handle common patterns, not all patterns | Review codemod output manually; check for skipped files |259| Skipping the migration guide | Framework authors document known pitfalls and workarounds | Read the official migration guide end-to-end before starting |260| Migrating in a long-lived branch | Main branch diverges, causing painful merge conflicts | Use feature flags for incremental migration on main |261| Not updating CI to test both versions | CI passes on old version but new version has failures | Add matrix testing for both versions during transition |262| Database migration without backup | Irreversible schema changes with no recovery path | Always backup before migration; test rollback procedure |263| Forgetting to update Docker/CI base images | Code upgraded but runtime is still old version | Update Dockerfile FROM, CI config, and deployment manifests |264265## Reference Files266267| File | Contents | Lines |268|------|----------|-------|269| `references/framework-upgrades.md` | React 18→19, Next.js Pages→App Router, Vue 2→3, Laravel 10→13, Angular, Django upgrade paths | ~700 |270| `references/language-upgrades.md` | Python 3.9→3.14, Node 18→26, TypeScript 4→6, Go 1.20→1.26, Rust 2021→2024, PHP 8.1→8.5 | ~650 |271| `references/dependency-management.md` | Audit tools, update strategies, lock files, monorepo deps, supply chain security | ~550 |272273## Staleness verifier274275This skill hardcodes specific framework/language target versions (React 19, Laravel 13, Python 3.14, Node 26, TypeScript 6, Go 1.26, Rust 2024, PHP 8.5). [`scripts/check-migrate-facts.py`](scripts/check-migrate-facts.py) guards them against silent drift:276277```bash278# Structural (PR CI, no network): every catalogued target version still appears279# where it is recorded (description vs body), and the currency note carries a year.280python scripts/check-migrate-facts.py --offline # exit 0 consistent, 10 drift281282# Live (freshness job, never blocks a PR): each target is resolved against283# endoflife.date (python/nodejs/laravel/php/go) and npm (react/typescript).284python scripts/check-migrate-facts.py --live # exit 10 a target lags latest, 7 unreachable285```286287The canonical target-version list lives in [`assets/migrate-facts.json`](assets/migrate-facts.json); when you change a recommended target, update it to match or `--offline` fails CI. A `--live` drift means the skill is naming an older target than the ecosystem's current stable — review, don't auto-rewrite.288289## See Also290291| Skill | When to Combine |292|-------|----------------|293| `testing-ops` | Ensuring test coverage before migration, writing regression tests after |294| `debug-ops` | Diagnosing failures introduced by migration, bisecting breaking commits |295| `git-ops` | Branch strategy for migration, git bisect to find breaking change |296| `refactor-ops` | Code transformations that often accompany version upgrades |297| `ci-cd-ops` | Updating CI pipelines to test against new versions, matrix builds |298| `container-orchestration` | Updating base images, Dockerfile changes for new runtime versions |299| `security-ops` | Vulnerability remediation that triggers dependency upgrades |