Просмотр исходного кода

fix(ci): give the review bot the pull request's own code and CI verdict

Three consecutive review runs (#6105, #6265, #6272) posted accurate findings
but ended with the same "nothing was verified" paragraph, and the transcripts
show why: under pull_request_target the only checkout is the base branch, so
every Read of a changed file returned the pre-merge version and the agent
fell back to fetching blobs one at a time through the API — 452 Bash calls on
#6105 alone. It tried `git fetch origin pull/N/head` in all three runs and was
denied every time.

Check the head out read-only beside the base tree and say so in the prompt, so
the reviewer greps the code actually under review. Nothing builds or executes
from pr-head/: this job carries a write-scoped token, which is exactly the
pwn-request REVIEW.md classes as blocking.

CI had already run the full gate on each head SHA, but no run ever looked —
`check-runs` appears in none of the three transcripts. Point the reviewer at
it so a red or missing required check becomes a finding instead of a
disclaimer.

Also pass an explicit review level: with none given the skill reuses the last
one typed, which in CI does not exist (ReportFindings recorded level=null on
#6272). And allow WebFetch/WebSearch — the PIA review was denied both while
trying to confirm the bundled PIA public key, then had to file that same check
as unverified.
Sanaei 8 часов назад
Родитель
Сommit
73a971c2d1
1 измененных файлов с 10 добавлено и 3 удалено
  1. 10 3
      .github/workflows/claude-bot.yml

+ 10 - 3
.github/workflows/claude-bot.yml

@@ -494,6 +494,13 @@ jobs:
       - uses: actions/checkout@v7
         with:
           persist-credentials: false
+      # Read-only: this job holds a write-scoped token, so building or running
+      # anything out of pr-head/ would turn the review into a pwn-request.
+      - uses: actions/checkout@v7
+        with:
+          ref: refs/pull/${{ github.event.pull_request.number || github.event.issue.number }}/head
+          path: pr-head
+          persist-credentials: false
       - uses: anthropics/claude-code-action@v1
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -501,13 +508,13 @@ jobs:
           allowed_non_write_users: "*"
           plugin_marketplaces: "https://github.com/anthropics/claude-code.git"
           plugins: "code-review@claude-code-plugins"
-          prompt: "/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number || github.event.issue.number }}"
+          prompt: "/code-review:code-review high --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number || github.event.issue.number }}"
           claude_args: |
             --model claude-opus-5
             --effort xhigh
             --max-turns 100
-            --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh api:*),Bash(gh pr diff:*),Read(//tmp/**),Write(//tmp/**),Edit(//tmp/**)"
-            --append-system-prompt "Before reviewing, read REVIEW.md at the repository root and follow it: it defines what counts as a blocking finding in this repository, what not to report, and the repo-specific checks. Three overrides apply here. First, the skip gate for already-reviewed PRs: an existing Claude review comment justifies skipping ONLY when its 'Reviewed head:' SHA equals the PR's current head SHA; when the head has moved on, or this run was triggered by an explicit '@claude review' comment, run the full review, focusing on the commits since the previously reviewed head. Second, this is a headless run that terminates the moment you end your turn: launch every subagent with run_in_background set to false and wait for its result inside the same turn - never end your turn while a subagent is still running, and never end it before the review comment is posted. A run that ends without posting the review has failed. Third, the comment you post is the only part of this run anyone can see: it must carry the coverage list REVIEW.md asks for, whether or not you found anything."
+            --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh api:*),Bash(gh pr diff:*),Read(//tmp/**),Write(//tmp/**),Edit(//tmp/**),WebFetch,WebSearch"
+            --append-system-prompt "Before reviewing, read REVIEW.md at the repository root and follow it: it defines what counts as a blocking finding in this repository, what not to report, and the repo-specific checks. Five overrides apply here. First, the skip gate for already-reviewed PRs: an existing Claude review comment justifies skipping ONLY when its 'Reviewed head:' SHA equals the PR's current head SHA; when the head has moved on, or this run was triggered by an explicit '@claude review' comment, run the full review, focusing on the commits since the previously reviewed head. Second, this is a headless run that terminates the moment you end your turn: launch every subagent with run_in_background set to false and wait for its result inside the same turn - never end your turn while a subagent is still running, and never end it before the review comment is posted. A run that ends without posting the review has failed. Third, the comment you post is the only part of this run anyone can see: it must carry the coverage list REVIEW.md asks for, whether or not you found anything. Fourth, the default working tree is the BASE branch, and a read-only checkout of the pull request head sits beside it in pr-head/: read and grep the changed files under pr-head/, and treat anything read outside it as the pre-merge baseline rather than as the code under review. Never build, install or execute anything from pr-head/ - this job holds a write-scoped token, so running pull-request code with it is the workflow vulnerability REVIEW.md itself calls blocking. Fifth, you cannot build or test here, but CI already did: read the head commit's checks with 'gh api repos/OWNER/REPO/commits/HEAD_SHA/check-runs' and report what they actually concluded instead of writing that verification was unavailable. A required check that failed, or that never ran on this head, is itself a finding."
       - name: Upload the run transcript
         if: always()
         env: