Project-scoped subagent policy profiles: named-agent allowlists, model/effort gates, and concurrency quotas

Open 💬 1 comment Opened Jul 15, 2026 by Gerry9000

What variant of Codex are you using?

Codex CLI primarily; the same policy should apply consistently in the desktop app and IDE extension when they use project-local Codex configuration.

What feature would you like to see?

Codex should support project-scoped subagent policy profiles that can:

  1. Restrict spawning to an allowlist of named custom agents.
  2. Treat the selected named agent's model and reasoning effort as immutable unless the active policy explicitly permits overrides.
  3. Limit concurrency by named agent and by resolved model/model family.
  4. Switch policy profiles easily between project phases such as discovery, implementation, and adversarial review.
  5. Apply the quota across the project, not merely one parent thread, so multiple Codex sessions cannot accidentally exceed an expensive-model limit.

Codex already supports project-local custom agents and a global agents.max_threads, but max_threads cannot express policies such as:

  • allow up to ten Luna workers;
  • allow only one Sol worker across the project;
  • prohibit generic/default workers;
  • permit one set of model/effort combinations during implementation and a smaller set during final review.

A possible project-local configuration could look like this:

# .codex/config.toml
[agents]
max_threads = 12
policy = "implementation"

[agents.policies.discovery]
allowed_agent_types = ["luna_high", "luna_xhigh"]
require_named_agent = true
allow_model_override = false
concurrency_scope = "project"
on_limit = "queue"

[agents.policies.discovery.max_concurrent_models]
"gpt-5.6-luna" = 10
"gpt-5.6-sol" = 0

[agents.policies.implementation]
allowed_agent_types = ["luna_high", "luna_xhigh", "sol_low"]
require_named_agent = true
allow_model_override = false
concurrency_scope = "project"
on_limit = "queue"

[agents.policies.implementation.max_concurrent_models]
"gpt-5.6-luna" = 10
"gpt-5.6-sol" = 1

[agents.policies.review]
allowed_agent_types = ["luna_xhigh", "sol_medium"]
require_named_agent = true
allow_model_override = false
concurrency_scope = "project"
on_limit = "queue"

[agents.policies.review.max_concurrent_models]
"gpt-5.6-luna" = 4
"gpt-5.6-sol" = 1

The exact schema is flexible. The important semantics are:

  • Resolve the named agent configuration first.
  • Validate its resolved model and reasoning effort against the active policy.
  • Reject unnamed/built-in/generic agents when require_named_agent = true.
  • Prevent spawn-time model or reasoning overrides from bypassing the policy.
  • Enforce per-agent and per-model quotas before allocating the thread.
  • Keep agents.max_threads as the overall hard ceiling.
  • Either queue or fail with a clear diagnostic when a quota is reached.
  • Provide explicit session selection, for example codex --agent-policy review or /agent-policy review, while allowing a project default.
  • Show the active policy, resolved agent/model/effort, and quota usage in /agent.

This is useful even when all models are available. Model selection is an orchestration and cost/quality decision, not just an entitlement decision. For one project, we may intentionally use only named Sol and Luna agents: Luna high/xhigh for parallel implementation or evidence work, and Sol low/medium for scarce higher-value review or implementation tasks. Sol should remain scarce so it is used at the appropriate decision points rather than consumed by broad fan-out.

Acceptance criteria

  • A trusted project can define two or more subagent policy profiles locally.
  • The user can select a profile at launch or during a session.
  • A named-agent-only profile blocks generic and unapproved agent types.
  • A profile can allow exact model/reasoning combinations and disallow caller overrides.
  • A project-scoped model quota of one prevents two concurrent Sol subagents even when different parent sessions request them.
  • A quota of ten permits ten concurrent Luna subagents when the global thread ceiling allows it.
  • Limit behavior is configurable as queue or fail, and diagnostics identify the exhausted quota.
  • Existing projects without policies retain current behavior.

Additional information

Related issues:

  • #11701 introduced model/reasoning-aware custom subagent configuration, but its requested enable/disable controls and named-agent-only enforcement are not documented in the delivered surface.
  • #9205 requests task-based model routing.
  • #14039 requests per-subagent model/provider/profile selection.

This request is specifically about enforceable, project-local allowlists and concurrency policy after agent/model resolution, rather than merely choosing a model.

Motivating third-party cost/performance analysis: https://x.com/rasbt/status/2075573860796436626/photo/1

That analysis should not be treated as a universal OpenAI benchmark. It illustrates why a project may choose a narrow Pareto-efficient set of model/effort combinations—for example Luna high/xhigh and Sol low/medium for its evaluated workload—and then need hard orchestration limits so the more capable or expensive tier is used deliberately.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗