R-893 slice 1: a failed off-site replay after files/volumes/version moved holds the app

Decision 192 (D8, option C). After a failed off-site database replay whose
rollback worked, but where the snapshot's definition was written or a named
volume was replaced, the app is no longer started on the mixed state:
the live definition is written back, the database service stopped, and the
app held (HoldReasonRestoreMixed) for support. The sentence (hu+en) says the
app needs help and no longer claims the data is back as it was. The operator
gets a backup_run_failures mail (leg restore-hold-mixed).

The plain case (no version change, no volume replaced) keeps today's
behaviour (TestR379_ScenarioA). Red-proofed: r893_mixed_restore_test.go.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-08 14:39:20 +02:00
parent 740339567a
commit 63441f0a69
7 changed files with 268 additions and 0 deletions
+5
View File
@@ -1876,6 +1876,11 @@ const (
// HoldReasonUnhealthyStop (v0.269.0, `09` §3 decision 28): the box stopped an app in a crash loop or
// an out-of-memory storm. Lifted by the household's Start (one more try); nothing else starts it.
HoldReasonUnhealthyStop = "unhealthy_stop"
// HoldReasonRestoreMixed (R-893, `09` §3 decision 192): an off-site restore of one app failed its database
// replay AFTER the snapshot's definition was written or a named volume was replaced. The database was
// rolled back, the live definition written back, and the app is held: its files and volumes are the
// snapshot's, its database the pre-restore one. Cleared like a restore hold — by the operator.
HoldReasonRestoreMixed = "restore_mixed"
)
// SetRestoreHold records a hold. Modelled on SetDisconnected: a condition, plus what it is holding.