Skip to content

fix: move state files into workspace and address bash sandbox denials#9

Merged
mtrunkat merged 1 commit into
mainfrom
claude/mongodb-query-index-check-workspace-paths
May 17, 2026
Merged

fix: move state files into workspace and address bash sandbox denials#9
mtrunkat merged 1 commit into
mainfrom
claude/mongodb-query-index-check-workspace-paths

Conversation

@mtrunkat
Copy link
Copy Markdown
Member

Why

Two real-world runs against apify/apify-core showed ~10 permission denials per run, each costing Claude a turn. Three causes, all addressed here:

Cause Fix
$RESULT_PATH / $CHANGED_FILES_PATH live in $RUNNER_TEMP, outside the bash sandbox Move both into $GITHUB_WORKSPACE/__mongo_index_check/
Common text tools (awk, wc, sed, sort) not in allowlist Add them — read-only, no security surface
Claude doesn't know bash output redirection / chained commands are blocked, so it retries Document the sandbox in the prompt and require Write for the result file

What changes

action.yaml

  • Validate step now seeds $RESULT_PATH and $CHANGED_FILES_PATH to $GITHUB_WORKSPACE/__mongo_index_check/{result.txt,changed-files.json} via $GITHUB_ENV. The state dir naming mirrors the existing __mongo_index_check_apify_core/ sparse-checkout dir.
  • Pre-check step re-exposes $CHANGED_FILES_PATH under the name preCheck() reads (OUTPUT_CHANGED_FILES_PATH) via the step's env: block — no JS-side process.env mutation needed.
  • Render step drops its inline CHANGED_FILES_PATH (inherited from $GITHUB_ENV now).
  • Claude allowedTools gains Bash(awk:*), Bash(wc:*), Bash(sed:*), Bash(sort:*).

prompts/review.md

  • New "Bash sandbox notes" section right before the hard-constraints list:
    • Output redirection (>, >>, tee to a file) is blocked even within the workspace → use Write.
    • Chained commands (&&, ;) are rejected → one command per Bash call.
    • Paths outside $GITHUB_WORKSPACE are blocked for bash → state paths now live inside the workspace.
  • Step 4 tightened: "Use the Write toolprintf > $RESULT_PATH will fail."

Out of scope

  • max-turns stays at 100. Iterating the allowlist + prompt should bring real runs well under that on their own.
  • show_full_output: true stays on for now. Can revisit once we've seen a few more runs.

Test plan

  • python3 -c "import yaml; yaml.safe_load(...)"action.yaml valid
  • pnpm run lint / type-check / test — clean, 35/35
  • envsubst allowlist still aligned with all $VAR placeholders in the prompt (no new placeholders introduced — $GITHUB_WORKSPACE in the prompt body is left literal on purpose so Claude reads the env var name)
  • Real run: re-trigger the index check against an apify-core PR. Expected: permission_denials_count drops substantially. The remaining denials, if any, will be more useful signal.

Side effect

The action now creates __mongo_index_check/ inside the caller's workspace at every run. Mirrors the existing __mongo_index_check_apify_core/ pattern, doesn't get committed (ephemeral runner, actions/checkout@v6 cleans untracked files on next run anyway).


Generated by Claude Code

Real-world runs against apify-core showed ~10 permission denials per run
where Claude burned turns retrying calls the sandbox blocks. Three
classes of denial, all addressed here:

* **State paths outside `$GITHUB_WORKSPACE`.** Previously `RESULT_PATH`
  and `CHANGED_FILES_PATH` lived in `$RUNNER_TEMP`, which the bash
  sandbox forbids — Claude had to fall back to the native `Read`/`Write`
  tools after a few retries. Move both into
  `$GITHUB_WORKSPACE/__mongo_index_check/` so bash can touch them
  directly (alongside the existing `__mongo_index_check_apify_core/`
  sparse-checkout dir).

* **Common text utilities not in the allowlist.** Claude reached for
  `awk` / `wc` / `sed` / `sort` to slice diffs and got blocked. Add
  `Bash(awk:*)`, `Bash(wc:*)`, `Bash(sed:*)`, `Bash(sort:*)`. All
  read-only, no security surface added.

* **Prompt missing the sandbox shape.** Claude didn't know that bash
  output redirection (`>`, `>>`) is blocked even for in-workspace paths
  and that chained commands (`&&`, `;`) are rejected as "multiple
  operations". Add a short "Bash sandbox notes" section in the prompt
  documenting these constraints so Claude doesn't burn turns on
  retries. Also tighten step 4 to explicitly require the `Write` tool
  (not `printf > $RESULT_PATH`) for persisting the result.

`max-turns` default stays at 100.

No new envsubst placeholders. The Pre-check step picks up
`CHANGED_FILES_PATH` from `$GITHUB_ENV` (set in Validate) and re-exposes
it under the name `preCheck()` reads (`OUTPUT_CHANGED_FILES_PATH`), so
the JS doesn't need to mutate `process.env`.
Copilot AI review requested due to automatic review settings May 17, 2026 14:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the MongoDB query index check action to reduce Claude bash sandbox permission denials by moving state files into the workspace, expanding the bash allowlist, and documenting sandbox constraints in the review prompt.

Changes:

  • Move $RESULT_PATH / $CHANGED_FILES_PATH from $RUNNER_TEMP into $GITHUB_WORKSPACE/__mongo_index_check/ and seed them via $GITHUB_ENV.
  • Expand Claude’s --allowedTools bash allowlist to include common text utilities (awk, wc, sed, sort).
  • Add “Bash sandbox notes” to the prompt and require using Write (not output redirection) for $RESULT_PATH.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
mongodb-query-index-check/action.yaml Moves state files into the workspace, wires paths through env, and expands the allowed bash tools.
mongodb-query-index-check/prompts/review.md Documents bash sandbox limitations and tightens result persistence guidance to use Write.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +93 to +95
# CHANGED_FILES_PATH was seeded into $GITHUB_ENV by the Validate step. Pass it under the name
# preCheck() reads (OUTPUT_CHANGED_FILES_PATH) so we don't need to mutate process.env in the script.
OUTPUT_CHANGED_FILES_PATH: ${{ env.CHANGED_FILES_PATH }}
@mtrunkat mtrunkat merged commit 6e2aa05 into main May 17, 2026
6 checks passed
@mtrunkat mtrunkat deleted the claude/mongodb-query-index-check-workspace-paths branch May 17, 2026 14:17
fnesveda pushed a commit that referenced this pull request May 18, 2026
🤖 I have created a release *beep* *boop*
---


## [1.1.0](v1.0.0...v1.1.0)
(2026-05-18)


### Features

* add mongodb-query-index-check action
([#3](#3))
([e288951](e288951))
* add python-package-check composite action
([#11](#11))
([cafe9c0](cafe9c0))
* bump max-turns default to 100 and stream full Claude output
([#7](#7))
([812c5cb](812c5cb))
* expand allowed-tools list for mongodb-query-index-check
([#6](#6))
([42e0fe2](42e0fe2))
* make the review prompt directive instead of descriptive
([#8](#8))
([910af2a](910af2a))
* mention [@mtrunkat](https://github.com/mtrunkat) in the review summary
on findings ([#12](#12))
([2f0becd](2f0becd))


### Bug Fixes

* move state files into workspace and address bash sandbox denials
([#9](#9))
([6e2aa05](6e2aa05))
* Stop using `@octokit/rest` in scripts
([#10](#10))
([232b613](232b613))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

4 participants