Skip to content

Commit de79823

Browse files
Retire mistaken Hetzner OS backups (#6068)
1 parent a780443 commit de79823

4 files changed

Lines changed: 57 additions & 20 deletions

File tree

apps/crawler/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.13.189
1+
0.13.190

apps/crawler/alerts.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ groups:
194194
route: codex-daily
195195
annotations:
196196
summary: "{{ $labels.service }} backup failed on {{ $labels.instance }}"
197-
description: "The latest application-data backup attempt failed. Legacy OS backups must remain enabled."
197+
description: "The latest application-data backup attempt failed. The native repository is now the only recovery path; investigate immediately and preserve existing artifacts."
198198
runbook: https://github.com/colophon-group/jobseek/blob/main/docs/19-data-backup-recovery.md#failure-and-removal-gates
199199

200200
- alert: DataBackupStale

docs/19-data-backup-recovery.md

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ The root-owned fleet sampler republishes only the numeric status fields as
7171
`jobseek_backup_*` metrics with stable host/service labels; it never forwards
7272
the JSON error text. `DataBackupFailed` and `DataBackupStale` are owned by the
7373
daily Codex route in `apps/crawler/alerts.yaml`. This establishes the telemetry
74-
source, but it does not by itself satisfy the server-backup removal gate: the
75-
error-review bundle must still prove bounded historical reads and GitHub issue
76-
delivery without a write credential.
74+
source. Bounded historical reads and GitHub issue delivery without a write
75+
credential remain tracked by #5948; the owner-approved legacy-backup retirement
76+
described below did not waive that follow-up.
7777

7878
## Initial production evidence (2026-07-22)
7979

@@ -94,8 +94,18 @@ failures and Typesense remained healthy without a restart.
9494
Both timers are enabled and their next jittered runs are visible. Delete and
9595
rebuild protection is enabled on both data servers, delete protection is
9696
enabled on the PostgreSQL Volume, and the validated pre-cutover PostgreSQL
97-
container has been removed. Legacy server backups remain until daily
98-
error-review alert delivery passes the removal gate below.
97+
container has been removed.
98+
99+
On 2026-07-23, the account owner explicitly directed retirement of the mistaken
100+
server backups while #5948 was paused on account-owner acceptance of updated
101+
Grafana terms. Immediately before the control-plane change, both native backup
102+
jobs had succeeded that day, both timers were enabled, PostgreSQL WAL archival
103+
had zero failures, the Storage Box and data resources were delete-protected,
104+
both services were healthy with zero restarts/OOMs, and no backup alert was
105+
firing. Disabling the two Hetzner backup schedules also removed all seven
106+
server-bound backup images for each host. PostgreSQL and Typesense were not
107+
restarted. The independent encrypted repositories and Storage Box snapshots
108+
remain the recovery artifacts.
99109

100110
## Installation and scheduling
101111

@@ -302,8 +312,7 @@ Cloudflare tunnel to a restore drill.
302312

303313
## Failure and removal gates
304314

305-
Do not remove the existing Hetzner server backups until all of the following
306-
are true for both services:
315+
The normal replacement gate for any future legacy backup retirement is:
307316

308317
- the off-host backup completed and repository validation passed;
309318
- an isolated restore using that repository passed;
@@ -312,12 +321,18 @@ are true for both services:
312321
evidence and can create or update an actionable GitHub issue;
313322
- recovery evidence and measured recovery time are recorded in the audit.
314323

315-
Current gate state as of 2026-07-22: off-host backups, repository validation,
316-
isolated restores, measured recovery evidence, enabled schedules, and visible
317-
next runs have passed. Daily Codex failure/freshness evidence and proven GitHub
318-
issue delivery remain pending. Therefore the legacy server backups must remain
319-
enabled even though the replacement data protection is operating normally.
320-
321-
After the gate passes, disable server backups and delete the residual server
322-
backup images for PostgreSQL and Typesense. Preserve the independent Storage
323-
Box repositories and their secondary snapshots.
324+
Current state as of 2026-07-23: off-host backups, repository validation,
325+
isolated restores, measured recovery evidence, enabled schedules, visible next
326+
runs, resource protection, and live Grafana backup series have passed. At the
327+
account owner's explicit direction, the two mistaken Hetzner backup schedules
328+
were disabled before #5948's daily issue-delivery proof; the provider action
329+
also removed all residual server-backup images. This is a recorded,
330+
owner-approved exception, not a relaxation of the normal replacement gate.
331+
332+
Until #5948 completes, an operator must inspect the atomic backup status,
333+
repository validation, timers, WAL archive state, and `DataBackupFailed` /
334+
`DataBackupStale` rule state during production maintenance and backup incident
335+
review. A failure or stale result is critical because the native encrypted
336+
repositories are now the only recovery artifacts. Do not re-enable OS backups
337+
as a substitute for repairing the native data-backup path. Preserve the
338+
independent Storage Box repositories and their secondary snapshots.

docs/audits/2026-07-22-hetzner-systems.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,26 @@ pass.
6767
Codex error-review workflow and can create or update an actionable GitHub
6868
issue, as required by `docs/19-data-backup-recovery.md`.
6969

70+
### 2026-07-23 — mistaken OS backups retired
71+
72+
- Immediately before the provider change, the scheduled PostgreSQL
73+
differential backup and Typesense snapshot/upload/check had both succeeded
74+
that day. Their timers were enabled, the next runs were visible, PostgreSQL
75+
WAL archive failures were zero, the Storage Box and data resources retained
76+
delete protection, both services were healthy with zero restart/OOM counts,
77+
and the live backup-success/freshness series had no firing backup alert.
78+
- At the account owner's explicit direction, the PostgreSQL and Typesense
79+
Hetzner server-backup schedules were disabled while #5948 remained paused on
80+
account-owner acceptance of updated Grafana terms. Hetzner's disable action
81+
also removed all seven residual server-bound images for each server. This was
82+
a control-plane-only change; PostgreSQL and Typesense were not restarted.
83+
- The encrypted pgBackRest/WAL and Typesense Restic repositories, their tested
84+
restore procedures, and the Storage Box's seven daily secondary snapshots
85+
are now the recovery paths. Daily Codex issue-delivery proof remains a
86+
separate high-priority operational gap under #5948; until it is complete,
87+
backup state must be checked directly during production maintenance and
88+
backup incident review.
89+
7090
### 2026-07-22 — fleet observability staged
7191

7292
- Merged and deployed the repo-owned host telemetry surface from `main` to the
@@ -461,7 +481,8 @@ Observed project inventory for the in-scope systems: three running servers, one
461481

462482
- Name and verify accountable human owners/on-call escalation paths; the Cloud project API does not expose project membership or billing ownership.
463483
- Prove database/search backup failure and freshness evidence in the daily
464-
Codex issue-delivery path, then remove the mistaken Hetzner OS backups.
484+
Codex issue-delivery path. The mistaken Hetzner OS backups have already been
485+
retired under the recorded owner-approved exception.
465486
- Add explicit historical metrics coverage to the root-produced Codex error-review evidence boundary without exposing production or write credentials.
466487
- Verify the documented Cloudflare per-IP rate-limit rule and notification routing in the Cloudflare control plane.
467488
- Verify notification delivery rather than rule evaluation only; the false `ExporterStale` alerts show that firing state alone is not useful evidence.
@@ -472,4 +493,5 @@ The baseline audit phase was read-only. Subsequent operator-approved changes
472493
are recorded only in the verified remediation change log above so the original
473494
observations remain reproducible. Replacement database/search backups,
474495
restores, scheduling, capacity expansion, and resource protections are now
475-
verified; legacy OS-backup removal remains gated on daily alert-delivery proof.
496+
verified, and the mistaken OS backups have been retired. Daily alert-to-issue
497+
delivery remains pending under #5948.

0 commit comments

Comments
 (0)