| … | … | @@ -337,6 +338,41 @@ export const make = Effect.gen(function* () { | |
| 346 | + | .execute({ | |
| 347 | + | operation: "GitWorkflowService.currentBranch", | |
| 348 | + | cwd, | |
| 349 | + | args: ["symbolic-ref", "--quiet", "--short", "HEAD"], | |
🟡 Medium git/GitWorkflowService.ts:349
When a tag and branch are both named release, currentBranch returns heads/release instead of release, so VcsStatusBroadcaster.updateCachedRemoteStatus rejects remote results because the branch does not match local.refName. symbolic-ref --short retains the heads/ prefix when the name is ambiguous; read the full ref and strip the literal refs/heads/ prefix.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/server/src/git/GitWorkflowService.ts around line 349: |
| 2 | |
| 3 | When a tag and branch are both named `release`, `currentBranch` returns `heads/release` instead of `release`, so `VcsStatusBroadcaster.updateCachedRemoteStatus` rejects remote results because the branch does not match `local.refName`. `symbolic-ref --short` retains the `heads/` prefix when the name is ambiguous; read the full ref and strip the literal `refs/heads/` prefix. |
[from Codex]: Fixed in 2f13197384. Reads the full symbolic ref and strips only refs/heads/. A real Git regression covers the release tag/branch collision and a branch literally named heads/release.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
Verified on the maintainer rebuild 91d904d48a: currentBranch reads the full symbolic ref and removes only refs/heads/. The real Git/process-boundary regression covers both the release branch/tag collision and a branch literally named heads/release. Both independent full-diff reviews rechecked this finding; resolving as fixed.
| … | … | @@ -374,14 +451,12 @@ export const make = Effect.gen(function* () { | |
| 456 | + | if (remoteRead.branchChanged || local.refName !== remoteRead.branch) { | |
| 457 | + | local = yield* refreshLocalStatusCore(cwd); | |
| 458 | + | } | |
| 459 | + | return yield* updateCachedStatus(cwd, local, remoteRead.remote, remoteRead.branch); | |
🟡 Medium vcs/VcsStatusBroadcaster.ts:456
When getStatus detects a branch switch, it caches the discarded remote lookup as a confirmed null, so later calls treat the new branch's remote status as complete and refreshPullRequestStatus skips it. Return the refreshed local status without calling updateCachedStatus on this path, leaving the remote cache unknown so it can be fetched later.
| 1 | if (remoteRead.branchChanged) { |
| 2 | local = yield* refreshLocalStatusCore(cwd); |
| 3 | return mergeGitStatusParts(local, null); |
| 4 | } |
| 5 | if (local.refName !== remoteRead.branch) { |
| 6 | local = yield* refreshLocalStatusCore(cwd); |
| 7 | } |
| 8 | return yield* updateCachedStatus(cwd, local, remoteRead.remote, remoteRead.branch); |
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/server/src/vcs/VcsStatusBroadcaster.ts around lines 456-459: |
| 2 | |
| 3 | When `getStatus` detects a branch switch, it caches the discarded remote lookup as a confirmed `null`, so later calls treat the new branch's remote status as complete and `refreshPullRequestStatus` skips it. Return the refreshed local status without calling `updateCachedStatus` on this path, leaving the remote cache unknown so it can be fetched later. |
[from Codex]: Fixed in 2f13197384. The branch-switch path refreshes local state without caching the discarded remote result. Regression tests reproduce the poisoned cache and verify recovery through both getStatus and refreshPullRequestStatus.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
Verified on the maintainer rebuild 91d904d48a: a discarded read returns outer null and updateCachedRemoteStatus keeps it unknown, rather than storing a confirmed null entry. The retained behavior test verifies a later permitted turn-end refresh recovers the new branch PR while paused policy prevents work. Both independent full-diff reviews rechecked the cache distinction; resolving as fixed.