fix(pr-review): force-fetch + verify worktree HEAD matches PR head#175
Merged
Conversation
…rator
The self-approve guard exists so the cube bot can't approve its own
PRs. But `_cube_login()` called `gh api user` against the operator's
gh-auth (e.g. jacsamell) and used that as the cube identity. Result:
the operator was blocked from getting auto-approve on any PR they
authored, even though reviews are posted by `the-agent-cube[bot]` and
have nothing to do with the operator's GitHub account.
When the GitHub App is configured, the cube identity is the bot, not
the operator. New `get_app_login()` in `app_auth.py` derives the bot
login from the App's slug via the JWT-authenticated `/app` endpoint
(GitHub Apps can't call `/user`). Result is cached in-process.
`_cube_login()` now:
* Returns the App bot login (e.g. `the-agent-cube[bot]`) when the
App is configured.
* Falls back to `gh api user` only when no App is set up.
* Fails closed when the App is configured but its login can't be
fetched — better than pretending the operator is the bot.
Verified live: `_cube_login()` returns `'the-agent-cube[bot]'` on a
configured workstation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Symptom: judges kept posting "new" findings against code Roy had already rewritten. Walking through aetheronhq/aetheron-connect-v2#1266, all 10 most recent comments were against pre-rewrite line numbers and content — referenced files/tables/triggers that no longer existed. Root cause: PR was force-pushed (rebase / squash) several times. The review worktree synced via `git fetch origin <head>` got a non-fast- forward and the local ref refused to update. Then `git reset --hard origin/<head>` reset to a stale ref. Judges Read pre-rewrite files and re-raised findings. We logged a warning but proceeded. Three changes: 1. `git fetch --force origin <head> <base>` — handles force-pushes. Failure is now fatal instead of a warning. 2. After reset, `git clean -fdx` — leftover untracked files from a prior round (e.g. moved files) could mask file-list changes. 3. Verify worktree HEAD matches `pr.head_sha` after sync. Abort loud on mismatch with an actionable hint to delete the worktree. Banner now logs the head SHA being synced to so this regression is visible in the run output. Verified live: PR #1266 worktree was stuck at fda636a3 (6 commits behind 62e9fbd1). `git fetch --force` brought it current; HEAD verification would have caught the stale state. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis PR enhances two independent workflows: it introduces GitHub App bot identity caching for auto-approve gating logic, and strengthens the peer-review worktree synchronisation with deterministic cleanup and commit SHA validation. ChangesGitHub App Bot Identity Resolution
Deterministic PR Review Worktree Sync
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Comment |
jacsamell
added a commit
that referenced
this pull request
May 19, 2026
…med judges Symptom: cube panel kept posting findings against pre-rewrite code on aetheronhq/aetheron-connect-v2#1266 even after PR #175's --force fetch landed. Same 10+ findings against lines/tables that no longer exist. Two more layers of the bug surfaced: (1) Duplicate worktrees, only one synced. PR reviews historically used `~/.cube/worktrees/<project>/pr-<n>/` (legacy, created by `_prefetch_worktrees`). PR #172 added a second one at `pr-review-<n>/` for the new file-routing flow. Both worktrees existed in parallel; only the new one had the --force fetch + HEAD verification from #175. The other stayed pinned to whatever it was last synced to. Worse: `build_peer_review_prompt` told judges to Read from the LEGACY path, while `_apply_file_scope` told them to Read from the NEW path. Same prompt, two locations. Confirmed live: both worktrees existed on PR #1266; the legacy one was stuck at fda636a3 (6 commits behind 62e9fbd1). (2) Resumed judges had stale session memory. Sessions persist across panel runs. On the next run, the LLM continues its prior conversation — including its prior reasoning about file contents, line numbers, function shapes. Even when the resumed judge Reads fresh files, its reasoning anchors on the old memory. The previous "RE-REVIEW" hint was too soft to displace it. Fixes: * Skip `_prefetch_worktrees` in PR-review mode when a dedicated `review_worktree` was passed. The new sync is authoritative; the legacy sync just made a second stale copy. * Pipe `review_worktree` through `build_peer_review_prompt` so the prompt's worktree path matches the file-scope block. One location. * Replace the meek "verify commit" hint with a hard "CURRENT HEAD" callout that names the SHA, says "your prior reasoning may be out of date", and lists 4 explicit steps: Re-Read fresh, verify each prior finding still applies, add new ones, drop the rest. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3 tasks
jacsamell
added a commit
that referenced
this pull request
May 19, 2026
…med judges (#176) * fix(pr-review): eliminate stale legacy worktree + signal HEAD to resumed judges Symptom: cube panel kept posting findings against pre-rewrite code on aetheronhq/aetheron-connect-v2#1266 even after PR #175's --force fetch landed. Same 10+ findings against lines/tables that no longer exist. Two more layers of the bug surfaced: (1) Duplicate worktrees, only one synced. PR reviews historically used `~/.cube/worktrees/<project>/pr-<n>/` (legacy, created by `_prefetch_worktrees`). PR #172 added a second one at `pr-review-<n>/` for the new file-routing flow. Both worktrees existed in parallel; only the new one had the --force fetch + HEAD verification from #175. The other stayed pinned to whatever it was last synced to. Worse: `build_peer_review_prompt` told judges to Read from the LEGACY path, while `_apply_file_scope` told them to Read from the NEW path. Same prompt, two locations. Confirmed live: both worktrees existed on PR #1266; the legacy one was stuck at fda636a3 (6 commits behind 62e9fbd1). (2) Resumed judges had stale session memory. Sessions persist across panel runs. On the next run, the LLM continues its prior conversation — including its prior reasoning about file contents, line numbers, function shapes. Even when the resumed judge Reads fresh files, its reasoning anchors on the old memory. The previous "RE-REVIEW" hint was too soft to displace it. Fixes: * Skip `_prefetch_worktrees` in PR-review mode when a dedicated `review_worktree` was passed. The new sync is authoritative; the legacy sync just made a second stale copy. * Pipe `review_worktree` through `build_peer_review_prompt` so the prompt's worktree path matches the file-scope block. One location. * Replace the meek "verify commit" hint with a hard "CURRENT HEAD" callout that names the SHA, says "your prior reasoning may be out of date", and lists 4 explicit steps: Re-Read fresh, verify each prior finding still applies, add new ones, drop the rest. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * revert(pr-review): use the original pr-<n>/ worktree, drop pr-review-<n>/ PR #172 invented `pr-review-<n>/` as a parallel worktree to hold the file-routing flow's check-out. The original `pr-<n>/` (managed by `_prefetch_worktrees` for the cube panel + `_get_cli_review_worktrees` for CodeRabbit) kept existing alongside it. Result: two worktrees per PR, only one kept synced by the new code, prompts pointing at the wrong one, judges Reading stale content. Reverting the path so the file-routing flow reuses `pr-<n>/`. Combined with the #176 skip-`_prefetch_worktrees`-when-already-synced logic, this gives one worktree per PR with the new --force fetch + HEAD verification applied to it. CodeRabbit and cube judges both read from the same place. `pr-review-<n>/` orphan dirs deleted from the local cache; `git worktree prune` cleaned the stale refs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced May 19, 2026
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.
Symptom
Roy reported judges posting 10 "new" findings on aetheronhq/aetheron-connect-v2#1266 that were all against pre-rewrite line numbers and content — referencing files/tables/triggers that no longer existed in the PR.
Root cause
PR was force-pushed (rebase / squash) several times. The review worktree at `~/.cube/worktrees//pr-review-/` was synced via `git fetch origin ` without `--force`. On force-push, the local ref refused to fast-forward and silently stayed stale. `git reset --hard origin/` then reset to the old ref. Judges Read pre-rewrite files. We logged a warning and proceeded.
Confirmed live: worktree HEAD was at `fda636a3` (May 19 12:29) while the actual PR head was `62e9fbd1` — 6 commits behind including the rewrites that obsoleted the cube findings.
Fix
Test plan
🤖 Generated with Claude Code
Summary
This PR fixes a critical issue where judges posted incorrect findings after PR force-pushes due to stale review worktrees. The root cause was that
git fetchwithout--forcefailed to update local refs during force-pushes, causing subsequent resets to stale commits.Changes
peer_review.py – Strengthened worktree synchronisation to be deterministic and fail-fast:
git fetch --force(failures now fatal)git clean -fdxafter reset to remove stale untracked filesauto_approve.py – Improved cube identity resolution:
app_auth.py – Added GitHub App bot login discovery:
get_app_login()function that fetches and caches the App's bot login via/appendpointNonegracefully if not configured or if the API response lacks required fieldsOutcome
Eliminates the risk of running judges against stale PR content after force-pushes, ensuring findings map to correct line numbers and content. Force-push detection is now explicit and actionable rather than silent and error-prone.