Skip to content

fix(heartbeat): stop welding a stale reviewState onto a new same-PR review instance (BLO-22229) - #1063

Closed
allyblockcast[bot] wants to merge 2 commits into
masterfrom
blo-22229-review-wake-fix
Closed

fix(heartbeat): stop welding a stale reviewState onto a new same-PR review instance (BLO-22229)#1063
allyblockcast[bot] wants to merge 2 commits into
masterfrom
blo-22229-review-wake-fix

Conversation

@allyblockcast

@allyblockcast allyblockcast Bot commented Aug 5, 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.
  • Review feedback 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

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

…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>
@allyblockcast

allyblockcast Bot commented Aug 5, 2026

Copy link
Copy Markdown
Author

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

1 similar comment
@allyblockcast

allyblockcast Bot commented Aug 5, 2026

Copy link
Copy Markdown
Author

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

@allyblockcast

allyblockcast Bot commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention:

Missing or incomplete:

  • Missing section: ## Thinking Path
  • Missing section: ## What Changed
  • Missing section: ## Verification
  • Missing section: ## Risks
  • Missing section: ## Model Used
  • Add the dedup-search checkbox to your PR description and check it once you have searched the GitHub PR list for similar PRs. See the PR template at .github/PULL_REQUEST_TEMPLATE.md and CONTRIBUTING.md → "Before You Start: Search First".

Once updated, push a new commit and these checks will re-run automatically.

— commitperclip

@allyblockcast

allyblockcast Bot commented Aug 5, 2026

Copy link
Copy Markdown
Author

Ally — Consolidated PR Review

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

Important Issues (1)

  • [gstack/review] server/src/services/heartbeat.ts:6553 — Replacing the review fields does not retire the prior review's feedback comment from wakeCommentIds. After this loop clears githubReviewFeedbackCommentId, line 6567 still merges every comment ID from existing; buildPaperclipWakePayload then reloads those comments. In the reverse sequence covered by the incident class (comment-shaped actionable feedback followed by a formal APPROVED review), the author wake can therefore carry the new approval state while paperclipWake.comments still contains the superseded Critical/Important findings.
    • Remove the superseded review-feedback comment IDs from the existing comment set when a new review instance takes ownership, while preserving unrelated human comments. Add a feedback-to-approval regression test whose existing fixture includes githubReviewFeedbackCommentId, wakeCommentIds, and paperclipWake, and assert that only non-review comments survive.

Strengths

  • The new ownership rule correctly prevents a missing incoming githubPrReviewState or body from inheriting the previous review instance's value.
  • The tests cover both formal-review-to-comment-feedback and formal-review-to-formal-review field replacement.

Recommended Action

  1. Fix the Important issue before merge and rerun the focused heartbeat tests.
  2. The PR is authored by app/allyblockcast; the exact head must be reopened under an independent author before an Ally App approval is possible.

@kkroo

kkroo commented Aug 6, 2026

Copy link
Copy Markdown

Superseded by #1064, which carries the same BLO-22229 fix plus the follow-up for this review feedback from a human-authored branch so Ally can review it.

@kkroo kkroo closed this Aug 6, 2026
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.

2 participants