Uh oh!
There was an error while loading. Please reload this page.
[Bugfix #901] Skip stale post-merge prReady rows in NeedsAttentionList - #902
Conversation
Cross-reference the defensive prReady builder-fallback against the workspace's recently-merged PR set. After a PR merges, pendingPRs (open PRs only) correctly omits it, but in-flight builders that crossed the v3.1.4 → v3.1.5 line-453 setter boundary keep stale pr_ready_for_human in status.yaml. The iter-2 cache-miss defense (PR #874) couldn't distinguish "PR missing because cache miss" from "PR missing because merged" and surfaced both — emitting a stale "PR review" row for work already shipped. Adds OverviewData.recentlyMergedIssueIds (derived from the already- fetched mergedPRs list via parseLinkedIssue) and plumbs it into NeedsAttentionList.buildItems. The defensive emit now skips when the builder's issueId is in the merged set. Fixes#901
Adds an overview-server regression test that exercises the dedup `seen` set in `recentlyMergedIssueIds`: when the same issue has two merged PRs in the 24h window (e.g. a primary fix and a follow-up), the consumer must see one entry, not two. Thread note documents the dual `OverviewData` interfaces (shared in packages/types/src/api.ts plus a local copy in packages/codev/src/agent-farm/servers/overview.ts) — both had to be updated to satisfy the local tsc check.
waleedkadous
commented
May 28, 2026
Builder note — PR ready for architect review CMAP-3 (gemini/codex/claude,
Iter-1 outputs auto-persisted at Running |
Uh oh!
There was an error while loading. Please reload this page.
…rgedIssueIds end-to-end The merged-suppression projection (#901/#902) is dead once the dashboard builder-emit branch is gone (Phase 2). Remove it: - OverviewData (api.ts + overview.ts mirror): drop the recentlyMergedIssueIds field. - overview.ts: delete the merged-issue computation block and its inclusion in the returned result. - overview.test.ts: remove the two recentlyMergedIssueIds tests + the null-mergedPRs empty-array assertion. RETAINED: fetchRecentMergedPRs, the mergedPRs fetch, and the issueToPrUrl map — still needed for recentlyClosed PR-link enrichment (positive prUrl test at L1853 still passes, proving the fetch is wired). porch build + tests green; dashboard 13/13.
Net -45 LOC across packages/. Documents the universal-pr-gate Needs Attention contract, the dashboard-local no-builder-stand-in rule, the verify-approval label/styling (render-verified in headless chromium), and reconciles #919/#902. Captures the consultation history (Codex was the consistent skeptic; all blocks legitimate and addressed) and MAINTAIN-candidate lessons.
Summary
After a PR merges,
NeedsAttentionListstill surfaced the corresponding builder with a "PR review" badge. Cross-reference the defensiveprReadybuilder-fallback against the workspace's recently-merged PR set so post-merge stale rows are suppressed.Fixes#901
Root Cause
Two interacting problems documented in the issue:
advanceProtocolPhaseline 453 re-setpr_ready_for_human = trueon the terminalpr → verifiedadvance. In-flight builders that crossed the v3.1.4 → v3.1.5 boundary keep the staletrueinstatus.yaml.NeedsAttentionList.buildItemsiter-2 defensive fallback (PR [Bugfix #872] Fix: emit canonical pr_ready_for_human signal across all protocols #874) emits a row for anyb.prReady === truebuilder whose PR isn't inpendingPRs[]. Intent was cache-miss defense, but the same path fires when the PR has been merged — merged PRs are correctly absent frompendingPRs(open-only), and surfacing the row is wrong.The data needed was already fetched:
overview.ts:911callsfetchMergedPRsCached, but the result was only used internally to enrichrecentlyClosed[]withprUrl.Fix
OverviewData.recentlyMergedIssueIds: string[]— new field on both the wire type (packages/types/src/api.ts) and the internal overview type (packages/codev/src/agent-farm/servers/overview.ts).mergedPRs→ linked-issue IDs viaparseLinkedIssue, deduplicated, attached to every response (empty array when forge fails).NeedsAttentionList.buildItemsaccepts the merged-issue list and skips the defensive emit whenb.issueIdmatches a recently-merged PR's linked issue.WorkViewpassesoverview.recentlyMergedIssueIdsthrough.The PR-loop is untouched — it iterates open PRs only, so already correct. No one-shot migration needed for stale
pr_ready_for_human: truerows: this filter masks them in the UI, and they self-correct as new builders use #888's code path.Test Plan
prReady: true+issueIdinrecentlyMergedIssueIds→ no row emitted.recentlyMergedIssueIdsargument, comment clarifies that the test models the cache-miss scenario (NOT merged).recentlyMergedIssueIdspopulated from linked-issue parsing offetchMergedPRsCached; deduplicated; empty[]when the call returnsnull.porch check: ✓ build 4.1s, ✓ tests 20.1s).NeedsAttentionListtests (13/13) andoverviewtests (149/149) green.Scope
pr_ready_for_human: truein already-verifiedstatus.yamlfiles (per the issue — self-corrects, and this fix masks them anyway).CMAP Review (3-way, iter 1)
Claude's non-blocking observation: a couple of existing
buildItems(prs, builders)test invocations rely on the newrecentlyMergedIssueIds = []default rather than passing[]explicitly. Functionally identical to the updated test at line 208 that passes[]with a clarifying comment — left as-is to keep the diff minimal.Full per-reviewer outputs auto-persisted at
codev/projects/bugfix-901-needs-attention-surfaces-build/bugfix-901-pr-iter1-{gemini,codex,claude}.txt.