Skip to content

Fix phantom file carry-forward causing lingering shadow branches#586

Open
khaong wants to merge 1 commit intomainfrom
alex/more-e2e-fixes
Open

Fix phantom file carry-forward causing lingering shadow branches#586
khaong wants to merge 1 commit intomainfrom
alex/more-e2e-fixes

Conversation

@khaong
Copy link
Contributor

@khaong khaong commented Mar 3, 2026

Summary

  • Fixes E2E failures (TestMixedNewAndModifiedFiles, TestPartialStaging) caused by phantom file paths in filesTouched creating infinite carry-forward loops
  • Phantom files are paths captured from agent transcript tool calls that were never actually created on disk (e.g., Gemini writes src/types.go in a tool call but actually creates src/types/types.go for Go package structure)
  • filesWithRemainingAgentChanges now checks shadow tree existence before carrying forward non-committed files — the shadow tree is the ground truth since buildTreeWithChanges already skips non-existent files

Failing E2E runs

Test plan

  • Added TestFilesWithRemainingAgentChanges_PhantomFile unit test
  • All existing tests pass (mise run test:ci)
  • Lint clean (mise run lint)
  • E2E: TestMixedNewAndModifiedFiles and TestPartialStaging should stop failing for gemini-cli

🤖 Generated with Claude Code

Agent transcript parsers capture file paths from all tool calls, including
ones that were attempted but never created on disk (e.g. agent writes
src/types.go but creates src/types/types.go instead). These phantom paths
in FilesTouched caused filesWithRemainingAgentChanges to always return
non-empty results, creating an infinite carry-forward loop where shadow
branches were never cleaned up.

Fix: for non-committed files, also check the shadow branch tree before
carrying forward. buildTreeWithChanges already skips non-existent files,
so the shadow tree is the ground truth of what was actually checkpointed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 95bb0b3d0af0
Copilot AI review requested due to automatic review settings March 3, 2026 05:36
@khaong khaong requested a review from a team as a code owner March 3, 2026 05:36
@cursor
Copy link

cursor bot commented Mar 3, 2026

PR Summary

Cursor Bugbot is generating a summary for commit 7da41e6. Configure here.

Copy link
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

Fixes carry-forward logic in the manual-commit shadow-branch strategy by preventing “phantom” file paths (captured from agent transcripts but never materialized in the shadow tree) from being repeatedly carried forward, which can create lingering shadow branches and E2E failures.

Changes:

  • Update filesWithRemainingAgentChanges to skip uncommitted paths that aren’t present in the shadow tree (treating the shadow tree as ground truth for what the agent actually produced).
  • Add a unit test covering the phantom-file scenario to prevent infinite carry-forward loops.

Reviewed changes

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

File Description
cmd/entire/cli/strategy/content_overlap.go Adds a shadow-tree existence check before carrying forward uncommitted touched paths.
cmd/entire/cli/strategy/content_overlap_test.go Adds a unit test ensuring phantom transcript paths don’t get carried forward.

Comment on lines +437 to +449
// If file wasn't committed, check if it actually exists in the shadow tree.
// Transcript parsers capture file paths from all tool calls, including ones
// that were attempted but never created (e.g. agent writes src/types.go then
// creates src/types/types.go instead). buildTreeWithChanges skips non-existent
// files, so the shadow tree is the ground truth. Without this check, phantom
// paths cause infinite carry-forward loops.
if _, wasCommitted := committedFiles[filePath]; !wasCommitted {
if _, err := shadowTree.File(filePath); err != nil {
logging.Debug(logCtx, "filesWithRemainingAgentChanges: file not committed and not in shadow tree, skipping",
slog.String("file", filePath),
)
continue
}
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The new "phantom file" check treats any path missing from the shadow tree as skippable when it wasn’t committed. That also matches legitimate agent deletions (deleted files are included in FilesTouched), causing uncommitted deletions to be dropped from carry-forward. Consider only skipping when the path is missing from BOTH the shadow tree and the HEAD/commit tree (or otherwise explicitly handle deletions), and include the underlying shadowTree.File error in the debug log. Adding a unit test for an uncommitted deletion would prevent regressions.

Copilot uses AI. Check for mistakes.
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