Skip to content

fix(heartbeat): retire stale same-PR review context (BLO-22229) - #1064

Open
kkroo wants to merge 3 commits into
masterfrom
codex/blo-22229-review-wake-fix
Open

fix(heartbeat): retire stale same-PR review context (BLO-22229)#1064
kkroo wants to merge 3 commits into
masterfrom
codex/blo-22229-review-wake-fix

Conversation

@kkroo

@kkroo kkroo commented Aug 6, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip coordinates AI agents, GitHub events, and issue work through heartbeat wakeups.
  • GitHub PR review wakeups carry review state, author, body, comment ids, and structured wake context into author-facing directives.
  • Active heartbeat runs can coalesce multiple wakes for the same issue/PR, so stale review fields or stale comment ids can be inherited if replacement is partial.
  • BLO-22229 found a same-PR review-instance bug: a comment-shaped Ally review could inherit an older formal approval state.
  • Ally review feedback on fix(heartbeat): stop welding a stale reviewState onto a new same-PR review instance (BLO-22229) #1063 also showed the reverse sequence could keep superseded feedback comments in wakeCommentIds after a later formal review took ownership.
  • This pull request makes review-instance wakes replace review content as a unit and retire superseded review-feedback comment ids while preserving unrelated human comments.
  • The benefit is that author wakes no longer mix an approval state with stale Critical/Important findings from a different review instance.

Linked Issues or Issue Description

Refs: https://paperclip.blockcast.net/BLO/issues/BLO-22229
Refs: https://paperclip.blockcast.net/BLO/issues/BLO-19118
Supersedes: #1063

Bug: Same-PR review wake coalescing could compose context from two different review instances. A later comment-shaped review lacked its own formal reviewState and inherited an earlier approval; a later formal review could also keep an older actionable review-feedback comment in wakeCommentIds, causing the rebuilt paperclipWake.comments payload to reload superseded findings.

What Changed

  • Treat github_pr_review_submitted and github_pr_review_feedback wakes as fresh review instances that own review-content fields outright.
  • Clear review-content fields the incoming review instance does not supply instead of inheriting them from an earlier same-PR review.
  • Filter superseded github_pr_review_feedback comment ids out of the existing wake-comment set when a same-PR review instance replaces the prior review context.
  • Preserve unrelated human comment ids during that filtering so ordinary comments still remain available to the next wake payload.
  • Added regression coverage for stale approval-state inheritance, formal-review replacement, and feedback-to-approval comment retirement.

Verification

  • PATH=/opt/homebrew/bin:$PATH pnpm install --frozen-lockfile
  • PATH=/opt/homebrew/bin:$PATH pnpm exec vitest run server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/heartbeat-workspace-session.test.ts --no-file-parallelism --maxWorkers=1 (283 passed)
  • PATH=/opt/homebrew/bin:$PATH pnpm --filter @paperclipai/server typecheck
  • PATH=/opt/homebrew/bin:$PATH pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts --testNamePattern "provisions worktree-local pnpm node_modules instead of reusing base-repo links" --no-file-parallelism --maxWorkers=1 (2 passed, 116 skipped)
  • PATH=/opt/homebrew/bin:$PATH pnpm exec vitest run server/src/__tests__/heartbeat-queued-backlog-convergence.test.ts --no-file-parallelism --maxWorkers=1 (11 skipped locally)

Risks

Low to moderate risk. The change is scoped to heartbeat coalescing for GitHub review-instance wakes. The main behavior shift is intentional: a new review instance no longer inherits stale review-content fields or stale review-feedback comments from a prior review instance. Non-review wakes still inherit existing review context.

Model Used

Codex GPT-5 coding agent with shell, GitHub CLI, and local test execution.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: # / Closes # / Refs # OR (b) described the issue in-PR following the relevant issue template
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • All Paperclip CI gates are green
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups
  • I will address all Greptile and reviewer comments before requesting merge

Paperclip-Paperclip and others added 2 commits August 5, 2026 22:39
…eview instance (BLO-22229)

mergeCoalescedContextSnapshot spread `{...existing, ...incoming}` over the
review-content keys (githubPrReviewState/Body/AuthorLogin/...). A new
review-instance wake that doesn't carry its own reviewState — every
issue_comment-sourced `github_pr_review_feedback` wake, since that branch
never sets a formal state — inherited whatever reviewState an EARLIER,
unrelated review instance on the same PR happened to leave behind. Observed:
a comment-shaped Ally review carrying Critical findings got composed with a
prior human APPROVED, producing a directive that told the PR author to merge
a PR carrying unresolved critical findings.

Treat the review-content key block as owned outright by whichever wake most
recently reported it: when the incoming wake is itself a review-instance wake
(github_pr_review_submitted or github_pr_review_feedback), any review-content
key it doesn't re-supply is cleared rather than inherited, mirroring the
existing BLO-19118 handling for cross-PR contamination.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@allyblockcast

allyblockcast Bot commented Aug 6, 2026

Copy link
Copy Markdown

🔗 Paperclip issue: BLO-19118
🔗 Paperclip issue: BLO-22229

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 66d6123

Critical Issues (0)

Important Issues (1)

  • [pr-review-toolkit, gstack/review, native-codex] server/src/services/heartbeat.ts:6610 — A same-PR review replacement does not clear stale comment routing when the superseded review-feedback comment was the only comment. preserveNonGithubPrReviewFeedbackWakeCommentIds(existing) removes that sole ID, so mergedCommentIds is empty; however, the cleanup branch runs only for isDifferentGithubPr. The spread-retained wakeCommentIds, commentId, wakeCommentId, and paperclipWake therefore survive, allowing the superseded Critical/Important feedback to be reloaded alongside the replacement formal review.

    Clear the canonical comment fields and paperclipWake when either isDifferentGithubPr or isNewReviewInstance yields an empty merged list. Add a regression case where the existing snapshot contains only the generated review-feedback comment and the incoming formal review has no comment IDs; the current test keeps human-comment-1, so it never exercises this branch.

Suggestions (0)

Strengths

  • Review-content fields are now replaced atomically, and the added tests cover mixed human-comment preservation and stale review-state inheritance clearly.

Recommended Action

  1. Address the Important issue this cycle and rerun the focused heartbeat-context tests.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 352489d

Looks good.

Prior Findings Dispositioned (1)

  • prior:66d6123 important 1 — fixed — server/src/services/heartbeat.ts:6610 — The empty merged-comment set now clears canonical comment routing for a new same-PR review instance, and server/src/__tests__/heartbeat-context-summary.test.ts:1196 covers the sole-feedback-comment case.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • Review content fields are now replaced as one unit, which prevents stale approval state from being paired with a later comment-shaped review.
  • The tests cover both review-order directions, preservation of unrelated human comments, and complete cleanup when no comment survives.

Recommended Action

  1. Merge when the required CI checks are green.

@allyblockcast allyblockcast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 352489d

Looks good.

Prior Findings Dispositioned (1)

  • prior:66d6123 important 1 — fixed — server/src/services/heartbeat.ts:6610 — The empty merged-comment set now clears canonical comment routing for a new same-PR review instance, and server/src/__tests__/heartbeat-context-summary.test.ts:1196 covers the sole-feedback-comment case.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • Review content fields are now replaced as one unit, which prevents stale approval state from being paired with a later comment-shaped review.
  • The tests cover both review-order directions, preservation of unrelated human comments, and complete cleanup when no comment survives.

Recommended Action

  1. Merge when the required CI checks are green.

@kkroo
kkroo enabled auto-merge August 6, 2026 03:11
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.

3 participants