Repository navigation
fix(opf): push the v1 commit the OPF rewrite verified, not the branch tip - #2669
Open
peyton-alt wants to merge 1 commit into
Open
peyton-alt wants to merge 1 commit into
peyton-alt wants to merge 1 commit into
Conversation
… tip After the pre-push OPF rewrite, the git-branch path pushed entire/checkpoints/v1 by name, so a checkpoint another session appended between the rewrite and the push shipped without being scanned. v1 now ships as the exact commit the rewrite verified; a later append stays local and is rewritten on the next push. If the remote rejects the pinned push, v1 is still synced with the remote but not retried, since the rebased tip holds unverified commits. OPF skipped or off keeps pushing by name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: 01M47E6JTDJH7F4C49AM56YT9B
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Pinned-push recovery can overwrite a checkpoint appended concurrently during synchronization.
Review effort: Balanced
Findings: 1
What changed in this PR
Pins OPF-protected v1 delivery to the exact verified commit, preventing concurrent unscanned checkpoints from reaching the remote.
Changes:
- Adds hash-pinned push and rejection recovery.
- Routes OPF-rewritten v1 pushes through the pinned path.
- Adds concurrency/rejection tests and updates security documentation.
| File | Description |
|---|---|
docs/security-and-privacy.md |
Documents pinned concurrent-push behavior. |
cmd/entire/cli/strategy/push_common.go |
Implements pinned pushes and recovery. |
cmd/entire/cli/strategy/push_common_test.go |
Tests rejected pinned pushes. |
cmd/entire/cli/strategy/manual_commit_push.go |
Uses the verified OPF hash. |
cmd/entire/cli/strategy/manual_commit_opf_rewrite_test.go |
Tests concurrent post-rewrite appends. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+347
to
+349
| if !src.IsZero() { | ||
| fmt.Fprintf(os.Stderr, "[entire] %s will be pushed on your next push\n", refLabel) | ||
| return false, nil |
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.

https://entire.io/gh/entireio/cli/trails/1491
Problem
On the
git-branchbackend with the OpenAI Privacy Filter (OPF) on, pre-push rewrites the unpushedentire/checkpoints/v1commits and then pushes v1 by name.pushRefIfNeededre-reads the branch, andgit pushresolves it again. If another session appends a checkpoint between the rewrite and the push, that untrailered, unscanned commit becomes the pushed tip.This is on main today. It was found in an adversarial review of the OPF PRs (#2533, #2631) and gets more likely once checkpoints are delivered in the background.
Fix
<verified>:refs/heads/entire/checkpoints/v1. The local branch is never re-read. A zero hash (no v1 yet) pushes nothing.git push <remote> <sha>:refs/heads/...still updates the remote-tracking ref, and its porcelain output parses the same.Tests
TestPrePush_V1PushesTheVerifiedCommitNotALaterAppendappends a checkpoint between the rewrite and the push. The remote gets the verified commit, and the append stays local and untrailered. It fails on main.TestDoPushRefAt_PinnedRejectionSyncsWithoutRetry: a rejected pinned push syncs the local ref without pushing the rebased tip.TestFetchAndRebase_DivergedBranches.mise run checkpasses.Known gap (unchanged)
When Entire's own push is deferred on an empty remote, a user who runs
git push origin entire/checkpoints/v1themselves still pushes by name.🤖 Generated with Claude Code
Note
High Risk
Changes what checkpoint metadata reaches the remote under OPF—a prior bug could ship unscanned privacy-sensitive content; the fix is security-critical but narrowly scoped to the OPF pre-push path.
Overview
Fixes a privacy gap on the git-branch backend when OPF runs at pre-push: after rewriting
entire/checkpoints/v1, the push used the branch name and could ship a newer local checkpoint another session appended between rewrite and push—content that was never OPF-scanned.Pre-push now pins the hash returned by the rewrite and pushes v1 as
<verified>:refs/heads/entire/checkpoints/v1viapushVerifiedRefIfNeeded, without re-reading the local branch tip. OPF-off behavior is unchanged (still push by name).If that pinned push is rejected, the code still syncs the local branch to the remote but does not retry with the rebased tip (which might include unscanned commits); the user is told the ref will go out on the next push.
Tests cover the concurrent-append scenario and pinned-push rejection; security docs note that post-rewrite appends stay local until the next push.
Reviewed by Cursor Bugbot for commit c97efe2. Configure here.