Skip to content

Fix mirror restore deletion semantics - #20

Merged
vrtmrz merged 2 commits into
mainfrom
fix-mirror-delete-semantics
Jul 15, 2026
Merged

Fix mirror restore deletion semantics#20
vrtmrz merged 2 commits into
mainfrom
fix-mirror-delete-semantics

Conversation

@vrtmrz

@vrtmrz vrtmrz commented Jul 15, 2026

Copy link
Copy Markdown
Owner

User-facing behaviour

  • Only new restores only files that are absent locally or newer in the selected backup.
  • All restores every selected file without deleting local files.
  • All and delete extra restores every selected file, then deletes local files represented by the selected deletion records.
  • A restore that will delete local files uses the title Restore and Delete Confirmation and the explicit action Restore and delete; Cancel remains the default action.
  • Selecting an older restore point now follows the state recorded at that point. A file deleted later is restored from an earlier revision, while a deletion record selected at that point removes the corresponding local file.
  • If an archive cannot be read, an entry is missing, or a Vault write fails, the restore reports the failure and does not proceed with the planned deletions.
  • The legacy folder restore skips deletion records and restores the available file revisions.

Implementation summary

  • map each restore mode to its intended overwrite and deletion behaviour
  • derive deletion decisions from the selected historical revision
  • require every requested archive entry to be restored before deleting confirmed local files
  • propagate archive and Vault write failures
  • distinguish destructive restore confirmations in their title and primary action
  • keep restore planning and execution under separate wake-lock leases, without holding a lease during confirmation

Root cause

The restore view mapped the UI modes incorrectly, and restore execution used the current top-level missing state rather than the state of the selected historical revision. Extraction failures could also be reported as success, allowing deletion to proceed without a complete restore. The legacy folder workflow attempted to extract contentless deletion records.

Behaviour and responsibility boundary

‘All and delete extra’ now restores every selected archive entry successfully before it removes the confirmed deletion candidates. The confirmation dialogue presents a point-in-time restore plan; it does not lock the Vault or revalidate candidates changed while the dialogue is open. If the Vault may have changed during review, the operation must be cancelled and prepared again.

Validation

  • npm run build
  • npm run check:e2e:obsidian
  • npm run lint
  • npm run test:ui — 11 passed
  • deno task test — 68 passed
  • npm run test:e2e:obsidian:legacy-folder-restore
  • npm run test:e2e:obsidian:restore-confirmation
  • npm run test:e2e:obsidian:wake-lock
  • npm run test:e2e:obsidian:mirror-delete-semantics

The mirror E2E covers historical deletion and recreation decisions, extraction failures, write failures, wake-lock lifetimes, and a 24-file deletion plan. The legacy E2E restores an ordinary revision from a real ZIP while skipping a deletion record.

@vrtmrz
vrtmrz marked this pull request as ready for review July 15, 2026 05:50
@vrtmrz
vrtmrz merged commit 6096890 into main Jul 15, 2026
1 check passed
@vrtmrz
vrtmrz deleted the fix-mirror-delete-semantics branch July 15, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant