Repository navigation
fix(pr-review-cli): fail a review that read only part of its scope - #943
Conversation
A review of an oversize diff read 2 of 1186 files and still concluded success with "0 finding(s)". The model now returns files_read; the job counts the files in scope and the diff's bytes itself. A review that read fewer files than in scope, or whose diff is over the 300000-byte read budget, is partial: the check fails, no completion notice is written, the comment's first line states files read of files changed, and the marker records sha=none so the next push reviews the whole pull request. A review with no files_read is incomplete. Refs: melodic-software/claude-code-plugins#11575 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…path The head could commit a symlink at .claude-lane/pr.diff (to /dev/null), so a stat of the path read 0 bytes and the read-budget check passed for a diff of any size. The full-diff step now counts the diff's bytes in the pipe and the incremental scope step counts the text it writes; the extract step reads that count and requires the diff path to be a regular file. Refs: melodic-software/claude-code-plugins#11575 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Security review (incremental, since 3e94beb)Reviewed
critical-findings: 0 |
|
claude-review reviewed No findings in the incremental change since What changed
What I checked
I ran nothing myself. This is from reading the diff and the surrounding workflow and test code. Closing issue: the PR uses |
…s pipe The step runs as bash -e without pipefail, so a git diff that failed inside the new byte-count pipe left written=true and files=0, and a review of the truncated diff passed as complete (read 0 of 0). set -o pipefail restores the old behavior: the step fails and the review is incomplete. Refs: melodic-software/claude-code-plugins#11575 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs: melodic-software/claude-code-plugins#11575
Summary
The review lane read 2 of the 1186 files on claude-code-plugins#11169 (head
778ceff0d0), and its comment said so. The checkpr-review / claude-review-statusstill concludedsuccess, and the comment opened with "0 finding(s)". This change makes a review that read only part of its scope fail closed. It does not add chunking, so acceptance item 1 of #11575 (review an oversize diff in chunks) stays open on that issue.Fix
Schema and prompt (all three legs): the model also returns
files_read, the number of changed files in scope whose whole change it read.Extract step (all three legs, same script): the job counts the files itself. An incremental review uses the scope step's new
filesoutput, and a whole review uses the full-diff step's newfiles=output. The job also measures the diff's bytes where the diff is written: in the full-diff pipe, or from the text the scope step writes. It requires the diff path to be a regular file, so a symlink the head commits there isincomplete. It recordscoverage: { read, changed, over_budget? }, withreadcapped atchanged. The review isincompletewhenfiles_readis missing or invalid, the count is unreadable, or the diff file cannot be read. A diff over 300000 bytes is partial whatever the model reports. Basis: pr-verify's per-chunk read budget in claude-code-plugins.github/scripts/pr-verify/chunk-diff.sh.publish.cjs: a review without valid coverage is
incomplete. A partial review (read < changed, or over budget):**claude-review** partial review of <head>: read 2 of 1186 changed file(s). 0 finding(s) in what was read ... This head is not reviewed.;sha=nonein the hidden reviewed-head line, so the next push reviews the whole pull request and no merge gate reads the head as reviewed;claude-lane-review-completenotice;failure-class=partial.A complete review's line now reads
reviewed <head>: read N of N changed file(s); F finding(s), .... In summary mode the shadow report records the outcome and coverage, and the step never fails.Who is affected: every caller of
pr-review-cli.yml@main, both lanes, since the security lane shares the schema and extract step. In claude-code-plugins those callers arepr-review-hosted.yml(claude-review-status) andpr-review-security-hosted.yml. Until chunking lands, a pull request whose diff is over 300000 bytes, or whose review reads fewer files than it changed, keeps a non-success review check. Itsci-statustherefore stays red. #11575 asks for this non-success result.Marker consumers: the claude-code-plugins parsers (
babysit_review_evidence.py,clear-escalations.mjs,address-feedback.mjs,feedback-dispatch.mjs) matchsha=[0-9a-f]{40}. They readsha=noneas no reviewed head.README: the
partialoutcome and the coverage rule.Verification
node --test, all passing (321 tests) on:publish-reviewpr-review-clipr-review-cli-api-callsapply-review-holdclaude-lane-review-completeclaude-lane-scopeclaude-lane-status-checkclaude-review-declared-outputsclaude-review-outcome-wiringclaude-lane-job-gatesclaude-lane-fallbackclaude-lane-compose-argsnetwork-timeout-policypartialwith no completion notice, and its first visible line states coverage. The hidden marker recordssha=none.incomplete.partialwithout failing.files_read, count or diff fileincomplete.coverage/files_read. Only the two marker-line assertions changed text.noneon a partial review fails the publish suite.zizmor --offline: no findings. Biome check on.github/scripts: clean.review:security-revieweragent) of the first commit found no HIGH or CRITICAL issue. It raised one IMPORTANT issue: a head could commit.claude-lane/pr.diffas a symlink to/dev/null, so a stat of the path read 0 bytes and the budget check passed. The second commit fixes it, and a symlink test covers the fix. The review confirmed thatsha=nonematches no 40-hex consumer regex, that the new env values carry no injection path, and that every gap fails closed. One risk remains, and it is not new:files_readis self-reported, so a prompt injection can still claim full coverage of a diff under the budget, as it could already claim 0 findings.Related
pr-review-mainoversize)🤖 Generated with Claude Code