Problem
AO workers on a shared machine can take the whole fleet down with one bad process, and AO currently has no guardrail at the spawn boundary.
Two incidents from a multi-project factory on one 16GB macOS machine (ao 0.9.5, tmux runtime, codex + claude-code agents):
- A worker ran
ugrep -o '<pattern>' against an extracted spreadsheet's sheet1.xml (single enormous line). The process grew to a ~31GB footprint (16GB resident + 15GB compressed), swap hit 27/28.6GB, and every other worker on the machine slowed to a crawl until a human found and killed it.
- Recurring: workers start
next dev servers in their worktrees (5–12GB each once warm) and exit without tearing them down. The orphans survive the session's terminal state indefinitely.
We now carry a prose 'resource hygiene' clause in our spawn directive, but prose is advisory — an agent mid-task doesn't know its grep is about to eat 31GB.
Proposal
- Memory ceiling per spawn (opt-in, configurable per project/agent): launch the worker's pane process group under a memory cap —
ulimit -v where it works, or a launchd/cgroup-equivalent wrapper on macOS/Linux — so a runaway child gets OOM-killed instead of swapping the machine. Config sketch: agentConfig.maxMemoryMB: 8192.
- Orphan reaper on terminal state: when a session reaches a terminal lifecycle state (or
ao session kill), kill the session's remaining process group/children (the tmux pane's descendants), with an opt-out for deliberately detached processes.
- Nice-to-have: surface per-session RSS in
ao session ls / the dashboard so a runaway is visible before the machine pages out.
Happy to help test on our fleet.
🤖 Filed with Claude Code on behalf of @Tonedeath
Problem
AO workers on a shared machine can take the whole fleet down with one bad process, and AO currently has no guardrail at the spawn boundary.
Two incidents from a multi-project factory on one 16GB macOS machine (ao 0.9.5, tmux runtime, codex + claude-code agents):
ugrep -o '<pattern>'against an extracted spreadsheet'ssheet1.xml(single enormous line). The process grew to a ~31GB footprint (16GB resident + 15GB compressed), swap hit 27/28.6GB, and every other worker on the machine slowed to a crawl until a human found and killed it.next devservers in their worktrees (5–12GB each once warm) and exit without tearing them down. The orphans survive the session's terminal state indefinitely.We now carry a prose 'resource hygiene' clause in our spawn directive, but prose is advisory — an agent mid-task doesn't know its grep is about to eat 31GB.
Proposal
ulimit -vwhere it works, or a launchd/cgroup-equivalent wrapper on macOS/Linux — so a runaway child gets OOM-killed instead of swapping the machine. Config sketch:agentConfig.maxMemoryMB: 8192.ao session kill), kill the session's remaining process group/children (the tmux pane's descendants), with an opt-out for deliberately detached processes.ao session ls/ the dashboard so a runaway is visible before the machine pages out.Happy to help test on our fleet.
🤖 Filed with Claude Code on behalf of @Tonedeath