From c52a4a37f0505bb020dd4f121dfe3908b8b30783 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jun 2026 16:45:34 +0700 Subject: ci(claude-review): allowlist the tools /code-review needs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The auto-review job runs /code-review headless, which uses Bash (git diff, gh), file search, and Task (it fans out sub-agent reviewers). None were allowlisted, so every such call stalled on a per-tool approval prompt and the review couldn't gather the diff or spawn reviewers. Add --allowedTools. Safe here (unlike claude.yml): this job is gated to same-repo PRs and its token is contents:read, so it cannot push. Bash is broad — scope to git/gh/grep if preferred. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude-code-review.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 59019616f..88d435c00 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,8 +53,15 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true + # /code-review needs git/gh (Bash), file search, and the sub-agents it + # fans out (Task). This job runs ONLY on same-repo PRs (the `if` above) + # with a contents:read token that cannot push — so, unlike claude.yml's + # fork-exposed @claude job, allowlisting these is safe. Without it the + # headless run stalls on per-tool approval and can't read the diff or + # spawn reviewers. (Bash is broad; scope it to git/gh/grep if preferred.) claude_args: | --max-turns 50 --model claude-opus-4-8 --effort max + --allowedTools Bash,Read,Grep,Glob,Task,WebFetch,WebSearch,TodoWrite # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From 2bedc60e8335e33abe6c0ed24a1785e5b0e90a8d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jun 2026 17:04:32 +0700 Subject: ci(claude-review): trim allowlist to Bash (the only gated tool) Every blocked call in the review log was a compound Bash pipeline; Read/Grep/ Glob/Task already ran un-prompted, so only bare Bash needs allowlisting. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude-code-review.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 88d435c00..18659e2c7 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,15 +53,14 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true - # /code-review needs git/gh (Bash), file search, and the sub-agents it - # fans out (Task). This job runs ONLY on same-repo PRs (the `if` above) - # with a contents:read token that cannot push — so, unlike claude.yml's - # fork-exposed @claude job, allowlisting these is safe. Without it the - # headless run stalls on per-tool approval and can't read the diff or - # spawn reviewers. (Bash is broad; scope it to git/gh/grep if preferred.) + # The review's only blocked calls were COMPOUND Bash commands (sed/python/ + # grep pipelines): default permission mode splits a multi-op command and + # gates the parts not on its allowlist. Bare `Bash` allows them all; + # Read/Grep/Glob/Task already run un-prompted. Safe here (unlike claude.yml): + # same-repo-only + contents:read token that cannot push. claude_args: | --max-turns 50 --model claude-opus-4-8 --effort max - --allowedTools Bash,Read,Grep,Glob,Task,WebFetch,WebSearch,TodoWrite + --allowedTools Bash # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1 From 37e247176cb37e15f25622bdbdc6b03931ff3d9b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jun 2026 17:14:29 +0700 Subject: ci(claude-review): allowlist Write too (review writes a helper script) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The log shows two gated tools, not one: compound Bash pipelines AND Write — the review tried to drop check_headings.py (at /tmp, then the workdir, both denied). Add Write to the allowlist. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/claude-code-review.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 18659e2c7..a9b026bfd 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -53,14 +53,15 @@ jobs: # TEMPORARY: expose the full Claude transcript in the Actions log for # debugging. Revert to remove once done. show_full_output: true - # The review's only blocked calls were COMPOUND Bash commands (sed/python/ - # grep pipelines): default permission mode splits a multi-op command and - # gates the parts not on its allowlist. Bare `Bash` allows them all; - # Read/Grep/Glob/Task already run un-prompted. Safe here (unlike claude.yml): - # same-repo-only + contents:read token that cannot push. + # The headless review was blocked on two tools: compound Bash pipelines + # (sed/python/grep) and Write (it dropped a check_headings.py helper to + # inspect the diff). Default permission mode gates both; Read/Grep/Glob/ + # Task already run un-prompted. Allowlist them. Safe here (unlike + # claude.yml's fork-exposed @claude job): same-repo-only + contents:read + # token, so any write is ephemeral and nothing can be pushed. claude_args: | --max-turns 50 --model claude-opus-4-8 --effort max - --allowedTools Bash + --allowedTools Bash,Write # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md -- cgit v1.3.1