# felhom.eu — task reports > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). ## Hub v0.60.1 — host deletion demotes escrow custody (never destroys) + S6b verdict — 2026-07-17 **Baseline:** hub v0.60.0 (`106c337`) → **v0.60.1** (LIVE, ArgoCD Synced/Healthy). Hub-only; no controller/agent change. Closes the deletion-path gap found in the v0.60.0 review. Green: `go build ./... && go vet ./... && go test ./...` + hub confirm gate. ### Scenario A — host delete demotes, never destroys (`store.DeleteHost`) The v0.60.0 code deleted `host_escrow` + `host_escrow_superseded` on `deleteEscrow=true`. Now it DEMOTES the current row into `host_escrow_superseded` (copy-BEFORE-delete, same tx) and SPARES existing superseded rows. Extracted THE one escrow row-copy routine `demoteCurrentEscrowTx` (INSERT…SELECT) and refactored `SaveHostEscrow` to use it too — one copy routine, not two (rule 2). The F-14 provenance row + gate semantics are unchanged (comments reworded: demotion, not destruction). Edge: no escrow row → unchanged; the `ErrHostEscrowPresent` refusal without the flag is unchanged. **Red-proof (run-fail-revert):** `TestDeleteHost_DemotesEscrowNeverDestroys` — pre-fix (delete both) → retained=0 → FAIL; fixed → both blobs (demoted current + spared superseded) retrievable, host gone. ### Scenario B — customer delete is the purge point (`store.DeleteCustomerConfig`) **What it did before:** ONLY `DELETE FROM customer_configs` — it touched neither hosts nor escrow (so deleting a customer left hosts + escrow blobs orphaned — an offboarding gap, see Observations). **Now:** one tx that purges `host_escrow` AND `host_escrow_superseded` for all the customer's hosts — INCLUDING already-deleted hosts (resolved via the F-14 `host_deletions` provenance `UNION`), so a host-delete-then-customer-delete ordering leaves nothing orphaned. Danger-zone copy states it. **Red-proof:** `TestDeleteCustomer_PurgesEscrowCustody` (pre-fix config-only → blobs survive → FAIL). ### Scenario C — wording (`host_detail_body.html`, `hosts.go`, `customer_unified.html`) Host-delete escrow checkbox → "Move key escrow to retained custody (required when escrow present) + remove DR bundle for this host"; the 409 refusal message → "…move it to retained custody…"; the customer Danger-zone copy → "…permanently removes the retained recovery-key custody (escrow blobs)… This is the one true purge point; host deletion only demotes custody, never destroys it." Guard test `TestHostDeleteEscrowLabel_DemotionWording`. ### Scenario D — S6b necessity verdict: **OBSOLETE** **Verdict + landmarks:** re-enrolling an existing host_id upserts cleanly — `store.UpsertHost` is `INSERT … ON CONFLICT(host_id) DO UPDATE` (`internal/store/store.go:2099`), and `handleAdminCreateHost` (`internal/api/handler.go:913`) calls it with NO duplicate refusal (it even mints a fresh api_key). Combined with the v0.57.0 re-enroll arc (claim/offsite/escrow-honesty auto-fire on re-enrollment, `reissueOnReenroll` `handler.go:1020`), no manual stale-host deletion is required before re-enroll. Since S6b is not a literal runbook step, the verdict is recorded here + in ROADMAP R-3 ("re-enrollment upserts cleanly; S6b obsolete; escrow cascade now defined; the rehearsal live-confirms it"). Scenario A also makes the funnel harmless either way (deletion demotes, not destroys). ### Deploy verification `felhom-hub:0.60.1` built + pushed; `manifests/hub.yaml` bumped; ArgoCD Synced/Healthy; rollout complete (`:0.60.1`). The `demoteCurrentEscrowTx` path is INSERT…SELECT (atomic within the delete tx). ### Observations - **Customer-delete offboarding gap (unchanged this task, by scope):** `DeleteCustomerConfig` still does NOT delete the customer's HOST rows or the broader offboarding (Hetzner sub-account, WG peer, Storage-Box data) — only the escrow tables + the config row. That non-escrow lifecycle stays the delete/re-create rehearsal's question (ROADMAP R-3). - No pruning added (Viktor's data-first ruling); the ACK assembly + the upload supersede path are untouched.