v0.311.0: after a power cut, an app repairs the files the cut left empty; the household sees lost photos (R-1007)
gates / gates (push) Successful in 52s

New template block after_unclean_boot (decision 236): once per controller start that followed an
UNCLEAN host boot (crashboot's own verdict, after the 15-minute crash grace; a normal or unknown boot
never runs it), each app with the block rebuilds ONLY its zero-byte files (scan: regular files, no
symlinks, its own filesystem; ids appended to the app's own command in batches; one retry, then
reported) and its own lost-file check is read. The household sees lost files (name, date taken) on
the app page until dismissed; the operator gets app_repaired_after_crash with counts only. Skips,
with the reason, an unproven image, an unknown key, an app not running. MinAgent 0.155.0 unchanged.
Tests red-proofed (14 guards). One new parity fixture (the new card only).

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-14 16:47:13 +02:00
parent acbbf4b305
commit 8d862e4e69
24 changed files with 1865 additions and 3 deletions
@@ -413,6 +413,13 @@ func i18nCases() []i18nCase {
d["SignupNativeOpenFailed"] = true // R-717: the window could not open the app's own switch
return d
}})
// R-1007: the lost-files note after an unclean boot (name, date taken, the boot time, the dismiss button).
base = append(base, i18nCase{"app_info_lost_files", "app_info", func() map[string]interface{} {
d := signupCase("x", false, "").data()
d["LostFiles"] = []stacks.LostFile{{Name: "IMG_0001.jpg", Taken: "2026-10-14 10:41"}}
d["LostBootAt"] = "2026-10-14 14:07"
return d
}})
// R-718: the close card and the gate card say the app restarts once where the app has its own switch.
base = append(base, i18nCase{"app_info_close_signup_native", "app_info", func() map[string]interface{} {
d := signupCase("x", false, "").data()