Repository navigation
feat(computer)!: an app's shm_mb sizes its computer's /dev/shm - #573
Merged
earakely-scale merged 3 commits intoNov 9, 2026
Merged
earakely-scale merged 3 commits into
earakely-scale merged 3 commits into
Conversation
A Linux app declares the shared memory it needs with @linux(shm_mb=N), checked at put. A computer takes the most its apps ask for, records it with its composed computer and its deploy, and boots with it: the VM path's docker run and local Docker pass --shm-size, a reset keeps it, the disk form's init mounts /dev/shm at that size (512 MiB without), and a container-only backend (Modal, CoreWeave) boots anyway and logs that it can't size it. agentenv's chromium asks for 1024 MiB, so Chrome keeps its shared memory in /dev/shm rather than in files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ask for A probe boots a build as a deploy with no env_params does, so it now passes the computer's shm_mb too: an app that needs its size to start no longer fails at the probe and leaves its build undeployable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es shm_mb only to one that does A sandbox provider says whether the container create_container or reset_container runs has the /dev/shm their shm_mb asks for, or more. It's derived when undeclared: on for the default VM path, off for a container-only backend and for a class that overrides either method. A deploy, its probe and a reset pass shm_mb only to a provider that declares it, and log once otherwise, so a plugin whose create_container doesn't take shm_mb boots as before. Local Docker, sail_vm and Modal declare it (Modal's /dev/shm is a host-sized tmpfs); CoreWeave no longer takes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
deleted the
edgararakelyan/fd-5052-m850-an-apps-shared-memory-shm_mb-on
branch
November 9, 2026 23:31
Comment on lines
+266
to
+270
| if "SHARED_MEMORY" not in cls.__dict__: | ||
| if {"create_container", "reset_container"} & cls.__dict__.keys(): | ||
| cls.SHARED_MEMORY = False | ||
| elif cls.create_container is SandboxProvider.create_container: | ||
| cls.SHARED_MEMORY = SANDBOX_MODE_VM in cls.SUPPORTED_SANDBOX_MODES |
There was a problem hiding this comment.
Older plugin subclasses cannot reset
If a VM plugin overrides reset_container with the old signature, a subclass that inherits it can wrongly regain SHARED_MEMORY. The override is absent from the child's __dict__, while its inherited create_container matches the base method, so this check turns the flag back on.
For an app that requests shared memory, reset_env then passes shm_mb to the old reset method and fails with an unexpected keyword argument. Check inherited reset methods too, and preserve the parent's capability decision when neither method changes.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agent_env/providers/sandbox_providers/sandbox_provider.py
Line: 266-270
Comment:
**Older plugin subclasses cannot reset**
If a VM plugin overrides `reset_container` with the old signature, a subclass that inherits it can wrongly regain `SHARED_MEMORY`. The override is absent from the child's `__dict__`, while its inherited `create_container` matches the base method, so this check turns the flag back on.
For an app that requests shared memory, `reset_env` then passes `shm_mb` to the old reset method and fails with an unexpected keyword argument. Check inherited reset methods too, and preserve the parent's capability decision when neither method changes.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
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
A Linux app can now declare the shared memory it needs:
@linux(..., shm_mb=N), in MiB. A computer gives its/dev/shmthe most any of its apps asks for. agentenv's chromium asks for 1024, so Chrome keeps its shared memory in/dev/shminstead of in files (--disable-dev-shm-usage), which it used to fall back to on Docker's 64 MiB.This is M8.50 (FD-5052).
shm_mbis checked likeports: 1 to 65536 MiB, Linux installs only. A macOS or Windows install that names it is refused.metadata["computer"]["shm_mb"]and in the deploy record'smetadata["computer"]["shm_mb"]. Nothing is recorded when no app asks.create_containerandreset_containertakeshm_mb:docker run(modal_vm and every VM backend) and local Docker pass--shm-size {N}m;reset_env;env_paramsdoes;/dev/shmatAGENTENV_SHM_MBMiB, which the deploy puts in the seed (512 MiB without it, as before);shm_mbonly to a provider whoseSHARED_MEMORYis on (below). Any other provider, such as CoreWeave, a container-only backend or a plugin that overridescreate_container, boots with its own/dev/shm, and the deploy logs<Provider> can't size /dev/shm: the container keeps its default, not the N MiB asked for.SandboxProvider.SHARED_MEMORY, besideWEBSOCKETSandPRIVATE_NETWORK, says whether the containercreate_containerorreset_containerruns has the/dev/shmthatshm_mbasks for, or more. Local Docker and sail_vm declare it. The default VM path (modal_vm, smol_vm, any VM plugin that keeps the basecreate_container) gets it derived. Modal declares it because its/dev/shmis a host-sized tmpfs larger than any app can ask. It is off for a container-only backend, and for a class that overridescreate_containerorreset_containerwithout declaring it.shm_sizefor the browser it adds to compose.Decisions (FD-5052)
/dev/shmfromAGENTENV_SHM_MB, defaulting to 512 MiB.shm_mband logs.Rollout
Linux.shm_mbdefaults toNoneand the protocol dumps withexclude_none, so an app that doesn't name it stores and hashes as before.boot/initchanged, as it did in feat(computer): a versioned disk boot seed, and a reset an older launcher can't misread #476. New composes and the next release's published base disks get new keys. A disk composed before this PR keeps its old init, which ignoresAGENTENV_SHM_MB: it boots at 512 MiB, and chromium on it falls back to--disable-dev-shm-usageas it does today.!is for the plugin-api check.SandboxProvider.create_containerandreset_containergainshm_mb, which the check counts as a break to the surface because it reads signatures. But a deploy passesshm_mbonly whereSHARED_MEMORYis on, and a class that overrides either method is off unless it declares it. So a plugin with the old signature never receives it: it boots with its own/dev/shm, and the deploy logs. A unit test boots such a plugin.Measured
ShmSize=1073741824and a 1 GiB/dev/shm, a reset asking again keeps it, and a reset asking for none gets Docker's 64 MiB./dev/shm. Its/dev/shmis a tmpfs of about 377 GiB (size=395120960k, the host's), more than any app can ask for, and Modal's SDK has no option to size it. The sandbox's memory limit is what bounds it.Tests
shm_mb;shm_mb, the record keeps it, a reset passes it again, and nothing is passed without it;AGENTENV_SHM_MBat boot and reset, andcreate_vmgets noshm_mb;--shm-size 1024mat create and reset.SHARED_MEMORYis derived on for the VM path and off where a class overrides create or reset without declaring it. A boot passesshm_mbto a provider that gives it, and for a plugin with the old signature only logs while the plugin boots;chromium_app_test.pytest deploys chromium's desktop, reads/dev/shmwithstatvfsas the browser base does, checks Chrome's argv,reset_envs, and reads both again. It runs as a container and, on a machine with/dev/kvm, as a disk. The existing argv test no longer expects--disable-dev-shm-usage.website_browser_test.py's fixture browser declares nothing, so it still expects the flag: that is the control./dev/kvm; arm64 is an m7g.4xlarge. All results are at fc84d49 unless marked./dev/shm(statvfs), runs without--disable-dev-shm-usage, and keeps both afterreset_env./dev/shmand keeps it across areset_env(a reboot).disk_test.pyanddisk_boot_test.pypass there too (4/4), so the desktop disk still boots at 512 MiB when nothing asks.boot/initput back, the same disk test fails with[536870912, 536870912](512 MiB at boot and after the reset). So the test does measure the init.--mount type=imagefails on the disk's long image reference ("file name too long") before the VM starts. The same mount works under a short tag. That's FD-5416. CI's runners use the classic store, so CI only tests the copy path.chromium_app_test,website_browser_test,browser_computer_test,computer_app_test,computer_env_test,multi_env_computers_test,desktop_example_test,recording_chaos_test,multi_env_child_envs_local_test,test_verify_sandbox_local,disk_test):exec format error). They pass on amd64.ulimit -n 1024, which the tier's local-sandbox and gateway files exhaust. They fail identically at main (0ec4652): 45 failed and 22 errors on both trees. Withulimit -n 65536those files pass (597) bar the 3 known environment-only tests (nohttpxin the system Python, no.gitin the synced tree).🤖 Generated with Claude Code
The inherited old-plugin reset failure still needs fixing before merge.
Fix with agent prompt
Summary
Apps can request Linux shared memory through
shm_mb. Computers use the largest request and keep it across resets.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A["Apps declare shm_mb"] --> B["Computer takes largest request"] B --> C["Probe or deploy"] C --> D{"Computer form"} D -->|Container| E{"Provider SHARED_MEMORY"} E -->|On| F["Pass shm_mb"] E -->|Off| G["Keep default and log"] D -->|Linux disk| H["Seed AGENTENV_SHM_MB"] B --> I["Save size in deploy record"] I --> J["Reset repeats the same path"]Reviews (6) · Last reviewed commit: "feat(providers): a provider declares SHA..." · Reviewed by Greptile