R-893 option A (operator D20): a failed off-site restore puts the app's live volumes and definition back exactly and starts it; fit check before the stop; the held sentence made true (R-1169)
gates / gates (push) Successful in 1m11s

This commit is contained in:
2026-10-20 09:17:00 +02:00
parent ae2bfb2f7a
commit 93fb251ea9
13 changed files with 752 additions and 55 deletions
+9
View File
@@ -1471,6 +1471,15 @@ func main() {
"The app will not start from any path until the hold is cleared. Replay error: %v. Rollback error: %v", stack, replayErr, rollbackErr)
notifier.NotifyBackupRunFailures(msg, d)
})
// R-893 option A (D20 = A): a failed off-site restore that was PUT BACK — the live volumes and definition poured
// back and the app started. The same operator-tier event as the hold above (no new event type), its own leg.
backupMgr.SetRestorePutBackNotify(func(stack string, replayErr error) {
d := notify.BackupRunFailuresDetails{RunKind: "offsite-reconstitute", Failed: 1, Attempted: 1}
d.Apps = append(d.Apps, notify.RunFailureDetail{App: stack, Leg: "restore-put-back", Reason: "restore failed; the pre-restore copy was put back"})
msg := fmt.Sprintf("App %q: its off-site restore FAILED and was undone — the live volumes and definition from just before the restore were put back "+
"and the app was started (R-893). No support step is needed; the household was told. Error: %v", stack, replayErr)
notifier.NotifyBackupRunFailures(msg, d)
})
// 3a: the pre-push enlargement gate blocked an app's userdata push (config+DB still saved). Edge-
// triggered by the engine (only NEW blocks notify), so the hub's per-event-type cooldown suffices —
// no controller-side timer (the hub owns cooldown).