Repository navigation
fix(task_steps): reach the container of a container-mode deploy_sandbox sandbox - #68
Merged
Merged
Conversation
…ox sandbox A container-mode deploy_sandbox sandbox is either the container itself (a container provider such as modal) or a container running beside a VM host (a VM-backed provider such as local, modal_vm or e2b), where only `docker exec <container>` reaches its files. The sandbox_name steps treated it as a VM: - load_artifact(sandbox_name) staged onto the VM host: on a container provider the host-only calls do not exist, and on a VM-backed one the files land where the container never sees them. - collect_artifacts / verify_sandbox(sandbox_name) read the VM host. A VM-backed provider reattaches every sandbox as a VM, so the steps decide from the mode deploy_sandbox recorded (DeployedSandbox.sandbox_mode): - load_artifact stages files into a container-mode sandbox the way an agent's container is loaded, through stage_files_into_container (moved out of A2AAgent.load_file_artifact_universe, which now uses it); URLs go through write_file_from_url and environment payloads into the sandbox's container. - collect_artifacts and verify_sandbox reach into the container of a container-mode sandbox on a VM-backed provider. - collect_artifacts reads inside a container as root, like the steps that write there: files they leave are root-owned, which a non-root image user cannot always read. VM-mode sandboxes and agents are unchanged.
psinghal20
force-pushed
the
pratyush/container-sandbox-file-routing
branch
from
October 6, 2026 17:20
50161e8 to
e106517
Compare
…r test's probe dir root-only Addresses review: a non-root image user couldn't read files load_artifact wrote as root, so probe_file_* criteria failed. bash_cmd_succeeds still runs as the image user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
psinghal20
added this pull request to stack #72
October 6, 2026 17:51
earakely-scale
approved these changes
Oct 6, 2026
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.
Background
A container-mode
deploy_sandboxsandbox comes in two shapes:modal). A plain exec runs inside it.local,modal_vm,e2b, and any provider using the basecreate_container). A plain exec runs on the host; onlydocker exec <container>reaches the container's files.VM-backed providers reattach every sandbox as a VM (
localtoo, since #37), so a step that looks at the reattached sandbox'smodecannot tell a container-mode deploy apart. The modedeploy_sandboxrecorded,DeployedSandbox.sandbox_mode, can.Why agents and envs already worked
load_artifactwithagent_nameorenv_idalready reaches containers:A2AAgent.load_file_artifact_universe): chooses by sandbox class. AVmSandboxgetsdocker exec -u 0 <container_name> mkdir+write_file_from_s3(staged on the host,docker cp'd in); a container sandbox getsexec mkdir+ a direct write.MCPServerEnv._copy_artifact_into_container): writes into a container-mode sandbox directly, and on a VM stages on the host anddocker cps into the server's container.sandbox_name): none of this.load_artifactalways staged onto the VM host, andcollect_artifacts/verify_sandboxalways read it.Edge cases
1. Loading into a container-mode
deploy_sandboxdeploy_sandbox(sandbox_mode="container")→load_artifact(sandbox_name).exec_script/load_s3_fileexist only on a VM sandbox); on a VM-backed provider the files landed on the host, where the deployed image never sees them.A2AAgent.load_file_artifact_universeinto a sharedstage_files_into_container, which both use. URLs go throughwrite_file_from_url, environment payloads into the sandbox's container. VM mode is unchanged.2. Collecting from / verifying a container-mode
deploy_sandboxcollect_artifacts(sandbox_name)/verify_sandbox(sandbox_name).docker exec <container_name>), decided by the recorded mode; a container provider is still exec'd directly.3. Reading root-owned files from a non-root image
USER, holding files the steps wrote as root (docker exec -u 0,docker cp).collect_artifactsrandocker exec <container>as the image's user and could not read a root-only file (base64 read failed), so the step dropped it.collect_artifactsreads inside a container as root (docker exec -u 0), like the steps that write there. This applies to agent containers on a VM too; collect only reads (stat,base64,find), so it can only see more.verify_sandboxprobes keep the image's user, so a verifier'sbash_cmdis unchanged.Unchanged: VM-mode sandboxes, agents (including a reattached local agent, #37), and container providers.
Tests
tst/unit/task_step/test_container_sandbox_routing.py(new): which containercollect_artifacts/verify_sandboxreach for an agent and for a named sandbox: VM, a VM-backed container (livecontainer, and reattached asvmwith a recordedcontainer), and a container provider.tst/unit/task_step/test_load_artifact_container_sandbox.py(new): container-mode staging on a container provider (mkdir +write_file_from_s3, nothing on a host) and on a VM-backed one (docker exec+write_file_from_s3), URLs viawrite_file_from_url, recorded metadata.tst/unit/task_step/test_collect_artifacts_vm_host.py,test_collect_artifacts.py:_exec_argsreads in a container with-u 0.tst/integration/task_step/test_container_sandbox_files_local.py(new; Docker + a throwawayregistry:2):load_artifact→verify_sandbox→collect_artifactson a path only the container has, for a container-modedeploy_sandboxwith a non-root image user (fails atload_artifactwithout this change) and for a local echo agent. Cleanup removes only the containers of sandboxes in the test's own sandbox root.tst/unit+ protocol suite in apython:3.12slim image: 6084 passed; the 3 failures (local_sandbox_testprocess-group tests,run_docker_container_test::test_a_context_zip_from_a_non_s3_store_unpacks_in_a_real_local_sandbox) fail identically onmainin that image (nounzip/ process tools).check_plugin_api.py: no break to the plugin surface.Not covered: real
modal_vm/e2bcontainer-mode sandboxes; they take the sameVmSandboxpath aslocal.Follow-up:
run_codeondeploy_sandboxsandboxes builds on this.🤖 Generated with Claude Code
The PR appears safe to merge; the earlier file-routing and root-access findings are addressed.
Summary
Named container-mode sandboxes now receive, verify, and return files from their container, including when a VM-backed provider reattaches them as a VM. Container reads also run as root so they can see root-owned files.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A["Named sandbox file step"] --> B{"Recorded sandbox mode"} B -- VM --> C["VM host"] B -- Container --> D{"VM-backed provider?"} D -- Yes --> E["docker exec into container"] D -- No --> F["Use container sandbox directly"]Reviews (3) · Last reviewed commit: "fix(verify_sandbox): probe container fil..."