Summary
ensureSubagentConcurrencyLimit() ends by calling ensureMultiAgentV2ThreadLimit(result) unconditionally, and that helper writes [features.multi_agent_v2] max_concurrent_threads_per_session = 1000 into the user's config.toml on every run — creating the section if absent, and overwriting any user-set value if present. This happens regardless of the selected model, and there is no equivalent of the "hand-removed key stays removed" behavior that the same file deliberately implements for the legacy agents.max_threads path.
Pinned source at v4.17.0 (f39306f):
Why it matters
On multi_agent_v2 sessions (e.g. gpt-5.6-sol), max_concurrent_threads_per_session is effectively the only concurrency gate that holds:
We audited a runaway session on codex-cli 0.144.1 + gpt-5.6-sol where the injected runtime hint "There are 1000 available concurrency slots" appeared 23× in the rollout, alongside a spawn tree of 1,004 descendant threads (depth 11) and ~46 GB RSS before manual intervention. After we restored Codex's stock default (cap 4) by deleting the override, source inspection showed this migration would silently re-write 1000 on the next session start with the plugin enabled — i.e. a user who fixes their config gets re-broken.
What v4.17.0 already improved (appreciated)
The v2 cap write is the remaining piece of #97.
Suggested fix
Any of, in order of preference:
- Stop writing
max_concurrent_threads_per_session unless the user opts in
- Honor existing / hand-removed user values, mirroring the
raiseExistingAgentsMaxThreads philosophy already applied to the v1 key
- At minimum, make the limit configurable instead of hard-coding
"1000"
LAZYCODEX_CONFIG_MIGRATION_DISABLED=1 exists but is all-or-nothing — enabling it also loses the genuinely useful guards (e.g. the #118 cleanup).
Environment
- codex-cli 0.144.1, model
gpt-5.6-sol (multi_agent_v2), macOS
- Originally observed with OMO 4.15.1; behavior confirmed by source inspection at
v4.17.0 (f39306f)
Summary
ensureSubagentConcurrencyLimit()ends by callingensureMultiAgentV2ThreadLimit(result)unconditionally, and that helper writes[features.multi_agent_v2] max_concurrent_threads_per_session = 1000into the user'sconfig.tomlon every run — creating the section if absent, and overwriting any user-set value if present. This happens regardless of the selected model, and there is no equivalent of the "hand-removed key stays removed" behavior that the same file deliberately implements for the legacyagents.max_threadspath.Pinned source at
v4.17.0(f39306f):CODEX_SUBAGENT_THREAD_LIMIT = "1000": subagent-limit-guard.mjs#L5ensureSubagentConcurrencyLimit: subagent-limit-guard.mjs#L38Why it matters
On multi_agent_v2 sessions (e.g.
gpt-5.6-sol),max_concurrent_threads_per_sessionis effectively the only concurrency gate that holds:agents.max_depthis not enforced on the v2 spawn path (agents.max_depth = 1 permits child-to-grandchild spawning in 0.144.1 openai/codex#32027, still open)cap − 1)[features.multi_agent_v2] enabled = falsedid not disable v2 forgpt-5.6-sol— model catalog metadata took precedenceWe audited a runaway session on codex-cli 0.144.1 +
gpt-5.6-solwhere the injected runtime hint"There are 1000 available concurrency slots"appeared 23× in the rollout, alongside a spawn tree of 1,004 descendant threads (depth 11) and ~46 GB RSS before manual intervention. After we restored Codex's stock default (cap 4) by deleting the override, source inspection showed this migration would silently re-write1000on the next session start with the plugin enabled — i.e. a user who fixes their config gets re-broken.What v4.17.0 already improved (appreciated)
agents.max_threadsremoved instead of written (thev2Preferredbranch inensureSubagentConcurrencyLimit), and a hand-removed key stays removed on the no-model-evidence pathhide_spawn_agent_metadatacleanup works as describedThe v2 cap write is the remaining piece of #97.
Suggested fix
Any of, in order of preference:
max_concurrent_threads_per_sessionunless the user opts inraiseExistingAgentsMaxThreadsphilosophy already applied to the v1 key"1000"LAZYCODEX_CONFIG_MIGRATION_DISABLED=1exists but is all-or-nothing — enabling it also loses the genuinely useful guards (e.g. the #118 cleanup).Environment
gpt-5.6-sol(multi_agent_v2), macOSv4.17.0(f39306f)