Skip to content

fix(web): pull request header no longer flashes back to the pre-action state - #29400

Open
Brechard wants to merge 2 commits into
pingdotgg:mainfrom
Brechard:fix/pr-header-action-outcome
Open

Brechard wants to merge 2 commits into
pingdotgg:mainfrom
Brechard:fix/pr-header-action-outcome

Conversation

@Brechard

@Brechard Brechard commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Note

🤖 This PR was prepared by Claude Code (Claude Opus 5.5) on behalf of @Brechard.

Problem

After an action from the pull request header succeeds (Ready for review, Convert to draft, Close, Reopen, Enable or Disable auto-merge), the header briefly shows the old controls again. finishAction in PullRequestDetailPanel.tsx clears the pending state as soon as the host accepts the action, but the refetch it starts is not awaited. The header redraws from the pre-action detail until the new detail arrives, so on a draft that was just closed, Ready for review comes back enabled for about a second before Closed appears. Expected: once the host confirms the action, the header shows its result.

Repro: open a draft PR in the Pull requests page, then pick ⋯ → Close pull request → Confirm close.

Change

When the host confirms one of those actions, the detail applies its known outcome (state, isDraft or autoMergeEnabled) on top of the fetched detail. Each field is dropped once fetched data agrees with it, or after the same 60 s trust window the PR list already uses for its row overrides (PULL_REQUEST_OVERRIDE_TRUST_MS, now exported). A failed action changes nothing, and merge is left alone because it can be queued rather than done. The override lives in usePullRequestDetail, so the header, actions menu and summary all read the same state.

Scope and approval

Fixes #29402, which reports the bug and has not been triaged yet. This PR also fits the focused-bug-fix exception: a single obvious defect (the header shows controls for a state the host has already left) with a narrow fix in the web client. It reuses the list's existing settle-on-agree model rather than adding a new mechanism, and it changes no contracts, server code or other clients.

Verification

  • Before/after recordings, captured in isolated dev state with the standard dark theme against a throwaway draft PR in my fork:
    • Before, upstream main ac8dce0 (13 s): after Close succeeds, Ready for review comes back enabled while the refresh runs, then Closed appears. A DOM sampler logged the re-enabled button for about 1.1 s.
    • After, this branch efaf7f9 (13 s): the header goes straight from the disabled button to Closed.
  • New cases in pullRequestDetail.logic.test.ts under confirmed action outcome on the detail cover action-to-outcome mapping, applying over the fetched detail, accumulating within one PR and resetting for another, and retiring a field once fetched data agrees. They fail on main, where the helpers do not exist.
  • vp test run on pullRequestDetail.logic.test.ts and pullRequestList.logic.test.ts passes, and so does vp run check:changed.
  • Each recorded field expires on its own 60 s deadline. The pure expirePullRequestDetailOverride is covered, but the hook's timer that calls it is not.
  • Not checked: I recorded only Close. Ready for review, Convert to draft and auto-merge take the same code path. Desktop and mobile were not exercised, because this is web-only code in the shared detail panel.

Claude Opus 5.5 via Claude Code

…n state

After a header action succeeded (ready for review, convert to draft, close, reopen, auto-merge), the panel cleared its pending state and refetched without waiting, so the header redrew the pre-action detail until the refetch landed.

The detail now applies each confirmed action outcome over the fetched data and drops it once the fetched detail agrees or after 60 seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Nov 2, 2026
@Brechard
Brechard marked this pull request as ready for review November 2, 2026 15:25
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 2, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at d08a04d

Macroscope's review found this PR approvable — The PR keeps confirmed action results visible while refreshed PR data catches up, preventing header flashes. The overrides are local, PR-scoped, and expire after 60 seconds; host actions and permissions are unchanged.

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

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed labels Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between efaf7f9 and d08a04d.

Files selected for processing: 3
  • apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts
  • apps/web/src/components/pullRequest/pullRequestDetail.logic.ts
  • apps/web/src/components/pullRequest/usePullRequestDetail.ts

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

Walkthrough

After a supported pull request action succeeds, the detail panel records a scoped patch for state, draft status, or auto-merge status. The detail hook applies the patch while fetched details are pending, reconciles fields when fetched values match, and expires the override after 60 seconds.

Changes: Pull request detail updates

Layer / File(s) Summary
Patch mapping and settlement
apps/web/src/components/pullRequest/pullRequestDetail.logic.ts, apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts
New helpers map supported actions to detail patches, apply overrides, and settle fields against fetched values. Tests cover action mapping, scope behavior, expiration, and settlement.
Scoped override lifecycle
apps/web/src/components/pullRequest/pullRequestList.logic.ts, apps/web/src/components/pullRequest/usePullRequestDetail.ts
The hook tracks scoped overrides, applies remaining fields to fetched details, and expires the current override after the exported 60-second trust duration.
Successful action wiring
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx
After an action succeeds, the panel records its patch when the action has a supported outcome.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Low

Sequence Diagram(s)

sequenceDiagram
  participant PullRequestDetailPanel
  participant usePullRequestDetail
  participant pullRequestDetailLogic
  PullRequestDetailPanel->>pullRequestDetailLogic: derive patch after successful action
  PullRequestDetailPanel->>usePullRequestDetail: record supported action outcome
  usePullRequestDetail->>pullRequestDetailLogic: record and apply scoped override
  usePullRequestDetail->>pullRequestDetailLogic: settle override against fetched detail
Loading

Possibly related issues

  • pingdotgg/t3code#29402 — The change records confirmed pull request action outcomes to prevent the detail view from continuing to display pre-action fields during refresh.

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to d08a0

No merge-blocking risk was identified.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title names the main change: after a pull request header action succeeds, the header no longer briefly shows the pre-action controls. The changeset adds scoped optimistic overrides for state, isDr…
Description check Passed The description follows the template sections: Problem, Change, Scope and approval, and Verification. The Problem section gives the symptom, the cause in finishAction, expected behavior and a repro. T…
Linked Issues check Passed Issue #29402 requires the confirmed result of each affected header action to remain visible during detail refresh. pullRequestDetailPatchAfterAction maps ready, draft, close, reopen, `enable…
Out of Scope Changes check Passed The changes remain within issue #29402. The exported trust-period constant, detail override helpers, hook integration, panel integration, and focused tests directly support the confirmed-action displa…
Full details: Title check

Explanation

The title names the main change: after a pull request header action succeeds, the header no longer briefly shows the pre-action controls. The changeset adds scoped optimistic overrides for state, isDraft and autoMergeEnabled, applied in usePullRequestDetail, and the header reads them. The title is a conventional commit with a plain-language description, and it is specific enough for a teammate scanning history.

Full details: Description check

Explanation

The description follows the template sections: Problem, Change, Scope and approval, and Verification. The Problem section gives the symptom, the cause in finishAction, expected behavior and a repro. The Change section explains the override, its 60 s expiry, and why merge is excluded. The Scope section links issue #29402 and explains the bug-fix exception. The Verification section gives before and after recordings, names the new test cases and the commands run, and states what was not checked. The description has some gaps. It does not say the issue has maintainer approval. It also does not cover the expiry timer in the hook, which the author discloses as untested. These gaps are minor and do not block merge.

Full details: Linked Issues check

Explanation

Issue #29402 requires the confirmed result of each affected header action to remain visible during detail refresh. pullRequestDetailPatchAfterAction maps ready, draft, close, reopen, enable-auto-merge, and disable-auto-merge to the required fields. usePullRequestDetail applies the override to the shared detail, retires fields when fetched data agrees, and expires fields after the existing 60-second trust period. The panel records the outcome only after success. merge remains unchanged. Focused tests cover mappings, overlay behavior, accumulation, scope reset, settlement, and expiry.

Full details: Out of Scope Changes check

Explanation

The changes remain within issue #29402. The exported trust-period constant, detail override helpers, hook integration, panel integration, and focused tests directly support the confirmed-action display fix. No unrelated product area, server code, client contract, or other client change is shown.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@coderabbitai coderabbitai Bot 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.

  • Fix comments: Fix CodeRabbit comments on this PR

A second action within the trust window replaced the shared timestamp, so the first action's field outlived its own deadline. Each overridden field now carries its own timestamp and the timer expires only the fields it stamped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 2, 2026 15:36

Dismissing prior approval to re-evaluate d08a04d

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 2, 2026
@maria-rcks
maria-rcks marked this pull request as draft November 2, 2026 20:30
@maria-rcks
maria-rcks marked this pull request as ready for review November 2, 2026 20:30
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 2, 2026 20:31

Dismissing prior approval to re-evaluate d08a04d

@maria-rcks

maria-rcks commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified as-is at d08a04d00508dc2950ababbb27f4ed48f6ba1389 on a disposable linux vm, using repo Playwright and /usr/bin/google-chrome against real vp run dev servers. no code changes were needed.

  • reproduced on github/main at cc59f99e735300120a6fc74d9a0b9df7c98fa81c in a separate worktree. in the pull requests page, converted this pr to draft, then clicked ready for review. after the host accepted it, the old ready button became enabled again for approximately 659 ms before the refreshed detail displayed squash and merge.
  • repeated against the exact pr head and the same pr through the real git.cafe source-control adapter. the ready button went from enabled to pending, then disappeared when success was confirmed. it never became enabled again. squash and merge appeared when refreshed permissions arrived. no network interception, mocked responses, fixtures or replay provider were used.
  • checked convert-to-draft and its ready-for-review reverse path, the corresponding menu state, persistence after reload, loading all five changed files in the code tab, and cancelling the close confirmation. restored this pr to its original open, non-draft state. did not merge or close anything.
  • created the project and threads through the app. real codex gpt-6.1-sol turns executed shell commands and returned through the web conversation on both main and the pr. the pr turn reported /home/user/t3code, the exact head sha above, and PR_PROVIDER_OK.
  • vp run check:changed ac8dce0cc3abd8a337f2d806b5082a6834b9b81a passed through blacksmith-check: format, lint, both knip steps, affected typechecks, 116 tests across three files, and four selected react compiler checks. the worker needed shallow git history and Playwright browser installation first.

these captures focus on the header during the confirmed-action refresh. the screenshots show main re-enabling the stale action and the pr removing it while refreshed permissions arrive. the 7-second recording shows main above and the pr below; playback and seeking were checked after upload.

main: stale ready-for-review action enabled during refresh

pr: stale ready-for-review action absent during refresh

real ready-for-review transition on main and the pr

Not verified

  • close/reopen and merge were not executed because this verification forbids closing or merging this pr and touching other prs. only the close confirmation cancellation was exercised.
  • auto-merge actions were unavailable for this pr in the running app, so enable/disable auto-merge was not exercised.
  • rejected host actions, a fetch that remains stale for the full 60-second hook expiry, switching between different prs while an override is active, direct github-host actions, remote/relay/tunnel clients, native desktop, ios and android were not exercised. the existing focused tests cover pure override settlement, scope reset and per-field expiry.

verification by codex harness, gpt-6.1-sol.

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

bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pull request header shows the pre-action controls again after an action succeeds

4 participants