fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(web): refresh pull request diff after updates - #7167

Closed
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state
Closed

fix(web): refresh pull request diff after updates#7167
stephenjason89 wants to merge 7 commits into
pingdotgg:mainfrom
stephenjason89:fix/pr-diff-latest-state

Conversation

@stephenjason89

@stephenjason89stephenjason89 commented Aug 16, 2026

Copy link
Copy Markdown

Problem

After a pull request receives new commits, the detail header can update while the Code tab's All commits diff remains on an older aggregate snapshot. Switching to a commit and back exposes the stale aggregate until the user explicitly refreshes it.

The detail panel keeps the aggregate diff query warm, but live refresh previously refreshed only detail and activity data. The aggregate diff query therefore remained mounted with stale data.

Fix

  • Observe same-PR updatedAt revisions and invalidate the host cache when the revision advances.
  • Refresh the aggregate diff and reset Code-tab pagination after invalidation.
  • Guard asynchronous invalidation so a completion from an older PR or revision cannot refresh the currently displayed PR.
  • Continue refreshing immutable commit-scoped diffs directly without issuing a duplicate aggregate request.

Validation

  • Focused pull-request detail and diff tests: 72 passed.
  • @t3tools/web typecheck passed.
  • Targeted lint and format checks passed.
  • git diff --check passed.
  • Added a deferred-invalidation regression test proving stale async completions are ignored.

Built with GPT-5.6 in the Codex harness through T3 Code.

Note

Refresh pull request diff after updates using snapshot coordination

  • Introduces a createPullRequestDiffRefreshCoordinator in pullRequestDetail.logic.ts that manages diff refresh with a latest-wins strategy, skipping redundant refreshes and surfacing failures via an alert banner.
  • PullRequestDetailPanel now drives diff refresh through the coordinator: builds a PullRequestCodeSnapshot (detail + first-page aggregate diff) and applies it coherently, replacing the previous eager warm-up and refreshToken approach.
  • PullRequestCodeTab boots from the snapshot, defers diff queries until the snapshot is available, handles aggregate pagination manually with per-cursor retry, and shows PullRequestCodeRefreshFailure on refresh errors without losing displayed content.
  • Server-side, GitHub, GitLab, and Bitbucket providers now return diffRevision (base/head OIDs) on PR detail; PullRequestService uses these to separate aggregate diff cache invalidation from commit-scoped diff and detail invalidation via resource: "diff".
  • Behavioral Change: calling invalidate with resource: "diff" now only busts the aggregate diff cache, leaving detail and commit diff caches intact. Aggregate diff cache keys now include a second epoch slot, so existing cached keys are structurally incompatible.

Macroscope summarized 91a29c6.


Note

Medium Risk
Touches PR caching, multi-host detail decoding, and async refresh coordination; incorrect epoch or coordinator ordering could show stale diffs or skip updates, but behavior is heavily covered by new service and logic tests.

Overview
Fixes All commits staying stale after new pushes while the detail header updates, by tying aggregate diff freshness to immutable base/head OIDs and a dedicated refresh path.

Server & contracts: Optional diffRevision (baseOid / headOid) is populated from GitHub (extra gh api after detail), GitLab (diff_refs), and Bitbucket (source/destination commit hashes). invalidate accepts resource: "diff" to bump only the aggregate diff epoch; commit-scoped diffs use a separate epoch and are not cleared on diff-only invalidation. Epoch maps advance a fallback on LRU eviction so evicted scopes cannot reuse stale cache keys.

Web:PullRequestDetailPanel drops eager diff warm-up and refreshToken; a createPullRequestDiffRefreshCoordinator invalidates diff cache, re-reads detail+activity, fetches the first aggregate page, and applies a versioned snapshot. PullRequestCodeTab bootstraps from that snapshot, shows loading/error and stale diff + retry banners on refresh failure, and pages aggregate vs commit diffs separately (shouldRefreshAppliedCommitDiff for same-commit snapshot bumps).

Reviewed by Cursor Bugbot for commit 91a29c6. Bugbot is set up for automated code reviews on this repo. Configure here.

Closes#7310

@coderabbitai

coderabbitaiBot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e48ed2e-3892-4ca7-b6c6-d947ebf672bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026
@stephenjason89
stephenjason89 marked this pull request as ready for review August 16, 2026 07:12
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@macroscopeapp

macroscopeappBot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

Introduces substantial new async coordination infrastructure (createPullRequestDiffRefreshCoordinator) for managing diff refreshes, adds diffRevision tracking across all git providers, and implements new epoch-based cache invalidation. The complexity of the new state machine and cross-cutting changes warrant design review.

You can customize Macroscope's approvability policy. Learn more.

@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 16, 2026

@macroscopeappmacroscopeappBot 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.

One finding on header rendering in PullRequestDetailPanel.tsx. Everything else in the diff keeps using the shared primitives (Button, Empty-based unavailable state, DiffPanelLoadingState) and preserves the existing class strings and accessibility attributes.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new Code-tab bootstrap states. The earlier header regression (branch pair / diff stat disappearing) is resolved by the codeTabDetail ?? detail fallback.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
Comment threadapps/web/src/components/pullRequest/PullRequestDetailPanel.tsx Outdated
@stephenjason89
stephenjason89force-pushed the fix/pr-diff-latest-state branch from 6e35c7c to 6a00946CompareAugust 17, 2026 10:07

@macroscopeappmacroscopeappBot 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.

Two findings in the new Code tab diff-refresh UI. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment threadapps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a00946. Configure here.

Comment threadapps/server/src/pullRequest/gitHubPullRequestJson.ts Outdated

@macroscopeappmacroscopeappBot 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.

One finding on the new diff-refresh banner in PullRequestCodeTab.tsx. The earlier bootstrap-path and header-gating issues look resolved at this head.

Posted via Macroscope — UI Consistency

Comment on lines +246 to +259
return (
<div
role="alert"
className="flex shrink-0 items-start gap-2 border-b border-amber-500/25 bg-amber-500/8 px-3 py-2 text-xs"
>
<TriangleAlertIcon
aria-hidden
className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
/>
<div className="min-w-0 flex-1">
<p className="font-medium text-foreground">Could not refresh pull request diff</p>
<p className="mt-0.5 text-muted-foreground">Showing the last loaded version. {error}</p>
</div>
<Button size="xs" variant="outline" className="shrink-0" onClick={onRetry}>

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.

The banner's Retry has no in-flight state, so pressing it looks inert. bootstrapError is only cleared once the whole invalidate → detail/activity reread → aggregate diff chain resolves (setFailure(null) in the coordinator), so for several round trips the reader sees the identical "Could not refresh…" text and a fully enabled button, and repeated presses just re-enqueue the same lane. The bootstrap branch of this same component already tracks bootstrapRetryPending and swaps to the loading state, so the two retry affordances for one action now behave differently.

Smallest fix: give PullRequestCodeRefreshFailure an optional pending prop, pass bootstrapRetryPending at both render sites (line 1394 and line 1490), and use it to disable the Button (e.g. disabled={pending}, optionally animate-spin on RefreshCwIcon) so the control reports the in-flight refresh like the rest of the panel's retries.

Posted via Macroscope — UI Consistency

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Pull-request detail and diff refresh already shipped in #7148.

@t3dotggt3dotgg closed this Aug 23, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request All commits diff stays stale after new commits

2 participants

@stephenjason89@t3dotgg