Conversation
Grok isolated-write lanes cancel every run_terminal_command at a permission prompt the headless CLI cannot show, and the receipt reports malformed-output with evidence truncated to the init event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Grok cancels any tool call that needs an approval prompt when it runs headless, so isolated-write lanes lost every run_terminal_command and ended the turn. Writers now pass --allow Bash, which pre-approves the shell tool while the workspace sandbox, deny rules, and hooks still apply. The tool list uses Grok's real name, run_terminal_command. A Grok turn that ends on a permission cancellation now records permission-cancelled with the cancelled tool result and terminal event as evidence. Other Grok error results record child-failed. Both keep the reported model, session, usage, and cost instead of malformed-output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With shell commands pre-approved, a Grok writer can read and send anything in its environment. The test requires parent tokens and agent sockets to stay out of it while paths, locale, proxies, and Grok's own settings pass through. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Grok writer's shell is pre-approved, and Grok's workspace sandbox reads the whole host and, on macOS, never blocks child-process network. The runner passed it the parent's full environment, so a prompt-injected writer could send any token there to the network. Grok writers now get an allowlisted environment: paths, user, shell, locale, terminal, proxy and CA settings, and GROK_* and XAI_*. Other lanes keep the existing identity-only scrub. The dispatch reference now states the real trust boundary instead of claiming commands outside the workspace are cancelled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Grok 1.0.41 accepts run_terminal_cmd as the --tools ID and shows the tool to the model as run_terminal_command. Passing run_terminal_command makes Grok drop the whole allowlist, so every lane, read-only included, gets all 17 tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run_terminal_command is the name the model sees, not a valid --tools ID. Grok drops an allowlist that contains an unknown ID, so every Grok lane had all 17 tools, including write and search_replace in read-only lanes. With run_terminal_cmd a writer lane gets exactly its 5 tools and a reader its 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Grok's headless `acceptEdits` mode does not pre-approve its file tools. An isolated-write lane's `write` and `search_replace` calls stop at an approval prompt that headless mode cancels, so the lane ends without changing a file. The writer allowlist also leaves out `write`, Grok's file-creation tool. Expect the isolated-write argv to list `write` and to pass `--allow Edit` after `--allow Bash`. The read-only argv pin is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Headless Grok cancels any tool call that needs an approval prompt. The `acceptEdits` mode does not pre-approve Grok's file tools, so Grok cancelled every `write` and `search_replace` call in an isolated-write lane. The lane exited 77 with `permission-cancelled` and changed nothing. Pass `--allow Edit` after `--allow Bash` for isolated-write lanes. Grok's `Edit` rule covers both `search_replace` and `write`, and the `workspace` sandbox still refuses writes outside the worktree. Add `write` to the writer's `--tools` allowlist so the lane can call Grok's file-creation tool. Read-only lanes are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
On grok CLI 1.0.41, `--allow Bash` pre-approves plain commands such as
`touch`, `mkdir`, `git add`, and `python3 -c`. Grok still prompts for a
shell command that writes output into a file, such as `> out.txt` or
`| tee out.txt`, even with `--allow Edit`. It also prompts for a command
it cannot split into simple segments, such as `$(...)`,
`${VAR:-default}`, or a subshell. Headless mode cancels each of those
prompts. A heredoc or a multi-line `python3 -c` passes when it does not
redirect into a file.
Tell Grok writers to change files with their file tools and to run build
and test steps as plain commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Headless Grok cancels any tool call that needs an approval prompt, then ends the turn. The runner starts
isolated-writeGrok lanes with--permission-mode acceptEdits, but on grok CLI 1.0.41, that mode does not pre-approve Grok's file tools. Everywriteandsearch_replacecall stops at a prompt that headless mode cancels. The runner exits 77 with apermission-cancelledreceipt, and the worktree has no changes. A realgrok:grok-4.7@xhighimplementation lane ended this way after 38 turns. Its last tool result was "User cancelled the execution for toolwrite".isolated-writeGrok lanes now pass--allow Editafter--allow Bash. Grok's permissions doc groupsWritewithEditas one rule name, and live probes show that--allow Editpre-approves bothsearch_replaceandwrite. Theworkspacesandbox still refuses writes outside the worktree, and deny rules and hooks still apply. Read-only lanes pass no allow rules, as before.isolated-write--toolslist now includeswrite. Now that fix(runner): let headless Grok writers run shell commands #81 restores the valid terminal ID,run_terminal_cmd, Grok honors the allowlist. Without this entry, a writer cannot callwriteat all.provider-dispatch.mdnames the new rule and says why the lane needs it. It also names the shell commands Grok still cancels under--allow Bash, so writer prompts keep file changes on the file tools.This PR stacks on #81. Until #81 merges, this PR also shows #81's commits. Review the top three commits,
test(runner): reproduce headless Grok writers losing file edits,fix(runner): pre-approve file edits for headless Grok writers, anddocs(dispatch): name the shell commands headless Grok still cancels.Tradeoffs
--toolslist withwriteand no allow rule does not help. That probe still ends with "User cancelled the execution for toolwrite".--always-approvewould approve every tool, which theuses bounded write modes without blanket bypassestest forbids.--no-planchanges nothing.Edit(<worktree>/**)would not shrink what the lane can write. The pre-approved shell can already write anywhere the sandbox allows, so the sandbox is the real limit.Verification
On 7140d30, the two changed tests fail (
commands.test.ts: 4 pass, 2 fail). With the fix,bun run testpasses 162/162.bun run typecheck, the manifest JSON checks,PSTACK_STATIC_ONLY=1 bash tests/skill-collision-repro.sh, andgit diff --checkpass.Live evidence so far comes from the source runner on this branch. A Claude Code session's shell launched it with
--parent claude --provider grok --model grok-4.7 --effort xhigh --mode isolated-writeon grok CLI 1.0.41, and Grok reported the model asgrok-4.7-build. Each lane ran in a fresh scratch git repository. The 7140d30 column is #81's head. It ran once from the installed Claude Code plugin and once from source.probe.txtwithwritewritetool. It either falls back tosearch_replace, which it then cancels with exit 77, or repliesFAILED. No file is created.complete,probe.txtcreatedalphawithbetainseed.txtwithsearch_replacepermission-cancelledonsearch_replacecomplete,seed.txtreadsbetanotes/hello.txtand editseed.txt, no tool namedpermission-cancelledonsearch_replacecomplete, both changes made$HOMEwithwriteGrok's session
tool_definitions.jsonfor these lanes lists exactly six tools:grep,list_dir,read_file,run_terminal_command,search_replace, andwrite.The shell note comes from one-command probes on the same argv, read from Grok's
permission_resolvedevents. Grok allowedtouch,mkdir,git add,echo, a single-line and a multi-linepython3 -c, a heredoc intocat, andprintf ... > /dev/null. It cancelledprintf ... > plain.txt,printf ... | tee teed.txt,echo "$(pwd)",echo "${PROBE_UNSET:-x}", and(cd . && ls).This PR stays a draft until the exact candidate is installed in the Claude Code and Codex harnesses and passes from both.
🤖 Generated with Claude Code