feat(sync): Rebuild from iCloud — self-serve full resync (#300) - #303
Merged
Conversation
Adds a sync_rebuild command that discards the local materialized view of synced data and reconstructs it from the peer snapshots and event logs in the shared folder. One-way pull — nothing in iCloud is deleted or rewritten beyond the device's own log/snapshot/manifest. Sequence: pre-wipe fold tick (drains the outbox and materializes tombstones for not-yet-applied own deletes) → sealed bootstrap publish (re-applies the full own log under the outbox seal, failing closed on apply errors, so no own event can be masked by the snapshot id) → rebuild marker in the local-only settings table → one wipe tx clearing the eight synced tables and every replay watermark under the tick lock → full replay → marker cleared only on a complete un-cancelled pass. The whole state machine is single-flight; an interrupted or cancelled rebuild resumes on the next launch from either engine-boot site. Cancellation uses a monotonic generation captured inside the serialized section, with gates before every destructive step. Deviation from the spec: translations is preserved, not wiped — it has no replay source (snapshots don't carry it, its events are no-ops since #263), and it's already dropped on dev DBs stamped by a deleted migration 14. UI: danger-styled Resync row + confirm dialog in Library Sync settings (disabled with the paused tooltip in queue-only mode), two-phase progress through the existing sidebar chip, en/zh strings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #300.
What
A Resync action in Library Sync settings that discards the local materialized view of synced data and reconstructs it from the peer snapshots and event logs in the shared folder. One-way pull — nothing in iCloud is deleted or rewritten beyond the device's own log/snapshot/manifest. Escape hatch for diverged/stuck sync (#298).
How
sync_rebuildruns, single-flight and serialized:settingstable, then one wipe transaction clearing the eight synced tables and every_replay_statewatermark, under the tick lock.tick_with_progress(covers cover re-ingest and drives the existing sidebar progress chip), marker cleared only on a complete, un-cancelled pass.Interrupted/cancelled rebuilds resume on next launch from both engine-boot sites; retries and
sync_enableare marker-aware so a wiped/partial DB can never be published over the recovery snapshot. Cancellation uses a monotonic generation captured inside the serialized section, with gates before every destructive step.Spec deviation:
translationsis preserved rather than wiped — no replay source exists (snapshots don't carry it; its events are no-ops since #263), and the table is already dropped on dev DBs stamped by a since-deleted migration 14. Spec should be updated nine → eight tables.Testing
🤖 Generated with Claude Code