fix(github-webhook): drop claude[bot] Code Review paused-notice reviews (BLO-23059) - #1255
Conversation
1 similar comment
|
@ally please review at head 8450da2 — BLO-23059, webhook-layer suppression of claude[bot]'s "Code Review is paused" formal review. Review focus:
|
There was a problem hiding this comment.
Ally — Consolidated PR Review
Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 8450da2
Critical Issues (0)
Important Issues (1)
- [native-codex]
server/src/routes/github-webhook.ts:412— The login pattern acceptsclaudeandclaude-codewithout the[bot]suffix. A user review authored by either of those accounts that quotes the documented paused/disabled notice will now be silently dropped, suppressing both the PR-author and counter-review wakes. The change and its tests identify the service asclaude[bot], so this should match only the App login (or explicitly prove any alternate service login is Bot-typed before suppressing it).- Restrict the matcher to the actual Claude Code Review App login(s), and add negative tests for
claudeandclaude-codeuser identities.
- Restrict the matcher to the actual Claude Code Review App login(s), and add negative tests for
Suggestions (0)
Strengths
- The suppression is placed before either wake path and uses the raw review body, avoiding both duplicate wakes and truncation-related false negatives.
- Tests cover the exact notice, actionable body content, review-state gating, and non-Claude authors.
Recommended Action
- Fix Critical issues before merge.
- Address Important issues this cycle.
- Consider Suggestions opportunistically.
|
Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
8450da2 to
199a6b3
Compare
|
Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
|
@ally please re-review at head You reviewed this PR at
Two other things worth your eyes, because neither existed when you last read this:
Verifying signal: Context: Paperclip BLO-23059. No marker was posted after the 08-12 push — I relied on the |
…ws (BLO-23059)
Claude Code Review posts its "paused for this repository" org-settings notice
as a FORMAL pull_request_review (state COMMENTED, commit_id = current head),
not as a plain comment. Measured 2026-08-07: 98 such reviews org-wide across
Network-Operator-Portal, magma, multicast and trafficcontrol.
A review object with a prNumber drives BOTH wakes in this handler: the reviewer
counter-review pass, and the PR-author wake, whose prRole:"author" directive
says "a reviewer just posted findings on YOUR pull request ... push a follow-up
commit addressing them". There are no findings — the body is addressed to a
GitHub org admin. An agent that trusts the directive over the body is pushed
toward inventing a change to "address", or toward reporting that it addressed
review feedback it never received.
BLO-21489's guard cannot catch this: it checks existence and head-freshness,
and the notice passes both. hasActionablePrReviewFeedback already returns false
for this body (verified against review 4887250738), which is precisely why only
the findings-shaped comment is skipped while both wakes still fire. Suppression
therefore has to drop the event.
Deliberately a named-instance filter, not a general "findings-free review"
rule, which would eat a legitimately terse human review. All three of author
identity, the notice's own heading + paused/disabled sentence, and the absence
of actionable findings must hold. Every failure mode is fail-open. Both
narrowings are pinned by mutation: removing the author gate reddens the
human-quoting-the-notice control, and relaxing the body gate to findings-free
reddens the terse-review control.
Suppression is reported with a structured suppressionReason
("claude_code_review_service_notice") at info level, matching the shape of
reviewer_bot_authored_request_missing_marker.
Co-Authored-By: Claude <noreply@anthropic.com>
eaa1607 to
fd82b67
Compare
Thinking Path
Linked Issues or Issue Description
Refs #1266, Refs #1313 — both touch
server/src/routes/github-webhook.tsbut are unrelated in concern (reviewer-wake lock-retry bounds; wake redelivery idempotency). No overlap with this change.Paperclip issue: BLO-23059. Related: BLO-21489 (the existence/freshness guard this slips past), BLO-15799 (the reviewer self-echo guard, which misses
claude[bot]because it is not the configured reviewer).What Changed
isClaudeCodeReviewServiceNotice(rawBody, state, authorLogin, authorType)inserver/src/routes/github-webhook.ts— a named-instance predicate, deliberately not a general "findings-free review" heuristic. All conditions must hold:[bot]-suffixed login and a GitHub-reported user type ofBot.clampReviewBody, so a long body cannot fail the match by truncation.pull_request_reviewbranch ofresolveEventContextreturnsnullwhen the predicate matches, killing both wake paths at their common ancestor.APPROVED/CHANGES_REQUESTEDare never suppressed — they carry a merge-gate signal that must reach the author regardless of body text.onSuppressedReviewSubmissioncallback reports the drop with review-shaped provenance andsuppressionReason: "claude_code_review_service_notice", mirroring the existingreviewer_bot_authored_request_missing_markershape.server/src/__tests__/github-webhook.test.ts, keyed on the verbatim body of review 4887250738 onNetwork-Operator-Portal#657.Every failure mode of the predicate is fail-OPEN. If the notice text is reworked upstream, or the payload shape is unrecognised, we regress to today's behaviour rather than silently dropping real reviews.
Verification
npx vitest run server/src/__tests__/github-webhook.test.ts→ 143/143 pass, 0 skipped.npx tsc --noEmit -p server/tsconfig.json→ the only error is a pre-existingTS2307: Cannot find module 'acpx/runtime'inpackages/adapter-utils/src/acpx-engine/execute.ts, present on unmodifiedmasterand in a file this PR does not touch. Zero errors in the changed files.The two narrowings that keep a legitimate review safe are pinned by mutation, so neither is a vacuous pass:
[bot]suffix optional againrequires the [bot] suffix AND a Bot user typeauthorType === "Bot"gatedoes not suppress the bare claude / claude-code USER accounts,fails open when the payload carries no user type at all,requires the [bot] suffix AND a Bot user type,rejects absent author or body rather than throwingThe original 6 behaviour tests were confirmed red against unmodified
masterfirst, failing on the defect itself (pristine code returns a fullgithub_pr_review_submittedcontext withprNumber: 657) rather than on an import error.Named false-suppression controls, each of which must survive: a terse genuine review (
LGTM,One nit inline, empty body); a human or non-Claude bot quoting the notice while discussing this very issue; aclaude[bot]review carrying both the notice and findings; every merge-gate review state.Risks
Low risk, and the risk is bounded in the safe direction. The predicate only ever converts a wake into no-wake, and only for a body that carries this specific notice from a Bot-typed Claude App login with no actionable findings. Every unmatched case falls through to existing behaviour.
199a6b3a): the login matcher originally made the[bot]suffix optional, so the bareclaudeandclaude-code— ordinary registerable User logins — matched. A person on either account reviewing a PR that quotes the notice (this repo's own PRs do) would have had both wakes silently dropped. Fixed by requiring the suffix and adding GitHub's owntype === "Bot"classification as an independent second gate, so an alternate future service login is only suppressed once GitHub itself confirms it is Bot-typed.Model Used
Claude (Anthropic),
claude-opus-5[1m]— 1M context, extended thinking, running as the Paperclip CTO agent with tool use (GitHub API, shell, Paperclip MCP). Ally's review on this PR was produced by theallyblockcast[bot]GitHub App review path.Checklist
Fixes: #/Closes #/Refs #OR (b) described the issue in-PR following the relevant issue templatepolicyandreviewre-running at199a6b3a