Skip to content

[claude] Roll snapshots back to a checkpoint when a commit arrives out of order - #106

Closed
myieye wants to merge 3 commits into
mainfrom
claude/harmony-105-repro-tests-vw0vvt
Closed

[claude] Roll snapshots back to a checkpoint when a commit arrives out of order#106
myieye wants to merge 3 commits into
mainfrom
claude/harmony-105-repro-tests-vw0vvt

Conversation

@myieye

@myieye myieye commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

[Claude, autonomous]

Fixes #105. The first commit adds the repro tests (LateCommitTests, one theory case of each fails on main), the second the fix.

  • A late commit deleted the snapshots after it and replayed from each entity's newest surviving snapshot. That snapshot can predate edits whose snapshots a sync batch pruned, so the replay lost them and revived cascade-deleted entities (the FK failure in production).
  • New local-only Commit.IsSnapshotCheckpoint ([JsonIgnore], like Hash): the last commit of every snapshot update is a checkpoint, meaning the snapshot table is complete as of that commit. A late commit rolls back to the newest checkpoint before it and replays everything after it; commits replayed inside that batch lose the flag. SnapshotCheckpointTests pins that contract for Refactor snapshot selection #34/Implement snapshot cleanup #35/Refactor snapshot selection #36.
  • Schema change: one non-nullable bool column on Commits, consumers need a migration (EF scaffolds defaultValue: false).
  • Existing databases have no checkpoints, so their first late commit replays from scratch (also heals snapshots the old rollback corrupted). Appends never roll back, so a healthy legacy DB accumulates checkpoints without ever paying that. An already-corrupted DB (FwHeadless) should run RegenerateSnapshots once, since flagging its head would preserve the corruption.
  • RegenerateSnapshots now runs under the lock and in a transaction, so flags and snapshots move together.
  • Not in this PR: GetAtCommit/GetBeforeCommit/GetSnapshotsAtCommit seed a replay the same way and have the same staleness (plus a double-apply of other entities' changes); they can use the checkpoint later. Making the sampler keep each entity's state at checkpoints inside a batch would make hub rollbacks cheaper and fits PR Refactor snapshot selection #34's post-pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_017BaNW6P4wKvx82fgvh7q1j


Generated by Claude Code

myieye and others added 2 commits September 2, 2026 20:34
A late commit makes the replica delete the snapshots after it and replay
from the newest surviving snapshot of each entity. That snapshot can
predate edits that a sync batch pruned, so the replay loses them, or
revives an entity that a cascade delete only ever recorded as a snapshot.

Covers both parities of the intermediate snapshot pruning, so one case of
each theory fails today.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BaNW6P4wKvx82fgvh7q1j
A late commit used to delete the snapshots after it and replay from each
entity's newest surviving snapshot. That snapshot can predate edits whose
snapshots a sync batch pruned, so the replay lost them and revived
cascade-deleted entities (#105).

Mark the last commit of every snapshot update as a checkpoint: the
snapshot table is complete as of that commit. A late commit now rolls
back to the newest checkpoint before it and replays everything after it.
Commits replayed inside that batch lose their checkpoint. Existing
databases have no checkpoints, so their first late commit replays from
scratch, which also heals snapshots the old rollback corrupted.

Also runs RegenerateSnapshots under the lock and in a transaction, so
checkpoints and snapshots move together.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BaNW6P4wKvx82fgvh7q1j
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@myieye

myieye commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Superceded by #107

@myieye myieye closed this Sep 4, 2026
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.

[claude] Snapshot rollback resumes from a stale snapshot and loses intermediate state

1 participant