Independent AI intelligence Two editions daily · ET
FervorAI

Analysis · August 17, 2026 · concept

Codex Multi-Agent V2GPT-5.6 LunaOpenAI Codexspawn_agentcodexagent-harnessmulti-agentagent-infrastructure

Codex Multi-Agent V2 Rejects Your Cheapest Subagent, and Your Config File Can't Override It

What spawn_agent's model filter actually does, why gpt-5.6-luna stopped working as a delegation target, and how to find out what your subagents cost now

A Codex user ran three fresh sessions in July and recorded what each one actually did rather than what it claimed. Starting gpt-5.6-sol with --disable multi_agent_v2 produced a session whose persisted turn_context.multi_agent_version read v2 anyway. Starting gpt-5.6-luna with --enable multi_agent_v2 also produced v2. So the flag worked, sort of, in one direction. Then the Sol parent tried to spawn a Luna child and got this, quoted from issue #36294:

Unknown model `gpt-5.6-luna` for spawn_agent. Available models: gpt-5.6-sol, gpt-5.6-terra

Luna is not unknown. It sits in the model picker. The same CLI will happily start a Luna session and run it on the V2 runtime. It just cannot be handed to spawn_agent as a child model, and nothing in your config changes that.

That gap is the story. Not the missing model, the missing authority.

Your config is a suggestion at the spawn boundary

Codex documents subagent configuration in a way that sounds like you own it. Custom agents live in TOML files under ~/.codex/agents/ or .codex/agents/, and the official subagents page says plainly that "if a custom agent file sets model or model_reasoning_effort, the value in the file takes precedence." There is a global agents.default_subagent_model setting. There is a per-spawn model field. Three documented layers of control, all yours.

Underneath that, Codex ships a model catalog with a field you never set. Run codex debug models and you get something like the output reported in #36294:

[
  {"model":"gpt-5.6-sol","multi_agent_version":"v2"},
  {"model":"gpt-5.6-terra","multi_agent_version":"v2"},
  {"model":"gpt-5.6-luna","multi_agent_version":"v1"}
]

PR #32751, titled "Restrict spawned-agent models to the active backend," makes spawn_agent check a candidate child against that catalog value. Not against the runtime the child would actually get. Against the string in the catalog.

So the two facts collide. Your feature flag can demonstrably promote Luna to the V2 runtime as a top-level session. The spawn check reads the static v1 and refuses. The reporter in #36294 laid this out cleanly, including the observation that disabling the flag does not downgrade Sol, whose metadata already selects V2. The flag can raise a model. It cannot lower one, and it does not reach the filter at all.

The takeaway I keep coming back to is not about Luna. It is that the harness now has a class of decision your configuration file does not participate in. You can write a valid setting, watch it take effect at the session level, and still be overruled one function call later by a value shipped from somewhere else.

OpenAI's own example configs break on this

Here is the part that convinced me this is a design problem rather than a preference.

The same docs page that describes the filter also ships example custom agents. In the PR-review example, docs_researcher is defined with model = "gpt-5.6-luna". In the frontend-debugging example, code_mapper is defined with model = "gpt-5.6-luna". Both are read-only workers, both exactly the shape Codex recommends Luna for. The docs describe gpt-5.6-luna as the model to "use for fast, narrowly scoped agents handling clear, repeatable, or high-volume work."

Copy either example into .codex/agents/, ask a Sol parent to delegate to it, and you get Unknown model.

Documentation that recommends a pattern the runtime rejects is a good signal that nobody meant for this to happen. It reads like a compatibility check written for a different problem, then applied to a surface it was not scoped for. Every linked issue is still open, none are assigned, and the earliest one in the chain (#34700) predates the current release line.

The cost shape, which is the part that hits your bill

Codex is candid that delegation is expensive: "subagent workflows consume more tokens than comparable single-agent runs because each subagent does its own model and tool work." That is fine when the workers are cheap. It is a different calculation when your cheapest worker is unreachable.

I want to be careful here, because I could not find OpenAI's published per-token table on a first-party page this run. A third-party Codex playbook lists Luna at $1 input and $6 output per million tokens, Terra at $2.50 and $15, and Sol at $5 and $30. Treat those as reported rather than confirmed. If the shape is roughly right, moving a read-heavy scan from Luna to Terra multiplies that worker's token cost by about 2.5x, and falling back to Sol multiplies it by five.

You are unlikely to notice this as an error. You will notice it as a number that drifted. Codex resolves the model chain in order (explicit spawn value, then the [agents] default, then the parent's value), so when the explicit value is filtered out, delegation does not fail loudly. It lands on something more expensive and keeps going.

Put this into practice

Fifteen minutes of checking, and you will know exactly where you stand.

1. Read your own catalog. Run codex debug models and look at the multi_agent_version field for every model you delegate to. This is the value the spawn filter uses. Anything marked v1 is not spawnable from a V2 parent.

2. Check the runtime you are actually on. Start a session and inspect the persisted turn_context.multi_agent_version rather than asking the model what version it thinks it is. The reporter in #36294 made that distinction on purpose, and it is the right instinct: ask the artifact, not the narrator.

3. Grep your agent files. From your project root and your home directory:

grep -rn 'model *= *"gpt-5.6-luna"' ~/.codex/agents .codex/agents 2>/dev/null

Every hit is a worker that will silently resolve somewhere else, including any example you copied out of the docs.

4. Run one spawn probe before you trust a workflow. Ask a parent session to spawn a single throwaway child on your intended model with fork_turns set to "none". Either you get a thread or you get Unknown model. Ten seconds, and it turns an assumption into a fact.

5. Pick your fallback deliberately. Terra is marked v2 and Codex describes it as the option for "speed and efficiency over depth, such as exploration, read-heavy scans, large-file review." That is the honest replacement for Luna-shaped work inside V2 today. Set it explicitly with agents.default_subagent_model so the resolution chain stops guessing.

6. Write down your cost per delegated subtask. Not per token. Run one representative delegation, note the total tokens across parent and children, and keep the number. It is the only figure that survives a model swap you did not choose.

Two community workarounds are circulating: force multi_agent_version to v1, and phrase requests as "delegate new thread" instead of "delegate sub-agent." I have seen both reported and neither confirmed by OpenAI. The v1 route also costs you what makes V2 worth running (the task hierarchy and the granular fork_turns control), so it is the wrong trade for anyone whose children need parent conversation history.

Honest limitations

The framing going around this week is that OpenAI "removed" Luna from delegation on August 16. I do not think the evidence supports that sentence. The chain of issues starts weeks earlier: #35097 was filed on July 24 against codex-cli 0.145.0, and #36294 on July 31 against Codex Desktop 26.727.40816 with bundled CLI 0.146.0-alpha.9.2. What happened in mid-August was amplification, not a changelog entry. Nobody at OpenAI has said this was intentional, and PR #32751's stated purpose is compatibility, not tiering. The cynical reading (expensive framework, cheap tier withheld) is available and I understand why people reach for it. It is inference.

The A/B evidence is one person on one machine, one macOS arm64 setup, three sessions. It is unusually careful work for a bug report and it is still a single data point.

The pricing is third-party. Do not build a budget on my paragraph.

Luna is not gone. It runs as a root session model, including on V2 when the flag is on. This is a child-model restriction with a bad error message, which is a smaller problem than "the cheap tier was taken away" and a more annoying one, because it fails at exactly the moment you are least likely to be watching.

And openai/codex carries over 5,000 open issues against 103,000 stars. A stale open issue in that pile is not proof of neglect. It is proof of volume.

What I would actually watch

The interesting question is not whether OpenAI fixes this one filter. It probably will, and #36294 already hands them three reasonable options.

The question is how many other decisions in your agent harness resolve from a server-side value you cannot see. Model availability, delegation topology, and reasoning-effort defaults all arrive through the same channel, and none of them appear in the file you version-control. We got used to configuration being a contract. In a hosted harness it is closer to a request that usually gets granted.

Run codex debug models on your setup today and look at how much of your delegation strategy depends on a column you have never read. Then tell me what you found, because I suspect Luna is not the only row that matters.


Sources: openai/codex issue #36294, issue #35097, issue #34700, PR #32751, Codex subagents documentation, OrcaRouter Codex playbook (pricing, third-party).