--- name: lifecycle-deprecate-node risk_class: config_mutation inputs: [node_name, replacement_node_or_reason] verification: "MCP get_blast_radius — 'affected by' must be empty before completing" docs_update_checklist: [doc_page_deprecation_note] transition: "active -> deprecated" --- # Lifecycle: deprecate a node Per [seeds/ontology.yaml](../../../seeds/ontology.yaml): a node keeps running but takes no new dependents. **Completion condition: zero remaining inbound `depends-on`/`routes-to` edges** — this is a hard gate, not a suggestion; `seeds/policy.yaml` `lifecycle_overrides.deprecated.refuse` lists `new-inbound-edges` as refused going forward. 1. Set `state: deprecated` on the node. 2. MCP `get_blast_radius` — read `affected_by`. Every entry there is something still relying on this node. 3. Migrate or retire each dependent one at a time (point its `backend`/ `config_repo`/ingress route elsewhere, or deprecate it too if it's being retired alongside). 4. Re-run MCP `get_blast_radius` after each dependent is moved. The transition to `destroyed` is only safe once `affected_by` is empty — check this every time, don't assume from memory. 5. Note the deprecation on the doc page: reason, replacement (if any), date. If step 2 shows dependents you didn't expect, stop and investigate before proceeding — that's exactly the kind of drift the Week-3 detector will catch automatically, but until then this manual check is the gate. Next (once `affected_by` is empty): [lifecycle-destroy-node.md](../lifecycle-destroy-node/SKILL.md).