Skip to content

fix(pr-status): address claude-review feedback post-merge (#571 follow-up)#584

Merged
frankbria merged 1 commit intomainfrom
fix/issue-571-claude-review-followup
Apr 14, 2026
Merged

fix(pr-status): address claude-review feedback post-merge (#571 follow-up)#584
frankbria merged 1 commit intomainfrom
fix/issue-571-claude-review-followup

Conversation

@frankbria
Copy link
Copy Markdown
Owner

@frankbria frankbria commented Apr 14, 2026

Summary

Addresses claude-review feedback from PR #583 that was posted after merge.

  • Fix misleading "All clear" during PROOF9 loading — show skeleton pulse instead of green checkmark while proofData is loading
  • Surface proof API errors — show "Unable to load PROOF9 status" when the proof fetch fails, explaining why merge is blocked
  • Handle externally merged PRs — if merge_state === 'merged' (merged via GitHub UI), show success banner and hide merge button instead of leaving it visible
  • Add ciPending test — covers the "Waiting for CI checks" message path

Test Plan

  • 4 new tests added (760/760 total pass)
  • Build clean
  • Lint clean on changed files

Relates to #571

Summary by CodeRabbit

Release Notes

  • New Features

    • Added loading indicator while proof status loads
    • Improved merge detection for externally-merged pull requests
  • Bug Fixes

    • Fixed UI behavior for pending CI checks with appropriate messaging
    • Enhanced error handling when proof status fails to load, displaying user-friendly error message
    • Merge button now correctly disables during proof loading or error states

…w-up)

- Show PROOF9 loading skeleton instead of false "All clear" while
  proofData is still loading
- Surface proof API error in the PROOF9 section when fetch fails
- Treat externally merged PRs (merge_state==='merged') the same as
  locally merged — show success banner, hide merge button
- Add 4 new tests: ciPending path, proof loading, proof error,
  externally merged PR
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

Walkthrough

Enhanced the PRStatusPanel component and tests to handle PROOF9 API loading and error states explicitly. Added logic to treat externally-merged PRs consistently via data?.merge_state. Updated test fixtures and added test cases for pending CI, proof loading, proof errors, and external merge states.

Changes

Cohort / File(s) Summary
Test Enhancements
web-ui/__tests__/components/review/PRStatusPanel.test.tsx
Enhanced SWR mock to accept optional prStatus/proofStatus and new proof-specific controls (isLoading, error, data states). Added CI status fixture for in_progress checks and test cases for pending CI, proof loading, proof errors, and external merge behavior.
Component Logic Updates
web-ui/src/components/review/PRStatusPanel.tsx
Added explicit handling for PROOF9 loading and error states with skeleton and error message rendering. Unified merged-state checks via new alreadyMerged value derived from both merged state and data?.merge_state === 'merged'.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A proof comes dancing, loading slow,
With skeletons and error glow,
Merged states twirl in unity,
Tests and logic dance so free!
Status panels hop and cheer—
Better logic, crystal clear! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies this as a fix addressing claude-review feedback from PR #571, which aligns with the PR objectives of fixing UI/behavior issues identified in post-merge review.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-571-claude-review-followup

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

@claude
Copy link
Copy Markdown

claude bot commented Apr 14, 2026

Review: fix(pr-status) — post-merge follow-up (#571)

These changes directly address the feedback from #583. Each fix is targeted, well-tested, and correct. A few observations:

What's solid

  • alreadyMerged abstraction (merged || data?.merge_state === 'merged') cleanly unifies the local-merge and externally-merged paths. The two render sites (blocking messages, success banner / merge button) are both updated consistently.
  • Proof loading/error guards follow the right SWR pattern: isLoading fires only on the initial fetch (no stale data), and proofError && !proofData preserves stale data during revalidation rather than clobbering it with an error state. Both are correct.
  • canMerge (!!proofData && ...) already gates on proof data presence, so the button is correctly disabled during both proofLoading and proofError states without any extra code.
  • 4 new tests cover all the new paths cleanly. The setupSWRMock refactor (object | undefined, optional options) is a minimal, readable change.

One gap worth fixing before this merges

Tooltip content is empty during proof-loading and proof-error states.

When proofLoading is true or proofError is set (and proofData is undefined), canMerge is false and the tooltip renders — but none of its three conditions (openRequirements.length > 0, ciFailing, ciPending) are true, so it renders as an empty popover:

{!canMerge && (
  <TooltipContent>
    {openRequirements.length > 0 && 'Resolve all open PROOF9 requirements. '}
    {ciFailing && 'Fix failing CI checks. '}
    {ciPending && 'Wait for CI checks to complete.'}
    {/* ← nothing renders when proof is loading/errored */}
  </TooltipContent>
)}

Suggested fix (minimal):

{proofLoading && 'PROOF9 status loading — merge unavailable. '}
{proofError && !proofData && 'PROOF9 status unavailable — merge blocked until resolved. '}

This pre-existed in main but since this PR is the one that makes proof-loading/error states visible in the UI, it's the natural place to close the loop.

Minor (non-blocking)

The proof SWR refreshInterval still reads merged (local state) rather than alreadyMerged:

{ refreshInterval: merged ? 0 : 15_000 }

An externally-merged PR will continue polling proof data at 15s. Low-impact since proof data is static post-merge, but using alreadyMerged here would be consistent with the rest of the component.


Good shape overall — the tooltip gap is the only behaviorally-visible issue. Fix that and this is ready.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web-ui/src/components/review/PRStatusPanel.tsx (1)

100-104: ⚠️ Potential issue | 🟠 Major

Block merge on any PROOF9 fetch error, not only when proofData is absent.

At Line 125, the merge gate checks !!proofData but ignores proofError. At Line 210, the error condition proofError && !proofData suppresses the error message whenever stale proofData exists. In SWR, after a successful fetch, a later revalidation failure can set both error and data (stale). This allows merging on stale PROOF9 data and hides the error state from the user.

💡 Suggested fix
-  const canMerge = !!data && !!proofData && openRequirements.length === 0 && ciPassing;
+  const proofBlocked = proofLoading || !!proofError || !proofData;
+  const canMerge = !!data && !proofBlocked && openRequirements.length === 0 && ciPassing;
-            ) : proofError && !proofData ? (
+            ) : proofError ? (
               <p className="text-xs text-muted-foreground">
                 Unable to load PROOF9 status — merge blocked until resolved.
               </p>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-ui/src/components/review/PRStatusPanel.tsx` around lines 100 - 104, The
current logic allows a merge when stale PROOF9 data exists because it only
checks !!proofData and hides errors when proofError is set alongside stale
proofData; update the merge gate and error display to consider proofError: where
the UI decides merge eligibility (the check using proofData and merged), require
that proofError is falsy (e.g., only allow merge when !!proofData && !proofError
&& !proofLoading), and where the error banner/indicator is rendered (the
condition using proofError && !proofData), change it to display whenever
proofError is truthy (e.g., proofError) so fetch errors are surfaced even if
stale proofData exists; reference the useSWR result variables proofData,
proofError, proofLoading and the proofKey/proofApi.getStatus call to locate the
logic to change.
🧹 Nitpick comments (1)
web-ui/src/components/review/PRStatusPanel.tsx (1)

103-104: Stop PROOF9 polling once the PR is externally merged/closed.

At Line 103, polling stops only for local merged. Consider using server merge state too, so externally merged PRs don’t keep polling.

♻️ Suggested refactor
   const { data: proofData, error: proofError, isLoading: proofLoading } = useSWR<ProofStatusResponse>(
     proofKey,
     () => proofApi.getStatus(workspacePath),
-    { refreshInterval: merged ? 0 : 15_000 }
+    {
+      refreshInterval:
+        merged || data?.merge_state === 'merged' || data?.merge_state === 'closed' ? 0 : 15_000,
+    }
   );

Also applies to: 124-125

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-ui/src/components/review/PRStatusPanel.tsx` around lines 103 - 104, The
polling currently stops only when the local `merged` flag is true; update the
polling condition used for `refreshInterval` (and the similar check at the other
spot) to also check the server-side PR state (e.g., `pr?.state` or whatever
server field indicates merged/closed) so that polling is set to 0 when either
local `merged` OR the server reports the PR as merged/closed; locate the
`refreshInterval: merged ? 0 : 15_000` usage in PRStatusPanel (and the duplicate
at the other spot) and change the condition to include the server-state check
(for example `merged || pr?.state === 'MERGED' || pr?.state === 'CLOSED'`) so
externally merged/closed PRs stop polling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@web-ui/src/components/review/PRStatusPanel.tsx`:
- Around line 100-104: The current logic allows a merge when stale PROOF9 data
exists because it only checks !!proofData and hides errors when proofError is
set alongside stale proofData; update the merge gate and error display to
consider proofError: where the UI decides merge eligibility (the check using
proofData and merged), require that proofError is falsy (e.g., only allow merge
when !!proofData && !proofError && !proofLoading), and where the error
banner/indicator is rendered (the condition using proofError && !proofData),
change it to display whenever proofError is truthy (e.g., proofError) so fetch
errors are surfaced even if stale proofData exists; reference the useSWR result
variables proofData, proofError, proofLoading and the
proofKey/proofApi.getStatus call to locate the logic to change.

---

Nitpick comments:
In `@web-ui/src/components/review/PRStatusPanel.tsx`:
- Around line 103-104: The polling currently stops only when the local `merged`
flag is true; update the polling condition used for `refreshInterval` (and the
similar check at the other spot) to also check the server-side PR state (e.g.,
`pr?.state` or whatever server field indicates merged/closed) so that polling is
set to 0 when either local `merged` OR the server reports the PR as
merged/closed; locate the `refreshInterval: merged ? 0 : 15_000` usage in
PRStatusPanel (and the duplicate at the other spot) and change the condition to
include the server-state check (for example `merged || pr?.state === 'MERGED' ||
pr?.state === 'CLOSED'`) so externally merged/closed PRs stop polling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74f090ed-c249-4aff-97b7-8790f51e1fcb

📥 Commits

Reviewing files that changed from the base of the PR and between ba8f708 and fcd585d.

📒 Files selected for processing (2)
  • web-ui/__tests__/components/review/PRStatusPanel.test.tsx
  • web-ui/src/components/review/PRStatusPanel.tsx

@frankbria frankbria merged commit f67caa3 into main Apr 14, 2026
12 checks passed
@frankbria frankbria deleted the fix/issue-571-claude-review-followup branch April 14, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant