--- name: lifecycle-migrate-node risk_class: config_mutation inputs: [node_name, source_host, target_host] verification: "MCP get_blast_radius (re-check blast radius); MCP get_service_status for every hosted service" docs_update_checklist: [doc_page_migration_note, inventory_host_and_lan_ip] transition: "active -> migrating -> active" --- # Lifecycle: migrate a node Modeled on the strong Phase 1+2 migration ([archive/hermes-plans/2026-06-03_110000-library-ssd-migration-to-ludo-mini.md](../../../archive/hermes-plans/2026-06-03_110000-library-ssd-migration-to-ludo-mini.md)). Requires (ontology): preflight + backup-verified before migrating; post-verify + Caddy backends checked + mounts checked + docs updated before returning to `active`. 1. MCP `preflight` for every service the node hosts — capture current health as a baseline. 2. Verify backups are current for anything with data at rest on the node (see `backs-up-to` edges once populated). 3. Set `state: migrating` in `inventory.yaml`. 4. Perform the migration (pct/qm move, or create-on-target + data-copy + destroy-source, per the specific case). 5. Update `inventory.yaml`: new `host:`, `lan_ip`, `mesh` addresses for the node; update every `services:` entry whose `backend` pointed at it if the backend name itself changes (usually it doesn't — only the `host:`/`lan_ip` on the guest entry moves). 6. Post-verify: re-run the Week-1 drift check by hand — confirm Caddy's backend IP for each affected service matches the new `lan_ip` (automatic in Week 3's drift detector), confirm mounts still resolve. 7. MCP `get_service_status` for every service the node hosts. 8. Set `state: active`. Add a migration note to the node's doc page (old host/IP → new, date, phase reference) — this repo's convention for every past migration (see `archive/knowledge/containers/101-jellyfin.md`, `containers/129-house.md`). Regenerate: `oikos seed` (re-ingests `seeds/inventory.yaml` into the DB — the DB is authoritative at runtime, the YAML is the source of truth on disk).