[Bugfix #844] Gate NeedsAttention PR rows on porch pr-gate#845
Merged
Conversation
Before: every open PR appeared in Needs Attention the instant it was created, even while CMAP reviews were still running — reviewers arrived before the AI comments did. After: a PR with a tracked builder is surfaced only once that builder reaches the porch `pr` gate (blocked === 'PR review'). PRs without an associated builder (human-authored, externally opened) fall back to the GitHub reviewDecision and are surfaced only when reviewStatus is REVIEW_REQUIRED. Adds buildItems export and 6 regression tests covering the scenarios called out in the issue.
Three small refinements after the iter-1 CMAP review: 1. waitingSince now uses the builder's blockedSince (not pr.createdAt) for affiliated PRs — the wait-time chip now measures "how long since the human became the bottleneck," not "how long since the PR was opened while CMAP was still running." Falls back to pr.createdAt for unaffiliated PRs. 2. Builders stuck at the pr gate whose PR is missing from `prs` (cache miss, pagination, transient API failure) now surface via the builder loop instead of disappearing silently. Tracks an emittedPrGateIssueIds set during PR iteration and only dedupes when the PR was actually emitted. 3. gateKindClass now handles 'PR review' → 'attention-kind--pr' so the builder-loop fallback row from (2) renders with the same PR styling as the PR-loop emit. 3 new regression tests for these behaviors. 9/9 tests pass.
Contributor
Author
|
Excellent work — thank you. Approving. Two things I particularly liked:
The regression test for the double-emission invariant is the kind of test I'd hope someone would write but rarely see. Nice. Please merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #844
Root Cause
packages/dashboard/src/components/NeedsAttentionList.tsx:42-56iterated every open PR fromoverview.pendingPRsand emitted an attention row unconditionally. There was no cross-reference against the builder's porch gate state, so a PR appeared in Needs Attention the moment it was created — before the automated CMAP reviews (Gemini / Codex / Claude) had run. Reviewers arrived ahead of the AI review comments.Fix
buildItemsnow consultsOverviewBuilder.blocked/blockedSinceto decide whether a PR is genuinely waiting on a human:prGateSince=Map<issueId, blockedSince>for builders withblocked === 'PR review'(the human-readable label for the porchprgate, mapped inoverview.ts:GATE_LABELS).linkedIssuematches a pr-gate builder (prGateSince.has(...)), ORreviewStatus === 'REVIEW_REQUIRED'(the human-authored / externally opened case — no porch gate to wait on, so fall back to GitHub'sreviewDecision).waitingSinceuses the builder'sblockedSincefor affiliated PRs (the "human became bottleneck" moment), falling back topr.createdAtfor unaffiliated PRs.emittedPrGateIssueIds; the builder loop only dedupes pr-gate builders whose PR was actually emitted. This protects against a stuck builder disappearing if its PR is missing fromprs(cache miss, pagination, transient API failure).gateKindClassgains a'PR review' → 'attention-kind--pr'case so the builder-loop fallback row from (4) renders with the same PR styling.The
linkedIssueplumbing already existed onOverviewPR(populated byparseLinkedIssueinoverview.ts); no API/types change was needed.Note on issue suggestion
The issue suggested dropping the
continueat line 62, but doing so would create duplicate rows (one from the PR loop, one from the builder loop) for the same builder. Kept the skip and conditioned it on the emitted-set so a missing PR doesn't silently hide the gate signal.Test Plan
pnpm test NeedsAttentionList→ 9/9 passedporch checkpasses (build + tests)Test scenarios covered
blocked === null) → excluded ✓prgate → included ✓prgate → emitted exactly once (dedupe holds) ✓REVIEW_REQUIRED→ included ✓APPROVED→ excluded ✓linkedIssue(no matching builder) treated as unaffiliated ✓waitingSince === builder.blockedSince(notpr.createdAt) ✓CMAP Review (PR-845, 3-way)
waitingSinceas a non-blocking observation.waitingSincesemantics, invisible stuck builders, missinggateKindClasscase.All three of Gemini's points addressed in iter-2 commit
7ec0fc9c.