From af2d8e3792adbe1d106756eb613c58c2671ea8b6 Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Sun, 25 Oct 2026 12:38:28 -0700 Subject: [PATCH] fix(system): keep a refused or handed-back restore review usable A Restore refused as busy now opens the same review again with Discard / Restore, and a restore job whose leases did not drain hands its review back (scope.review_kept) to the page that started it, which reopens it; every other path that abandons a token after Restore sends its DELETE, so held reviews can no longer lock restore out. The kept-review line says where the review is, and a full review store says what to do (I1). applyPlan resolves with its outcome and its job tracking now has failing-before proof (N5). Also: the safety-backup toggle says what the policy does (D104, M2); the restore picker has no type filter so safety backups can be chosen (M3); "Export all prompts JSON" names what /export holds (N1); small snapshots show KB (N3); the duplicated holding and save helpers are shared (N4); a dismissal test covers Cancel, x, Escape, a replacing dialog and leaving (M1). Refs #326 --- TESTING.md | 34 +++-- py/api/backup_restore.py | 7 +- tests/browser/system-backups-concept.spec.mjs | 22 +-- .../browser/workspace-system-backups.spec.mjs | 111 +++++++++++++++- tests/js/workspace-system-backups.test.js | 79 ++++++++++- tests/js/workspace-toolbar.test.js | 34 +++++ tests/test_restore_review_fixes.py | 28 +++- web/js/workspace/activity-scan.mjs | 4 +- web/js/workspace/index.mjs | 7 +- web/js/workspace/maintenance-review.mjs | 24 ++-- web/js/workspace/system-backups.mjs | 125 ++++++++++++------ 11 files changed, 396 insertions(+), 79 deletions(-) diff --git a/TESTING.md b/TESTING.md index 5ff54cdf..f15360ff 100644 --- a/TESTING.md +++ b/TESTING.md @@ -2630,14 +2630,17 @@ Recorded deviations (plan D60–D75, D79–D82 renumbered D92–D107 and D111– `.backup_*`, else "No backup recorded."; "Checking backups…" while read and "The backup status could not be read." when it failed (never "no backup"). Portable export's "Export JSON" (the concept's "Export sample JSON") downloads the Library - document (`/library/export`); a second `.row-actions.spaced` adds "Export components - JSON" (`/export`, the legacy prompt list) and "Export saved pairs JSON" + document (`/library/export`); a second `.row-actions.spaced` adds "Export all prompts + JSON" (`/export`, the legacy admin page's Export of every prompt) and "Export saved pairs JSON" (`/pairs/export`), plain buttons as the concept's; a failed export toasts "The export could not be downloaded. Nothing was saved to this device." "Import / inspect file" opens the shared "Import & inspect" (D15, D55), as Images does. - **D104** (Backup & export, S9, Q4): Recovery policy keeps the concept's "Proposed" chip. "Create a safety backup before maintenance" is the server's `safety_backup` - (`maintenance.safety_backup`) policy, drafted behind the Save row and saved with + (`maintenance.safety_backup`) policy. Its line says what it does ("Keep a verified copy + of the database on disk before maintenance, cleanups and LoRA imports change records. A + restore always keeps one."); the concept's "Preview a verified backup before applying + operations that change records." describes nothing the server does. It is drafted behind the Save row and saved with `expected_revision` (a configuration changed elsewhere is the conflict status); it is disabled with "Server settings could not be read." when the read failed. "Scheduled database backups" offers Manual only; Daily and Weekly stay listed but disabled @@ -2645,13 +2648,14 @@ Recorded deviations (plan D60–D75, D79–D82 renumbered D92–D107 and D111– back up with Back up whenever you choose." (the concept's proposal line is prototype copy) and nothing is drafted for it. The warning note reads "Restores are staged, migrated and validated before replacing live data." -- **D105** (Backup & export, S9): "Review restore…" picks a `.db` file and stages it +- **D105** (Backup & export, S9): "Review restore…" picks a file (no type filter: the + safety backups `.backup_