Skip to content

fix(run-agent,pr-review,deps-verify): allow the agent to write its report files outside the checkout by exact path - #218

Merged
azlekov merged 1 commit into
mainfrom
fix/pr-review-runner-temp-writes
Oct 27, 2026
Merged

azlekov merged 1 commit into
mainfrom
fix/pr-review-runner-temp-writes

Conversation

@azlekov

@azlekov azlekov commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Closes #216.

Cause

This is a permission rule problem in this repo, not a runner or slot problem. Claude Code refuses a Write call, and a Bash > file redirect, to any path outside its working directories unless an Edit allow rule names that path. A headless run cannot ask, so it refuses. The checkout is the only working directory, and RUNNER_TEMP is outside it on every runner, hosted and self-hosted. pr-review's allowlist is Bash "Bash(gh:*)" Read Grep Glob plus the inline-comment tool, with no Write and no Edit rule. A run got its two files only when the agent happened to write them in a way Claude Code does not inspect.

Evidence from 34 pr-review runs across the org on 2026-10-27, all on the same Claude Code version, model and tool list:

  • 6 runs missed both files. Each reports permission_denials_count: 2, and each agent says its two writes under _temp/ were refused.
  • All 28 runs that wrote both files report 0 denials.
  • The 6 failing runs were spread over slots 1, 2 and 3, and passing runs ran on the same slots. So the slot had nothing to do with it.

deps-verify, issue-implement and pr-iterate do not hit this, because they allow bare Write and Edit.

Fix

  • run-agent turns report-file and a new write-files input into one Edit(//abs/path) rule each, added to --allowed-tools. That allows exactly those files, through Write or a redirect, wherever RUNNER_TEMP is. A path holding a glob or pattern character, a . or .. segment, or anything that would split the tool list is refused, and the step fails.
  • --add-dir on RUNNER_TEMP was rejected on purpose, because the agent's settings file and its secrets live there.
  • pr-review passes review-body.md as write-files. review-verdict.json is already its report-file.
  • When the agent is refused a tool call, run-agent now names it by tool and file in a warning, and adds it to the fallback report's why. A missing verdict now says Claude Code refused: Write …/review-verdict.json instead of a bare "without writing a valid review-verdict.json". It never logs content or command text.

Tests

  • actions/run-agent/test.sh: the writable step with a self-hosted slot RUNNER_TEMP outside the workspace and with a hosted one. The tests check the exact rules, that the rules split into their own tool-list entries, and that unsafe paths are refused. They also check that denials are named without content, and that the fallback why includes them. 94 pass.
  • Self test: PR Review must pass both files it asks for as report-file or write-files. A mutation check confirmed it fails when write-files is dropped.

Not verified

I could not test a live headless run of the Edit(//path) rule here. The local CLI's sign-in had expired. The behaviour follows Claude Code's permission docs: // anchors at the filesystem root, and Edit rules cover Write and output redirects. The first pr-review run on a self-hosted slot after release is the real check. It should report permission_denials_count: 0 and write both files.

🤖 Generated with Claude Code

Also: deps-verify's agent writes deps-bumps.json and deps-verdict.md in RUNNER_TEMP besides its report file, so its run-agent call now lists both in write-files. The writable step runs only when there is a file to allow.

@azlekov
azlekov force-pushed the fix/pr-review-runner-temp-writes branch 2 times, most recently from 4cdce14 to 52fdcb0 Compare October 27, 2026 11:48
…port files outside the checkout by exact path

Claude Code refuses a Write call or a shell redirect to a path outside its working directories unless an
Edit allow rule names it, and RUNNER_TEMP is outside the checkout on every runner. pr-review's allowlist
has no Write, so a run got its verdict files only when the agent happened to write them a way Claude
Code does not inspect.

run-agent now turns report-file and a new write-files input into one Edit(//path) rule per file, and
names refused tool calls (tool and file only) in its warning and in the fallback report's why.
pr-review passes review-body.md through write-files.

Closes #216

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@azlekov
azlekov force-pushed the fix/pr-review-runner-temp-writes branch from 52fdcb0 to adc31ac Compare October 27, 2026 11:48
@azlekov azlekov changed the title fix(run-agent,pr-review): allow the agent to write its report files outside the checkout by exact path fix(run-agent,pr-review,deps-verify): allow the agent to write its report files outside the checkout by exact path Oct 27, 2026
@azlekov
azlekov merged commit 9f7eb6f into main Oct 27, 2026
2 checks passed
@azlekov
azlekov deleted the fix/pr-review-runner-temp-writes branch October 27, 2026 11:50
github-actions Bot pushed a commit that referenced this pull request Oct 27, 2026
## [1.44.7](v1.44.6...v1.44.7) (2026-10-27)

### 🐛 Bug Fixes

* **run-agent,pr-review,deps-verify:** allow the agent to write its report files outside the checkout by exact path ([#218](#218)) ([9f7eb6f](9f7eb6f)), closes [#216](#216)
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.44.7 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

fix(pr-review): the agent is refused writes to RUNNER_TEMP on some self-hosted slots, so the verdict fails

1 participant