v0.142.0: offsite repo continuity — orphaned-repo guard (A) + run-status auto-refresh (C)

- Part A: classify restic cat-config failure (wrong-password=orphaned vs no-repo vs other); ORPHANED state + Hungarian card + offbox_repo_orphaned/reset events (once, not nightly); reset = move-aside (never delete) + init, unclaimed auto / claimed confirm. Red-proofs TestOffbox_OrphanDetection_* + ConfirmedReset.
- Part C: GET /backup/offbox/status + poll on backups_remote → flips Fut→Rendben/Hiba without manual reload.
This commit is contained in:
2026-07-17 10:47:30 +02:00
parent 1452dd2b17
commit 596505ed64
11 changed files with 587 additions and 18 deletions
+12
View File
@@ -168,6 +168,18 @@ type OffboxTarget struct {
// hub-verified pending→escrowed flip (report.EscrowAutoConfirmer). Zeroed by that flip (and the
// deprecated manual confirm). Persisted, so it survives a controller restart mid-wait. Not a secret.
CeremonyCompletedAt string `json:"ceremony_completed_at,omitempty"`
// RepoState (v0.142.0, offsite continuity) classifies the offsite REPO — "" normal | "orphaned".
// ORPHANED = the remote repo exists but was keyed under a passphrase this controller no longer has
// (the reinstall/recreated-volume shape: `restic cat config` → "wrong password or no key found").
// While orphaned, scheduled runs SKIP (one event, not nightly) and the remote page shows the orphan
// card instead of the raw restic error; a reset (move-aside + init) clears it. Not a secret.
RepoState string `json:"repo_state,omitempty"`
// OrphanedAt is the RFC3339 stamp of the orphan detection (drives the card copy).
OrphanedAt string `json:"orphaned_at,omitempty"`
// OrphanedRenamedTo records the move-aside path of the last reset (e.g. <repo>.orphaned-20260717),
// so the card/log can name where the old (recovery-code-recoverable) history was set aside.
OrphanedRenamedTo string `json:"orphaned_renamed_to,omitempty"`
}
// CrossDriveBackup configures per-app backup to a secondary drive.