What they did
The Rulestack team runs a Claude Code agent on a Mac that fans work out to subagents and agent-team teammates. After one weekly review started 56 subagents and the machine ran low on memory, the owner set a cap of 10 running at once, written only as a rule in CLAUDE.md. That held in 15 of 16 sessions, but one research session climbed to 15 when teammates and their helpers each launched batches that looked fine locally. The team then added a shell script as a PreToolUse hook on the Agent tool. It hands the hook input to a TypeScript command that counts the session's subagents still running, judged from the last line of each subagent transcript, plus launches already approved in the same response, recorded in a small reservation file. At 10 it exits with code 2 and tells the agent to wait or split the plan into waves.
How it went
Across 676 launches since the hook went in, the peak has been exactly 10. It refused on two occasions. The first four refusals were wrong: subagents that finished by handing back a report did not end in a stop marker, so they looked like they were still running. The agent read the hook source, added that finish marker and relaunched the four reviewers two and a half minutes later. The six later refusals were correct and stopped a session that would have reached 16. The reservation path for launches in the same response has never caused a real refusal. Five test files with 142 tests cover the hook.
Worth knowing
Claude Code has its own limit of 20, set with CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS, but teammates follow separate limits, so it would not have caught this climb. If you do not use teammates, that variable is far less work. The hook counts per session, fails open without telling anyone, and reads an undocumented transcript format that has already broken it once.