Skip to content

fix(web): a closed proactive diff stays closed when you return to a thread - #14705

Open
ilyaliao wants to merge 1 commit into
pingdotgg:mainfrom
ilyaliao:fix/proactive-diff-offer-once
Open

ilyaliao wants to merge 1 commit into
pingdotgg:mainfrom
ilyaliao:fix/proactive-diff-offer-once

Conversation

@ilyaliao

@ilyaliao ilyaliao commented Oct 2, 2026 •

Copy link
Copy Markdown

Problem

With Proactive panels on, closing a completed turn's diff does not stick. Switch to another thread and back, or reload, and the same turn's diff opens again. This is #11636, which the triage marked accepted. The user-choice revision that openProactive checks is re-read on every thread entry and never persisted, so a close from an earlier visit is invisible to the next one.

Fix

The persisted per-thread panel state records proactiveDiffTurnId, the last turn whose diff was offered automatically. A diff request now carries its turn, and openProactive refuses a turn it already offered. It records the offer even when it refuses because the user picked another surface or a pull request has priority, so a revisit does not retry. updateThreadStateMap keeps the record when other panel actions rebuild the thread state, the record keeps an emptied panel's entry from being pruned, and it is restored on reload. A new turn is still offered once, so #10610's on-entry behavior is unchanged for turns this client has not offered.

Split out of #13593 as requested there.

Before / after

Closing the diff, switching threads, and coming back:

Before After
proactive-diff-reopen-before.mp4
proactive-diff-reopen-after.mp4

Recorded for #13593. Thread A has uncommitted changes, so its diff opens on entry in both builds, and that PR's working-tree check does not affect this flow. The Before build runs the changed files reverted to main, which is why they appear in its working tree.

Verification

  • vp test run apps/web/src/rightPanelStore.test.ts apps/web/src/components/ChatView.logic.test.ts: 205 passed. New cases cover hide then reload, close the last tab then reload, dismissing then opening a file, the Files surface, or a pull request then reloading, a declined offer not retrying, and the next turn still opening.
  • Removing each guard fails the suite: the offered-turn check (6 failures), keeping the record across rebuilt states (3), keeping an emptied panel's entry (1), and restoring the record on reload (5).
  • tsc --noEmit -p apps/web: 0 errors.
  • Web dev client on this branch, seeded with a copy of real data. Entering a thread auto-opened its diff and recorded the turn. After hiding it, switching to another thread, and reloading back into it, the panel stayed closed.

Made with Claude Opus 5.5 in Claude Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 2, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 2, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 68db8d9

Macroscope's review found this PR approvable — This is a focused web bug fix that persists which completed turn's diff was offered, preventing the same proactive panel from reopening after dismissal or reload while preserving later-turn behavior. The change is localized, backward-compatible, and accompanied by targeted tests, with no product-default, deployment, API, or static-analysis changes.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 28582089-1509-47a6-964a-3efc6625892d

📥 Commits

Reviewing files that changed from the base of the PR and between 68db8d9 and ed76c75.


📒 Files selected for processing (2)
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/rightPanelStore.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Walkthrough

Walkthrough

ChatView now includes the completed turn ID in proactive diff requests. The right-panel store tracks offered turns, checks whether a diff can open, and restores the offer marker from persisted thread state. Tests cover dismissal, reload, repeat offers, later turns, and user-selected panels.

Changes

Proactive diff offers

Layer / File(s) Summary
Turn-scoped request state and persistence
apps/web/src/rightPanelStore.ts
The right-panel state and request type track diff offers by turn ID. Thread updates preserve the marker, and persisted state restores it.
Proactive diff offer flow
apps/web/src/components/ChatView.tsx, apps/web/src/rightPanelStore.ts, apps/web/src/rightPanelStore.test.ts
ChatView sends the completed turn ID with a diff request. The store prevents repeat offers for that turn, checks whether the diff can open, and records the turn even when it does not open. Tests cover dismissal, persistence, later turns, and user-selected panels.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ChatView
  participant RightPanelStore
  participant PersistedThreadState
  ChatView->>RightPanelStore: Request diff offer with completed turnId
  RightPanelStore->>RightPanelStore: Check prior offer and opening conditions
  RightPanelStore->>PersistedThreadState: Retain proactiveDiffTurnId
Loading

Possibly related PRs

Suggested reviewers: t3dotgg


Merge Risk | ⚪ Minimal · up to ed76c

Merge Risk: ⚪ Minimal · up to ed76c

The change preserves dismissed diff offers across return visits and reloads. No merge-blocking issue was established.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to ed76c

The change remembers automatic diff offers across thread visits and reloads while preserving user-choice and pull-request priority checks. The verified changes affect panel behavior, not access permissions or the data a diff can retrieve.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The verified delta affects browser-resident panel preferences for scoped threads. Even a manipulated marker influences automatic offer suppression rather than granting additional diff access; persistence retains existing browser-origin storage authority.

Trust Boundaries and Controls

  • observed — Automatic diff opening still requires the expected per-thread user-action revision and no active pull-request surface. These are UI-choice controls, not server authorization controls. Recording a refused offer does not open the panel or bypass those checks.

Resilience and Maintainability Implications

  • observed — Offer admission and its marker are updated together in the right-panel state transition. Branch selection and the optional post-open callback occur afterward in separate steps. The source establishes this ordering, but does not establish transactional durability across storage failure, interruption, or concurrent browser tabs.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary fix: preventing a closed proactive diff from reopening when returning to a thread.
Description check Passed The description explains the problem, fix, scope, before-and-after behavior, focused tests, type-check result, and manual verification. It uses “Fix” instead of the template’s “Change” heading and omi…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 2, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 2, 2026 05:33

Dismissing prior approval to re-evaluate 43179b6

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 2, 2026
@ilyaliao
ilyaliao force-pushed the fix/proactive-diff-offer-once branch from 43179b6 to 410c41d Compare October 3, 2026 03:48
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 3, 2026 03:48

Dismissing prior approval to re-evaluate 410c41d

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 3, 2026
@ilyaliao
ilyaliao force-pushed the fix/proactive-diff-offer-once branch from 410c41d to 5625739 Compare October 6, 2026 17:48
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 6, 2026 17:49

Dismissing prior approval to re-evaluate 5625739

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 6, 2026
@ilyaliao
ilyaliao force-pushed the fix/proactive-diff-offer-once branch from 5625739 to 68db8d9 Compare October 7, 2026 14:31
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 7, 2026 14:31

Dismissing prior approval to re-evaluate 68db8d9

Proactive panels reopened a completed turn's diff on every thread visit
because the user-choice revision is re-read on entry and never persisted.
Remember the last offered turn in the persisted panel state, keep it when
other panel actions rebuild the state, and refuse a turn already offered.
@ilyaliao
ilyaliao force-pushed the fix/proactive-diff-offer-once branch from 68db8d9 to ed76c75 Compare October 12, 2026 16:29
@vwgp8wkgjz-beep

Copy link
Copy Markdown

Still reproduces on the macOS desktop app, nightly 0.0.46-nightly.20261013.3053 (server running on Linux), with Proactive panels on. In multiple threads, the diff panel reopens every time I enter the thread, even after I close it. Turning Proactive panels off works around it. Would be glad to see this merged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants