- DeleteHost(deleteEscrow) demotes current host_escrow into host_escrow_superseded (copy-before-delete, same tx), spares existing; one shared demoteCurrentEscrowTx (reused by SaveHostEscrow). F-14 provenance/gate unchanged. - DeleteCustomerConfig now purges both escrow tables for all the customer's hosts incl. already-deleted (F-14 provenance UNION) — the one true purge point. - Wording: checkbox/refusal/Danger-zone → demotion. S6b OBSOLETE. Red-proofs TestDeleteHost_Demotes + TestDeleteCustomer_Purges + wording guard.
4.2 KiB
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; the scripts history lives in 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
ErrHostEscrowPresentrefusal 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):
DeleteCustomerConfigstill 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.