--- name: lifecycle-destroy-node risk_class: destructive inputs: [node_name] verification: "homelab node relations returns unknown-entity; pct list on the backend no longer shows it" docs_update_checklist: [archaeology_entry, containers_index_update] transition: "deprecated -> destroyed" --- # Lifecycle: destroy a node **Destructive.** Requires operator approval + typed confirmation phrase per `oikos/policy.yaml`. Requires (ontology): backups verified, secrets recipients removed + re-keyed, ingress/DNS removed, archaeology entry, ledger entry. 1. Confirm the node is `deprecated` with zero `affected_by` edges (`homelab node relations`) — do not skip this even if the deprecation runbook was followed recently; state can drift. 2. If it's an enrolled client: `homelab client remove ` — revokes the age key, re-keys SOPS, removes the inventory entry. This is already destructive-class and confirmed in the CLI. 3. Remove any ingress route (Caddy config repo) and DNS record still pointing at it. 4. Verify backups of anything on it are retained per policy before the disk goes away (see `backs-up-to`). 5. Destroy the LXC/VM (`pct destroy` / `qm destroy`). 6. Move the `hosts.:` block (if any inventory remnant survives `client remove`, e.g. infra-only LXCs with no age key) into inventory.yaml's `archaeology:` section: `pve_id`, `destroyed` date, `reason`. Add a row to `containers/index.md` "Recently destroyed" table (kept for human-readable browsing alongside the structured data). 7. `oikos/ledger.py append host: destroy destructive --result ok`. 8. Regenerate: `python3 mcp/build_host_files.py && python3 oikos/gen-topology.py` — the node drops out of `hosts/*.yaml` and appears in the topology doc's archaeology table. If the destroy fails partway (e.g. secrets revoked but pct destroy errors), do not re-run step 2 — `client remove` is not idempotent against a second revocation attempt on the issuance server. Finish the remaining steps manually and note the partial state in an investigation.