Repository navigation
Run a row of read and command calls together, up to four at a time - #291
Conversation
The daemon gets apply_patch beside edit and write: Codex's patch format, checked whole before any file is written, with Codex's lenient context matching. On Responses it is a custom tool constrained by Codex's Lark grammar, its call stored as sent and answered with a custom_tool_call_output (tools.custom, schema 55); on Anthropic a function taking the patch as input. New bots get apply_patch on a Responses model and edit otherwise; the approver judges a patch by every file it names, and Sonny draws one as a diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…patch paths kept An insertion with no context goes at the end of the file, so a later chunk can change an earlier line; replacements are applied in file order and overlapping chunks fail instead of panicking. A moved file keeps the source's permissions. The approver reads the paths recovered from a cut patch preview. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…ounded, matching off the runtime A patch that changes one file twice is refused at parse, since the second change would be computed from the file as it was. A move to the same file (./f for f) is an ordinary update instead of a delete. The files a patch stages hold at most 64 MiB together. Matching runs on the blocking pool, normalizes each line once per pass and checks a place's last line first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…ept, a cut patch names all its files An added or moved-to path that is a folder, or sits below a file, fails before any file is written. A result of one empty line keeps its newline. tool_started names every file a cut patch changes, and the approver uses those over what the preview holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Past it the event says paths_cut, and a later call the approver judges is marked unseen, as when a written file is too long to show. A patch read from its cut preview alone counts the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
A sandboxed bot's patch is confined like its writes: each file it changes is checked against the bot's roots before any is written, and the files are written through the sandbox's helper. A patch that changes a file outside them escapes, and is gated as an escaping write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
… only regular files for a diff A sandboxed patch is staged before it takes a process slot, and one that only deletes takes none. Sonny's diff of an edit or a patch reads the file as it is now only when it is a regular file within the daemon's size limit, so a FIFO never blocks the screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…ipped Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…ound Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…nes compared Only the punctuation pass makes new strings, once for the whole file rather than for each chunk, and one update compares at most 50 million lines before it fails with invalid_patch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…cked in one sort Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…one placing budget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
…r at a time As Codex runs them: an ungated foreground command or a read starts beside the others in one commit, and each result is recorded in call order. A sandboxed bot's commands all run in its one sandbox; one that asks to leave it still runs alone, to be gated or refused. A steer moves every command still running to the background. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78c5a4d995
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… the screen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e32bf35f74
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t for store room beside the running calls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c490427dd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGFtCdGun1rPhhwTSrG
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 008da79e4b
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
| .iter() | ||
| .any(|(_, prepared)| matches!(prepared, Prepared::Shell { .. })); | ||
| let sandbox = match shells && record.sandboxed() { | ||
| true => self.sandbox(record, workspace).await, |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Security: Rebuild the sandbox policy before every shell spawn
With workspace-write enabled on Linux, a sandboxed bot can create inherited helpers rooted at /tmp and /tmp/x and replace /tmp/x with a symlink between calls. This batch constructs Policy once and clones it, so a later shell skips root()’s symlink recheck; the stale path reaches bwrap --bind, making an arbitrary host directory writable without escalation approval. The restricted socket permits children in caller-writable /tmp, and process-slot saturation can delay the later spawn until after the swap. Rebuild and revalidate the policy immediately before every shell spawn.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Not fixing this in this PR. It needs a hostile bot to swap a root for a symlink in the window between the batch's policy check and a later spawn, and the project's stance is to log sandbox edges like this rather than hold a release for them. It's logged in #96. The fix is small: build the policy per shell call, the way the lone path does.
Generated by Claude Code
…rent tool calls are built The README still said Agent provides no sandbox, and docs/EVIDENCE.md still listed concurrent tool calls as a design. Both now match main: bots made with a sandbox run confined (bubblewrap, Seatbelt), and calls in a row run together since #291, with no fleet measurement yet. Sonny's /usage is described as token usage from retained history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGEK7HMibaxgHFDtGXA
…rent tool calls are built The README still said Agent provides no sandbox, and docs/EVIDENCE.md still listed concurrent tool calls as a design. Both now match main: bots made with a sandbox run confined (bubblewrap, Seatbelt), and calls in a row run together since #291, with no fleet measurement yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013jkdGEK7HMibaxgHFDtGXA
…rent tool calls are built (#360) The README still said Agent provides no sandbox, and docs/EVIDENCE.md still listed concurrent tool calls as a design. Both now match main: bots made with a sandbox run confined (bubblewrap, Seatbelt), and calls in a row run together since #291, with no fleet measurement yet. Claude-Session: https://claude.ai/code/session_013jkdGEK7HMibaxgHFDtGXA Co-authored-by: Claude <noreply@anthropic.com>
Third PR from the tools-vs-Codex comparison, following #236, #247 and #254: parallel tool calls.
What changes
read) or run ungated foreground commands (shell) now starts together. At most four run at once. Codex runs these calls in parallel too.sandbox_permissions) still runs alone, so it can be gated or refused.Memory and load
A batch holds at most four calls' output buffers at once, and each is capped as before. The process budget still limits concurrent commands across all bots, so a batch can't run past it.
Tests
tests/test_wait.py: two calls that each sleep finish in about the time of one, and results come back in call order.tests/test_approvals.py: a sandboxed bot's two commands run together inside its sandbox, and a third that asks to escalate runs alone and is refused.test_approvals+test_waitpass (87 tests, with the sandbox tests on), and clippy is clean.No visible UI change, so no screenshots.
Generated by Claude Code