Skip to content

fix(checkpoint): skip checkpoint push on fork instead of leaking to origin#1776

Draft
pjbgf wants to merge 1 commit into
mainfrom
fork-remote
Draft

fix(checkpoint): skip checkpoint push on fork instead of leaking to origin#1776
pjbgf wants to merge 1 commit into
mainfrom
fork-remote

Conversation

@pjbgf

@pjbgf pjbgf commented Jul 16, 2026

Copy link
Copy Markdown
Member

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

When a private checkpoint_remote is configured but the push remote is a fork (its owner differs from the checkpoint target owner), the pre-push hook silently fell back to pushing checkpoints to the fork's origin. For a public fork this published session transcripts, defeating the private checkpoint target.

Treat the fork owner-mismatch as a distinct signal (ForkOwnerMismatchError) rather than a benign origin fallback: skip the checkpoint push and warn the user once, naming both opt-in paths — repoint checkpoint_remote at their own private repo, or set "checkpoint_remote": null to accept the fork as target. Other origin fallbacks (no target configured, unparseable URL, derivation failure) are unchanged.


Note

High Risk
Changes checkpoint push routing for fork workflows and prevents accidental publication of session transcripts; behavior is security-sensitive though the change is fail-closed with user-facing guidance.

Overview
Fixes a privacy leak: with a private checkpoint_remote configured, pushing from a fork (push remote owner ≠ checkpoint target owner) used to fall back and could publish session transcripts to the fork.

PushURL now returns ForkOwnerMismatchError instead of the fork/origin URL when owners differ. resolvePushSettings sets skipCheckpointPush and keeps fork details for messaging. Pre-push skips checkpoint pushes (both git-branch and git-refs paths) and prints a one-time stderr warning with opt-in steps (repoint checkpoint_remote to your private repo or set "checkpoint_remote": null). PushQueuedCheckpointRefs surfaces the same mismatch as an error for foreground “push now” flows.

Fetch behavior is unchanged—reading checkpoints from the configured target still works on forks. Other benign fallbacks (unparseable remotes, no target, derivation failures) are unchanged.

Reviewed by Cursor Bugbot for commit fc07b7b. Configure here.

…rigin

When a private checkpoint_remote is configured but the push remote is a
fork (its owner differs from the checkpoint target owner), the pre-push
hook silently fell back to pushing checkpoints to the fork's origin. For
a public fork this published session transcripts, defeating the private
checkpoint target.

Treat the fork owner-mismatch as a distinct signal (ForkOwnerMismatchError)
rather than a benign origin fallback: skip the checkpoint push and warn the
user once, naming both opt-in paths — repoint checkpoint_remote at their own
private repo, or set "checkpoint_remote": null to accept the fork as target.
Other origin fallbacks (no target configured, unparseable URL, derivation
failure) are unchanged.

Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Paulo Gomes <paulo@entire.io>
Entire-Checkpoint: 01KXNKES28422FTSW8FZQ66JTF
Copilot AI review requested due to automatic review settings July 16, 2026 14:10
@pjbgf
pjbgf requested a review from a team as a code owner July 16, 2026 14:10
@pjbgf

pjbgf commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 fc07b7b. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 hardens checkpoint pushing behavior to prevent inadvertent publication of session transcripts when a repo has a dedicated checkpoint_remote configured but the user’s push remote is a fork (owner mismatch). It introduces an explicit fork-owner-mismatch signal so the pre-push hook fails closed by skipping checkpoint pushes and guiding the user toward explicit opt-in configurations.

Changes:

  • Introduces ForkOwnerMismatchError from checkpoint remote URL resolution, replacing the previous “fallback to push remote” behavior on owner mismatch.
  • Updates strategy push resolution and pre-push execution to skip checkpoint pushes on fork owner mismatch (while preserving existing benign fallback cases).
  • Adds/updates unit and integration tests to validate the new fork-mismatch behavior and user-facing messaging.

Reviewed changes

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

Show a summary per file
File Description
cmd/entire/cli/strategy/manual_commit_push.go Skips checkpoint push on fork-owner mismatch and emits a warning; surfaces mismatch as an error for foreground “push now” flows.
cmd/entire/cli/strategy/manual_commit_push_test.go Adds a unit test for the fork skip warning message formatting/content.
cmd/entire/cli/strategy/checkpoint_remote.go Extends push settings resolution to recognize fork mismatch via errors.As and mark checkpoint pushing as skipped.
cmd/entire/cli/strategy/checkpoint_remote_test.go Updates tests to assert fork mismatches skip checkpoint pushes instead of falling back.
cmd/entire/cli/integration_test/remote_operations_test.go Clarifies the integration test’s “derivation failure fallback” case vs the new fork mismatch path.
cmd/entire/cli/checkpoint/remote/util.go Adds ForkOwnerMismatchError and changes PushURL to return it on owner mismatch rather than returning a fallback URL.
cmd/entire/cli/checkpoint/remote/util_test.go Updates PushURL tests to expect ForkOwnerMismatchError for owner mismatches.

}
return fmt.Sprintf(
"[entire] Checkpoints were NOT pushed.\n"+
"This repo sends checkpoints to a private target (%s), but your push remote is a\n"+
@pjbgf
pjbgf marked this pull request as draft July 16, 2026 14: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.

2 participants