Skip to content

Fix checkpoint v2 rotation push handling#1148

Merged
pfleidi merged 24 commits into
mainfrom
fix/checkpoints-v2-rotation-logic
May 11, 2026
Merged

Fix checkpoint v2 rotation push handling#1148
pfleidi merged 24 commits into
mainfrom
fix/checkpoints-v2-rotation-logic

Conversation

@pfleidi
Copy link
Copy Markdown
Contributor

@pfleidi pfleidi commented May 8, 2026

https://entire.io/gh/entireio/cli/trails/324

Problem

Archived checkpoints v2 /full/<N> refs are intended to be disjoint cleanup units for raw transcripts. In production, old /full/current data was being merged back into fresh local /full/current after rotation, causing the same checkpoint IDs to appear in many archived generations. That keeps raw transcript objects reachable and prevents git GC from reclaiming old generations.

The failure path was:

  • local rotation archived /full/current into /full/<N> and reset local /full/current
  • pre-push tried to push the fresh /full/current normally
  • the remote rejected it as non-fast-forward
  • recovery treated it as ordinary divergence and tree-merged the remote old /full/current back into the fresh local generation

Fix

  • Record local pending v2 full-generation publications when rotation or migration creates archived /full/<N> refs.
  • In pre-push, publish pending archived generations first, then update remote /full/current with a guarded force-with-lease from the expected previous current hash to the live local current head.
  • Keep /full/current recovery from generic-merging the old generation back after a local rotation.
  • Detect remote rotations more accurately by comparing archive hashes, not just ref-name presence, and fetch candidate remote archives in one batch when resolving rotation conflicts.
  • Fold local-only checkpoints into the related remote archive when another CLI instance already rotated the generation, then adopt the remote fresh /full/current.
  • Queue migration-created archived generations for push and roll back an archive ref if its pending publication cannot be recorded.
  • Push only active v2 refs by default; queued archives are pushed from the pending publication records, and empty ref lists are guarded so git never falls back to pushing the current branch.
  • Harden the pending-publication marker with the shared flock-based lockfile.WithTimeout helper and filtered removal so concurrent hook processes do not drop newly queued publications.

Coverage

Added regression coverage for:

  • local rotation publishing a fresh empty /full/current
  • local rotation followed by new current work before push
  • repeated local rotations before a single push
  • remote User A/User B rotation recovery, including multiple remote rotations
  • same archive ref name with different local/remote hashes
  • migration-created archived generations and rollback when queueing fails
  • pending archive push when no active v2 refs exist
  • lockfile timeout behavior and filtered pending-publication removal

Verification

Ran focused checkpoint/strategy/migration/lockfile regression tests, plus:

go build ./...
go vet ./...
mise run lint

Note

Medium Risk
Changes v2 checkpoint rotation/push behavior and remote conflict recovery around /full/current and archived generations, which can affect data retention/GC if incorrect. Logic is well-covered by new tests but touches concurrency, ref updates, and push-with-lease semantics.

Overview
Fixes v2 /full/current rotation publication so archived generations aren’t accidentally merged back into the fresh generation during push recovery.

Local rotations and migrations now write a pending publication marker (stored under the git common dir) before moving refs; pre-push reads these markers to push archived /full/<N> refs first, then updates remote /full/current via a guarded --force-with-lease, and clears the markers on success.

Tightens rotation conflict handling by detecting remote archive refs by hash mismatch (not just missing refs), batching archive fetches, and merging local-only checkpoints into the related remote archive before adopting the remote fresh /full/current. Also updates ls-remote parsing and adds lockfile.WithTimeout to serialize marker file access, with extensive new regression tests for rotation, migration rollback, and push behavior.

Reviewed by Cursor Bugbot for commit c2446ed. Configure here.

Copilot AI review requested due to automatic review settings May 8, 2026 01:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes v2 checkpoint “full generation” rotation push behavior so that locally-rotated generations are correctly published (including archive refs) and rotation conflicts with remote state are handled more robustly during push/recovery.

Changes:

  • Adds persistent bookkeeping for pending v2 full-generation rotations and publishes pending rotations before pushing refs.
  • Improves rotation-conflict recovery by selecting the related remote archive when the remote has rotated multiple times.
  • Expands push behavior and tests to cover multiple local archives (e.g., migration/repeated rotations) and stale remote archive refs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cmd/entire/cli/strategy/push_v2.go Adds pending-rotation publication, improves remote-rotation conflict handling, and adjusts which refs are pushed.
cmd/entire/cli/strategy/push_v2_test.go Adds tests for local rotation publication, repeated rotations, stale archives, and multi-rotation remote conflict scenarios.
cmd/entire/cli/strategy/cleanup.go Switches ls-remote parsing to strings.SplitSeq.
cmd/entire/cli/checkpoint/v2_read.go Switches ls-remote parsing to strings.SplitSeq.
cmd/entire/cli/checkpoint/v2_pending_rotation.go Introduces on-disk pending-rotation state stored under the git common dir.
cmd/entire/cli/checkpoint/v2_generation.go Records a pending full-rotation marker after successful rotation reset (best-effort).
cmd/entire/cli/checkpoint/v2_generation_test.go Adds coverage ensuring rotation still succeeds if the pending marker cannot be recorded.

Comment thread cmd/entire/cli/strategy/push_v2.go Outdated
Comment thread cmd/entire/cli/strategy/push_v2.go Outdated
Comment thread cmd/entire/cli/strategy/push_v2.go Outdated
pfleidi added 7 commits May 7, 2026 18:30
Cache --git-common-dir on V2GitStore so pending-publication operations
stop forking git rev-parse for every read/write. Read pending
publications once in pushV2Refs and pass the slice down, eliminating
the second locked read inside publishPendingV2FullGenerationPublications.
Skip the atomic rewrite in RemovePendingFullGenerationPublications when
no rows actually matched, and drop the unused
ClearPendingFullGenerationPublications export.

Entire-Checkpoint: b664852f94af
@pfleidi
Copy link
Copy Markdown
Contributor Author

pfleidi commented May 8, 2026

Bugbot run

Comment thread cmd/entire/cli/strategy/push_v2.go Outdated
…tation-logic

# Conflicts:
#	cmd/entire/cli/migrate.go
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread cmd/entire/cli/strategy/push_v2.go
Comment thread cmd/entire/cli/strategy/push_v2.go
@pfleidi
Copy link
Copy Markdown
Contributor Author

pfleidi commented May 9, 2026

Bugbot run

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread cmd/entire/cli/checkpoint/v2_generation.go Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d014d6d. Configure here.

@pfleidi
Copy link
Copy Markdown
Contributor Author

pfleidi commented May 9, 2026

Bugbot run

@pfleidi pfleidi marked this pull request as ready for review May 9, 2026 01:20
@pfleidi pfleidi requested a review from a team as a code owner May 9, 2026 01:20
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c2446ed. Configure here.

@pfleidi pfleidi merged commit b47257b into main May 11, 2026
10 checks passed
@pfleidi pfleidi deleted the fix/checkpoints-v2-rotation-logic branch May 11, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants