Proposal: Codex-native evidence-driven semantic escalation for dynamic multi-agent graphs
Summary
Codex Multi-Agent V2 is increasingly capable of model-driven graph construction rather than only running a fixed, human-authored pipeline: a model can delegate, recursively split work, consult other agents, request verification, choose different model/reasoning configurations, and reshape its next actions as new information arrives.
I am starting a local proof-of-concept around one missing control-plane behavior:
After execution produces new evidence, let the system decide what level of responsibility and capability should resolve the problem next.
Working term: semantic escalation.
This is not a proposal for a permanent EscalatorAgent, an always-running supervisor, or a mandatory pipeline stage. The decision could be made by the current owner, a transient no-history child, or another bounded model-backed turn.
The goal is to test whether Codex can use its existing graph primitives to build and revise workflows dynamically, while spending frontier intelligence primarily where execution reveals unresolved ambiguity.
---
Source-grounded starting point
I performed a static source audit against upstream commit 50ea8fd411422b3f7bc906bcde6c1c4432019a2e.
The current open-source architecture already contains much of the semantic surface needed for this experiment:
- V2 spawn preserves parent thread, parent turn, root turn, canonical agent path, and inherited execution context, while children can recursively create descendants:
spawn.rs. - Terminal child output is addressed to the direct parent as a contextual completion envelope:
session/mod.rs. - Child construction supports no-history and bounded-history contexts, so recursive ownership does not inherently require cloning the full parent trajectory.
- Spawn configuration can resolve child model and reasoning-effort overrides from the parent turn plus requested/default child configuration:
multi_agents_common.rs. - A shared root-tree
RolloutBudgetand concurrent execution limiter already provide hard resource boundaries:rollout_budget.rs. - Detached review and rich app-server thread/turn/tool/event identities already provide useful verification and evidence surfaces.
I did not find a mandatory Planner → Worker → Reviewer sequence in core. The existing direction appears closer to a set of model-visible graph primitives from which the model chooses an execution shape.
That suggests semantic escalation should first be tested as a small model-driven behavior over existing primitives, not as a new orchestration subsystem.
---
The missing decision
Most routing proposals answer a question before execution:
Which model or agent should receive this task?
But execution often changes the nature of the task.
A narrowly scoped worker may discover that:
- the failure is a trivial local implementation mistake;
- the scope is valid, but the assigned model lacks the required capability;
- the scope was decomposed incorrectly;
- the problem crosses the current owner's boundary;
- an architectural assumption made several levels above is wrong;
- another retry would spend more tokens while preserving the wrong graph;
- the safest action is to stop rather than continue mutating state.
At that point, neither “always retry the worker” nor “always escalate to the strongest model” is generally correct.
The useful question becomes:
Given the task contract, ownership chain, partial trajectory, evidence, prior attempts, and remaining budget, where should this problem be resolved now?
---
Illustrative decision space
A bounded semantic-escalation turn could return a typed decision such as:
RETRY_SAME
CHANGE_MODEL
RETURN_TO_PARENT
ESCALATE_SCOPE
REPLAN_SUBTREE
SPLIT_SCOPE
ABORT
This is illustrative, not a proposed final protocol.
The important distinction is that the decision routes a problem after execution has revealed new information, rather than only routing the original task.
Example:
root owner
|
+-- subsystem owner
|
+-- worker
|
+-- implementation attempt
+-- tests / validator / tool evidence: failure
|
v
semantic escalation
|
+-----------+-------------+
| | |
retry stronger return upward /
locally model reshape subtree
If the failure is local, the same worker retries.
If the scope is sound but capability is insufficient, the same narrow scope can move to a stronger model without expanding context.
If execution invalidates the decomposition, spending more intelligence inside the worker is the wrong action: the problem should move upward and the graph should change.
---
Why this is distinct from nearby roles
- A router usually selects an executor before or at task admission.
- A reviewer/validator decides whether an artifact satisfies a contract.
- A planner/owner decides what work should be done inside its scope.
- A permanent supervisor continuously manages the workflow.
Semantic escalation is narrower:
It interprets execution evidence and decides which level of ownership/capability should make the next decision.
A reviewer might return:
FAIL: the migration breaks backward compatibility.
Semantic escalation then decides whether that failure belongs to:
- the same worker;
- a stronger worker on the same scope;
- the current scope owner;
- a higher architectural owner;
- a replanned subtree;
- or an aborted attempt.
This function may not deserve a permanent runtime identity at all. The current owner or a transient child may already be the correct implementation shape.
---
Runtime records facts; models interpret them
The runtime can reliably know facts such as:
- child/turn/attempt identity;
- terminal status;
- timeout, interruption, or cancellation;
- tool/process failures;
- token or relative-budget usage;
- structured validator results;
- available receipts and evidence references.
The runtime should not pretend to know semantically whether:
- a test failure is a forgotten import;
- the task boundary is wrong;
- the worker misunderstood an architectural constraint;
- the parent decomposition must be revised.
That interpretation belongs in model context.
The runtime should enforce only the consequences and invariants:
- ownership and attempt identity;
- budgets and allowed graph growth;
- capabilities and permissions;
- cancellation;
- durable receipts/evidence delivery;
- recovery and deduplication.
In short:
Runtime records facts. Models interpret them. Runtime enforces the resulting physics.
---
This is not a fixed pipeline proposal
The goal is not:
Planner -> Worker -> Reviewer -> Escalator -> Integrator
The graph should remain model-generated and mutable.
A successful narrow task may simply be:
Owner -> Worker -> ACCEPT
Another task may dynamically create research, verification, consultation, or escalation only when evidence makes those actions useful.
Possible model-visible actions are conceptually closer to:
DO
DELEGATE
SPLIT
CONSULT
VERIFY
ESCALATE
REPLAN
ACCEPT
These are actions, not mandatory stages or permanent agent classes.
The pipeline is therefore an execution artifact. It is not the runtime architecture.
---
Cost/quality hypothesis
The working hypothesis is:
Frontier intelligence should be spent primarily where unresolved ambiguity exists, not mechanically at every level of the tree.
A strong owner can reduce an ambiguous problem into a concrete contract. A cheaper worker can then execute that contract.
If execution discovers new ambiguity, semantic escalation can temporarily purchase stronger reasoning or return the problem to the correct owner. After the ambiguity is resolved, execution can downshift again.
This is not assumed to be correct in every workload. It should be measured against simpler policies.
---
Minimal PoC / dogfood plan
The first experiment should avoid adding a new scheduler or permanent role.
When a worker produces a simulated or real failure receipt:
- Build a bounded evidence packet containing only:
- task/scope contract;
- ownership chain;
- configured model and reasoning effort;
- attempt count;
- relevant test/tool/validator evidence;
- compact diff/artifact summary;
- remaining relative budget.
- Ask either the current owner or a transient no-history escalation turn for one typed decision.
- Execute that decision using existing graph primitives.
- Compare at least three policies:
- always retry locally;
- always escalate to a stronger model;
- evidence-driven semantic escalation.
- Measure:
- total token/credit usage where observable;
- avoided blind retries;
- unnecessary tier-ups;
- recovery success rate;
- correct return-to-parent/replan decisions;
- false escalation and oscillation;
- whether a compact evidence packet is sufficient.
If backend-effective model/cost attestation is unavailable, the experiment should label that limitation rather than infer it from requested configuration.
---
Separate hard-invariant track
Semantic escalation can likely be prototyped with current model-facing primitives, but reliable unattended graphs still require hard runtime contracts.
The most relevant separate gaps appear to be:
- durable owned child attempts and terminal receipts;
- target-set join / exact owner continuation;
- hard depth, fan-out, deadline, and sub-budget admission;
- per-child capability narrowing;
- restart-safe obligation recovery and deduplication.
Reliable completion/wake behavior is already tracked in #15723.
This issue is not proposing to bundle all of those concerns into one feature. They are runtime prerequisites that should remain separate from the semantic decision itself.
---
Relationship to existing proposals
This seems adjacent to, but distinct from:
- #34278 — per-thread Auto routing for model and reasoning effort before a turn;
- #36251 — carrying model/effort recommendations into a ChatGPT → Codex handoff, with possible future escalation;
- #32100 — a concrete staged Orchestrated-mode workflow PoC;
- #32705 — heterogeneous Multi-Agent V2 routing and effective child configuration;
- #15723 — reliable completion delivery and owner wake.
Those focus primarily on initial model allocation, explicit workflow construction, child routing/configuration, or lifecycle delivery.
This proposal focuses specifically on:
Failure/evidence-driven routing of an already-running scope through a dynamic ownership graph, including the possibility that the graph itself must change.
---
Non-goals
This proposal does not require:
- a permanent
Escalatoragent; - an always-running supervisor;
- a mandatory review stage;
- a fixed model hierarchy by tree depth;
- a user-authored pipeline;
- a new scheduler or model runtime;
- all-to-all agent communication;
- another trajectory database/event bus;
- automatic replay after ambiguous side effects.
The useful implementation may turn out to be only:
- a compact evidence handoff;
- a bounded typed decision;
- existing parent/child graph actions;
- and hard runtime enforcement of the selected consequence.
---
Questions for maintainers
- Is evidence-driven graph reshaping aligned with the intended direction of Multi-Agent V2, or is similar behavior already owned by model/backend orchestration that is not visible in this repository?
- Is the current owner expected to make this class of decision, or would a transient no-history child/tool-backed turn be a better fit?
- Which existing app-server/core surface is the intended seam for a compact failure/evidence packet?
- Are there planned typed attempt/receipt semantics that would make this experiment overlap with upcoming work?
- Are there model-facing graph actions or backend constraints that a local PoC should avoid depending on?
---
Status
I am starting a local PoC/dogfood experiment against current Multi-Agent V2 and will add concrete results here rather than treating the architecture as proven in advance.
The purpose of opening this issue now is to:
- make the hypothesis inspectable;
- avoid building a large subsystem before validating the behavior;
- identify overlap with intended Codex architecture early;
- and keep the implementation Codex-native if the experiment is promising.
6 Comments
Follow-up architecture clarification from current dogfood: I think the proposal above describes only the post-evidence half of the control problem.
A more fundamental question appears before semantic escalation:
Four things that should stay orthogonal
I have found it useful to separate four concepts that are easy to accidentally collapse into one:
None should imply another.
A strong model is not automatically the parent architect. A child is not automatically a worker. The first user-visible thread does not need to remain the permanent architectural reasoning context. And a model concluding that stronger reasoning or a wider graph would help should not itself grant permission to spend more or expand fan-out.
There is some upstream evidence that these boundaries are already useful in narrower contexts:
Those PRs do not prove the broader architecture below, but they make the decomposition less hypothetical.
What is the "parent" actually?
This changes how I think about the parent in a native harness.
The stable thing should probably be the user-facing root authority, not a permanently long-lived parent-architect thread.
Under that root, the harness may create a transient control/coordinator role for one phase, create workers/reviewers beneath it, materialize compact durable state/evidence when the phase ends, and later create a different control context for the next phase. A single visible user chat could therefore hide an internal tree of separate agent/thread contexts without requiring the user to manually manage that tree.
Current local dogfood has been useful here. The same logical
operational-coordinatorrole has worked in two different physical shapes depending on lifecycle needs:That is only local behavioral evidence, not an upstream guarantee, but it suggests an important invariant:
The role is logical. The topology is an execution artifact chosen for the current lifecycle/context needs.
There is a bootstrap problem before semantic escalation
The original issue asks what should happen after execution evidence changes the problem. Before that there is a separate orchestration admission / meta-routing problem:
The bootstrap question is not just "which model should run?" It is:
That decision should not be inferred solely from the model currently selected in the UI.
Semantic need and economic authority are different decisions
There is then a second, independent admission problem around economics:
A model can say "stronger reasoning is useful here" without thereby gaining authority to spend more.
Likewise, spawning several cheap subagents can be economically significant even if no expensive model tier is used. So delegation policy and compute-escalation policy should be separate controls.
Possible user-facing product surface
I would not expose the whole control plane to every user. The default UX can stay simple while the underlying semantics remain explicit.
For ordinary users, a reasonable experience may be progressive disclosure:
For power users, an advanced control surface could expose independent policies such as:
Delegation policy
Single— never spawn subagents;Ask— ask before meaningful fan-out;Adaptive— allow the harness to create/reshape the graph within configured limits.Compute policy
Strict— never exceed the selected model/compute ceiling;Ask— ask before a meaningful tier-up or additional compute purchase;Budgeted Adaptive— allow automatic escalation only inside an explicit task/session budget and ceiling;Full Adaptive— after explicit consent, allow the system to choose stronger model/reasoning tiers and additional fan-out when semantically justified.Full Adaptiveshould have consent semantics analogous in spirit to Full Access: the user is not merely choosing a model, but granting the system discretion to spend additional compute.Strictshould be the opposite hard guarantee: the configured ceiling is never crossed.These controls should compose independently. For example:
could allow several agents while forbidding any model-tier escalation, whereas:
could allow a single context to temporarily use stronger reasoning without creating a graph.
For advanced inspection/debugging, a graph view could expose the facts that matter without making topology itself the programming model:
That would make adaptive behavior auditable without requiring users to manually operate every internal thread. A compact execution receipt at the end could similarly summarize which agents/models were actually used, which escalations occurred, and whether extra compute/fan-out was authorized by policy.
Updated conceptual control loop
Putting the pieces together, the native shape I am now testing conceptually is closer to:
The important part is that the model may request graph/model changes, while the runtime owns the hard consequence.
What this changes about #40037
I now see #40037 as one important component of a broader control loop:
These should not be collapsed into one model selector or one permanent supervisor.
This is still a research hypothesis, not a request to add another scheduler, fixed pipeline, or large policy subsystem. The current PoC/dogfood should keep the distinctions explicit and test the smallest Codex-native seams first.
The concrete questions I would now add for maintainers are:
For the PoC/dogfood I plan to keep these distinctions explicit rather than assuming that the currently selected model, current thread, graph parenthood, role, and spend authority are the same thing.
Purpose and boundary
This is a public attachment for cross-Issue analysis of agent-boundary patterns observed in a purpose-selected 100-Issue
openai/codexcorpus.Reviewed analysis
OpenAI/Codex public-Issue agent-boundary pattern classification (100-Issue corpus)
Purpose
This material shares recurring agent-boundary patterns observed across a purpose-selected set of 100 public
openai/codexIssues. It is not an assignment of responsibility to any individual Issue or reporter, and it is not a claim about OpenAI-internal causes. It is provided as improvement-oriented analysis.Method
INFERRED_FROM_METADATA.Reproduced counts
Tags are non-exclusive; shares do not sum to 100%.
| Tag | Name | Count | Share |
|---|---|---:|---:|
| A | Authority | 87 | 87% |
| B | Interface | 78 | 78% |
| C | Provenance | 52 | 52% |
| D | Role Boundary | 31 | 31% |
| E | Lifecycle | 41 | 41% |
| F | Human Load | 17 | 17% |
Most frequent pair co-occurrences
| Pair | Count | Descriptive reading |
|---|---:|---|
| A+B | 77 | authority expectations meet a concrete tool, sandbox, filesystem, connector, hook, or UI enforcement surface |
| A+C | 44 | authority depends on inspectable identity, configuration, evidence, or attribution |
| A+E | 38 | authority changes or decays across a session, turn, retry, resume, handoff, or other state transition |
| B+C | 37 | interface behavior is difficult to verify without provenance or correlated evidence |
| B+E | 31 | interface/runtime state changes across lifecycle transitions |
Supervisor review
Result:
PASS_WITH_LIMITATIONS.Required limitations
openai/codexIssue; the counts are not product-wide prevalence estimates.Artifact SHA-256
9b265d8e78b99b05f6bda8c6d1f5ab8087d6b4777d5c95158d3d888302171e0175997d2c83dc3fdd5b3054be84a03e25bb19962a9e165a2d1cfc3baee83fcf8c0cf2837073b6c3b6fd40759cc7dfd3ab2647a0834d816788b39147d01d7ab2026259b48c7ac26677cb98cb716d51299838501aa32a313e9d5666a683002a19a4<details>
<summary>100-row public classification CSV (Issue links, A–F flags, tag sets, rationales, review status)</summary>
</details>
<details>
<summary>Public manifest</summary>
</details>
Related observation: DOCX/PDF artifact pipeline failure pattern.
Observed:
Specific case:
Status:
Related observation: GitHub write/reachability variance across chat execution contexts.
Observed:
Status:
Reproducibility point:
Removed.
From Waiting to Ownership: Building a Multi-Agent Control Loop Inside Codex
A practical report on exact owner continuations, rejected GREENs, dynamic graphs, and the product surface they suggest.
This work grew out of openai/codex#40037, a proposal around evidence-driven semantic escalation in dynamic multi-agent graphs. What follows is the implementation and dogfood story behind the narrower runtime seam we ended up testing.
---
One chat should be enough
The product shape we wanted was simple to describe.
A user should be able to stay in one conversation — the place where intent, architecture, risk, priorities, approvals, and corrections live — while the system expands whatever execution topology the work requires below it. Sometimes that should be one direct child. Sometimes a transient coordinator with several workers. Sometimes several independent approaches and a reviewer. Sometimes no graph at all.
The user should not have to become a thread janitor.
They should not need to remember which child belongs to which coordinator, manually forward completed results, keep an architectural turn open for hours, or infer from a spinner whether a model is still thinking. They should be able to change their mind in the owner-facing chat and eventually receive a branch-level result rather than a stream of leaf-level noise.
Codex already had many of the visible ingredients: subagents, task messaging, waiting, different models and reasoning efforts, parallel work, and a runtime capable of managing multiple threads. The hard part was not inventing a graph. The hard part was making those ingredients compose into something we could operate repeatedly under long-running workloads.
The questions that kept returning were more basic than any preferred agent framework:
Completedactually prove?The project that grew around those questions became CodexForge. It was not intended to become a second Codex. It became a pressure rig: operate the native product hard, isolate the smallest missing piece of runtime physics, test it locally, and remove or avoid overlap whenever upstream becomes sufficient.
And this did not remain a diagram.
By our ninth and tenth local runtime iterations — V9 and V10 — we had a modified Codex that could run the bounded live-process composition we wanted:
The detached child completed later and woke neither layer. The graph itself was still model-generated native orchestration rather than a hard-coded universal pipeline. Skills and operating instructions shaped roles and cooperative behavior, but they did not become hard identity or permission authority. Codex created and executed the graph. The runtime patch supplied the exact continuation behavior at finalized ownership boundaries.
That distinction — between a model-generated graph and the runtime physics that make it operable — became the center of the work.
---
Our first explanation was wrong
We did not begin with the right problem statement.
Our early explanation was roughly: Codex cannot cheaply wait for delegated work, so a new join or continuation mechanism is required for ordinary coordination.
That sounded plausible from the product surface. Parents sometimes failed to wait cleanly, timed out, polled, duplicated work, killed slow children, or simply finalized while children were still running. In the UI, a long-running turn also looked like an occupied conversational surface. It was easy to collapse all of this into one story: waiting itself was missing or wasteful.
Then we checked the source and ran a neutral control.
Native
wait_agentalready suspended asynchronously. While the runtime was waiting on the subscribed event, the parent model was not continuously performing inference merely because the turn remained open. The capability predated CodexForge. Later model calls could still happen when a wait returned or timed out, and bad policy could still create short waits, repeated wakeups, polling, duplication, or premature intervention. But the statement “Codex cannot sleep cheaply” was false.So we removed it.
That correction changed the problem from:
into:
The residual seam was narrower:
A same-turn wait and a post-finalization continuation are not two implementations of the same lifecycle. They are different lifecycle choices.
The result was not that waiting is wrong. It was that a reliable system needs both waiting and finalization, and must know which owner receives the next turn.
---
Waiting and finalization are both useful
A direct parent/child task may be best expressed as one active parent turn:
No coordinator is required. No fresh owner continuation is required. Native waiting is the simplest correct mechanism.
But an owner-facing architect chat has a different job. It is where the user discusses architecture, changes intent, grants or refuses spend, and interprets the final evidence. Keeping that chat inside a long-running execution turn solely because work exists below it can be a poor lifecycle and context choice even when the wait interval itself is cheap.
For that surface, finalization can be cleaner:
The benefits are not a claim of continuous token savings. They are lifecycle and product benefits. The owner cockpit stays available for new input. Leaf traces and mechanical waits remain below the architectural conversation. Nearest-owner routing prevents leaf completions from waking higher layers prematurely. The root receives branch-level synthesis rather than raw worker noise.
A coordinator can also choose either lifecycle. It may wait inside one turn, finalize and later continue, or combine both across phases. The right choice depends on task shape, latency, context cost, steering needs, and owner policy.
V9/V10 is therefore not “a better wait tool.” It is the complementary runtime path for a finalized ownership boundary.
---
What we actually built
The implementation history matters only where it explains the claims we accept and refuse. The V labels below are local experiment iterations, not official Codex releases.
Local iteration V8: make the first boundary truthful
V8 established a bounded foundation around admission and result routing. Child work was made visible before startup, startup failure had truthful compensation, and successful completion routing was narrowed so lifecycle did not silently masquerade as proof of useful work or external effect.
That foundation was useful precisely because its ceiling was explicit. V8 did not prove durable Terminal persistence, an exact recoverable Bound, receiver consumption acknowledgement, restart replay, recovered authority, or external-effect success.
Local iteration V9: exact live-process owned continuation
V9 focused on the post-finalization seam.
The parent can register an exact set of direct child dependencies through
join_agents(...), finish its current turn, and later receive one fresh continuation when the registered condition becomes ready. This is intentionally narrower than a scheduler, durable inbox, or generic workflow engine.The key mechanics were:
Exact target registration. The obligation is tied to an exact set of direct owned children, not “any child completion” and not a global agent event stream.
Arm-before-recheck. A naive implementation can check a child, see that it is not ready, then subscribe after the child has already completed. The accepted design arms the obligation before rechecking readiness so completion cannot disappear into that race window.
Immediate-parent routing. A grandchild does not wake the root merely because the root can address or observe it. Nested execution composes one ownership edge at a time:
Exact-set readiness. For an
alljoin, one child finishing does not wake the parent early. The exact target set must satisfy the readiness condition.Exactly-one live-process handoff. Duplicate terminal observations, repeated readiness checks, and competing lifecycle paths must not create duplicate parent continuations. This is an exactly-one property inside the accepted live process — not a claim about exactly-once execution after crash or restart.
User-turn priority. Owned continuation does not trample active user input. If the parent already has an active or reserved user turn, the continuation defers.
Cancellation and cleanup guards. Failed or abandoned lifecycle paths must not leave a stale obligation that wakes a parent later for the wrong reason.
Detached exclusion. Detached or unrelated work can complete successfully without satisfying somebody else’s owned join.
No heartbeat poller. The intended path is event-driven:
Native
wait_agentremains the same-turn primitive. Owned continuation exists for the finalized-owner lifecycle.The V9 dogfood
The V9 dogfood deliberately included a neutral control and a hierarchical case.
The neutral control was native same-turn waiting: one child, one non-empty terminal result, one native wait, one original root turn. The deterministic replay/check matrix passed 13/13. We recorded that as upstream behavior, not a V9 advantage.
The primary case was hierarchical:
Both exact owned leaves completed before exactly one fresh coordinator synthesis. The coordinator completion then produced exactly one fresh root continuation. The detached child completed later and woke neither coordinator nor root. The ownership, fan-in, immediate-parent, exclusion, and dedupe matrix passed 24/24.
The accepted V9 artifact was independently reviewed. One fixture family remained unsupported because the cohort lacked a required host binary, and active steering injection was not exercised. We recorded both as unsupported rather than green.
Local iteration V10: transplant the semantics, not the history
V10 moved the accepted semantics onto a newer selected upstream commit rather than continuing to carry an aging patch stack forward. Independent exact-final-byte review returned
CLEAR_FINAL.Focused verification passed:
| Check | Result |
|---|---:|
| cancellation shield | 1/1 |
| race regressions | 2/2 |
|
join_agents| 7/7 ||
owned_join| 15/15 || native wait non-regression | 1/1 |
| native MSVC release build | exit 0 |
| neutral exact-artifact wait smoke | 13/13 |
| hierarchical owned fan-in / immediate-parent / detached exclusion | 26/26 |
The immutable Windows CLI was 311,539,712 bytes with SHA-256:
Then we ran that exact artifact through our normal OpenAI.Codex Desktop surface and confirmed that the selected live CLI matched the accepted artifact identity.
That establishes a bounded but real fact: the architect -> coordinator -> model-generated agent graph -> exact owner-continuation composition was not only a test fixture. It ran in the owner-facing product composition.
The ceiling remained strict: live-process-only. No upstream acceptance is implied.
---
Why GREEN was not enough
The most useful implementation history may be the versions we refused.
One early line of work made sender-side state durable and looked close to restart-safe continuation. Review forced a more important distinction: sender persistence is not receiver consumption. If the receiver has not durably consumed and acknowledged the work, suppressing retry can still lose a wake. A persisted obligation is not a receiver ACK, and neither is replay.
Several later candidates had complete-looking focused test suites and still failed semantic or concurrency review. The clearest late V9 counterexample was concrete.
A user submission reserved a task-less
ActiveTurn. A child completion correctly deferred its owned claim because user input had priority. Turn-context and settings preparation then failed.clear_reserved_idle_turnremoved the reservation — but did not invoke the already-ready owned-join handoff. No other terminal hook remained to revive that obligation. The result was a ready lease that could remain ready forever without a parent continuation.The correction was narrow: after a successful reservation clear, release the active-turn lock and run the existing owned-join handoff exactly once while preserving the original error, user priority, atomic multi-target behavior, nearest-parent routing, and dedupe.
V10 repeated the same lesson at a different boundary. Compilation and focused evidence were not enough to freeze the artifact; review found cancellation races involving lease rollback, competing terminal evidence, and post-commit delivery ordering. Deterministic regressions and exact-byte re-review came before the final build.
There was even an evidence-layer version of the same mistake. A driver could exit zero and the live stream could reach terminal state while the live summary remained
INCOMPLETE / WARNINGbecause observer finalization raced summary materialization. The saved trace replay later passed 13/13 and 26/26. We treated those as different facts instead of choosing the prettier one.The pattern became familiar:
This is not an argument against tests. It is an argument that a green test suite proves the schedules it covers. Ownership, cancellation, replacement, and recovery claims can still fail in a schedule nobody encoded yet.
---
The architecture that survived correction
The code changed repeatedly. A few distinctions survived because they explained failures across otherwise unrelated surfaces.
Model is not role
A model is the intelligence used for a step. A role is the function being performed: architect, coordinator, worker, reviewer, explorer. Changing the model does not automatically change the role.
Role is not thread or context
A role can be performed in different threads and contexts. A stronger reasoning step may not need a new child if the same logical context can switch model or reasoning effort natively. A separate child remains useful when the reason is parallelism, context isolation, independent judgment, no-history reasoning, or a distinct lifecycle.
Thread is not authority
Being inside a thread does not prove what the current action may do. Authority can belong to the exact issuing step, the action lifetime, the execution environment, an attached resource, the destination, current managed policy, or current user approval state. Historical configuration and UI labels are not timeless grants.
Semantic need is not spend authority
A model may correctly conclude that it needs stronger reasoning, more branches, or a gated capability. That semantic request does not authorize the cost. Runtime admission must validate it against entitlement, thread policy, current permissions, managed policy, destination constraints, and user-owned spend authority.
Requested state is not effective state
A requested model, provider, tier, topology, permission profile, or capability is not proof of what actually ran. Where the distinction matters, the system needs effective-state evidence and a compact receipt.
Provenance is not authority
Knowing why a turn or tool call exists — queue dispatch, retry recovery, a specific originating item — is useful evidence. It does not authorize the action or prove the result was correct.
Together:
These distinctions are not a preferred framework diagram. They are the minimum needed to keep a dynamic graph from confusing intelligence, ownership, capability, and payment.
A concise control principle emerged from that separation:
The model can decide that the current evidence warrants a new branch, a stronger reasoning step, an independent reviewer, a replan, or an abort. The runtime decides whether that request is admissible and guarantees the lifecycle, ownership, and authority consequences.
Topology is therefore an execution artifact, not a fixed architecture. A simple task can stay single-agent. A task with one obvious parallel branch can have one child. A bounded execution phase can have one transient coordinator. Multiple coordinators make sense only when their scopes are genuinely disjoint. There is no requirement that every task look like
Planner -> Worker -> Reviewer.---
Three different truths
Agent systems often collapse “done” into one bit. Our dogfood and public issue corpus kept showing at least three different truths.
Lifecycle truth: did the turn, tool call, or child reach a real terminal lifecycle state?
Useful-work truth: did it produce the work the task required?
External-effect truth: did the intended change actually happen in the outside world?
These are not interchangeable.
A visible final answer is not necessarily terminal lifecycle. A stale projection can show an in-progress state after durable completion. A lifecycle
Completedcan exist without meaningful model work. An exit code, tool output, or model claim is not proof that the expected file, Git state, process, remote action, or side effect exists.Therefore:
This distinction also applies to the evidence system itself. The live summary that says
INCOMPLETEand the saved replay that later passes every deterministic check can both be true. One is observer/projection truth; the other is replay evidence. Treating one as the universal truth would hide the race we actually need to understand.The practical consequence is straightforward: lifecycle belongs to runtime state; useful work is a semantic acceptance question; external effects require deterministic readback where they matter.
---
Upstream was often eating our backlog, not our code
During the experiment, upstream Codex added or expanded several adjacent native primitives: permission-aware admission, live turn settings, step-scoped model and effort attribution, execution-context ownership, originating-item correlation, action-lifetime approval policy, resource-scoped authority, worktree ownership metadata, generation fencing, native telemetry, typed output fidelity, and stronger paginated-history surfaces.
It would be inaccurate to say this deleted a large future CodexForge stack. We had not built most of that stack.
The useful classification is narrower:
In other words, upstream was often eating our backlog rather than our code.
That is a good outcome. The point of the pressure rig is not to preserve custom machinery as an identity. It is to make the road toward a sufficient stock Codex clearer.
We use a simple operability ladder before deleting local behavior that real work still depends on:
Source presence is useful evidence. It is not yet consumer sufficiency.
The same discipline prevents the opposite error: writing a second permission controller, telemetry plane, correlation layer, or model router for a problem that current native Codex already owns well enough.
---
Public issues are evidence, not a scoreboard
Independent public failures are useful stress cases, but they are not the requirements source and they are not a kill count.
We use an evidence ladder:
Each rung has a different claim ceiling.
FIXED_BY_CANDIDATEis intentionally expensive. It requires a comparable bounded baseline failure and candidate non-reproduction with the relevant negative or exclusion controls preserved. Architectural similarity is not enough.A fresh report, issue #40932, is almost a field illustration of the lifecycle seam we had been studying. In Codex CLI 0.149.1, the main turn observed three required subagents still running, sent them follow-up instructions, did not call
wait_agent, emittedfinal_answer, and completed two seconds later. The subagents continued working. Their results did not reactivate the completed parent turn; they surfaced only after the user sent another prompt roughly half an hour later. The report records no crash or abort in that interval. At the time of writing, an automated duplicate check suggested #40299, but there was no maintainer verdict.That report is source-relevant, not fix evidence. It may primarily be an orchestration-policy failure: the model should perhaps have waited instead of finalizing. It does not prove that stock Codex could not support another valid path, and we have not run the reporter scenario against our local artifact.
But it cleanly exposes the lifecycle choice:
The third path is what our V9/V10 experiments implemented locally. That does not make #40932 “fixed by V10.” It makes the report a particularly clear external example of why a post-finalization owner-continuation primitive is useful at all.
Issue #15723 plays a different role: it shows why relevance is still not enough for a fix claim.
Its subagent branch crosses the same bounded failure boundary changed by V10: a parent can finish, the child can later finish, and the parent may not autonomously continue. Our local path addresses that lifecycle shape, but the broader issue also includes background-process behavior that may be orthogonal.
To make a strict fix claim, we wanted a same-HEAD baseline and candidate. We built a clean Windows baseline from the exact same upstream commit and tree without the V10 diff.
Then the comparison hit a different boundary. The existing exact-artifact driver relied on ambient live authentication in a way we did not want to turn into credential-copying test infrastructure. Building a credential-safe execution seam would have been real additional engineering, mainly to move one public label from “plausibly addressed” to “fixed.”
We stopped.
The standard did not change. The label did.
The bounded subagent branch remains plausibly addressed / unverified. The reporter-style A/B is unexecuted. The #32203 requester-versus-owner case remains an unexecuted nearest-parent negative control rather than something we bend the routing rules to make green.
That stopping boundary is useful evidence too. A good evidence system should allow
UNKNOWNandUNEXECUTEDto be final results rather than force every interesting case into a binary trophy.One practical detail did slightly puncture our ambition: full Windows builds repeatedly took long enough for
mainto move again while the binary was still being produced. Chasing every intermediate commit was not going to converge, so causal comparisons stayed on frozen same-base cohorts and upstream was integrated when the semantic overlap actually mattered.The linker was not impressed by our sense of urgency.
---
Evidence has an economics
Evidence discipline does not mean proving every claim at unlimited cost.
There is a difference between evidence required to decide whether code is safe to ship and evidence required only to make a sentence sound stronger. Concurrency, recovery, authority, replay, and exact runtime bytes can justify expensive work. A public issue label often cannot.
Heavy evidence work should be able to change something material: shipped bytes, architecture, deletion or retention, safety or authority, owner spend, or a genuinely release-blocking public claim. Improving confidence or wording alone is not enough.
That is why the clean same-HEAD baseline was still worth building: it established the object needed for causal comparison. Building a new credential-safe driver solely to upgrade a public label was not obviously worth the additional infrastructure work.
The evidence ceiling is part of the result.
A causal experiment uses a frozen cohort. Upstream can be watched read-only while it runs. If a new commit does not materially change the same semantic invariant, the causal result does not expire. If it does, integrate once after the slice rather than rebasing the experiment mid-flight.
The aim is not to make every intermediate binary maximally fresh. It is to keep the research valid and the assimilation loop fast.
---
Product direction: one cockpit, hidden graphs, adaptive intelligence
Everything above is practical evidence. What follows is a product hypothesis derived from operating the system, not a claim that current Codex or current OpenAI plans already work this way.
One visible cockpit
The bounded V10 composition already demonstrated the owner/root -> coordinator -> agent-graph -> owner-continuation shape locally. The product hypothesis is that this should remain one owner-facing conversation, with graph status, branches, receipts, and spend disclosed only when useful. What remains hypothetical is the stock-native, restart-safe, policy-driven version of that surface.
Orchestration appetite, not graph drawing
The normal user-facing control should influence how readily the model seeks useful delegation while leaving the concrete topology adaptive.
One possible execution-style surface is:
The names are placeholders. The separation is the important part.
The user controls the appetite and the ceilings. The model synthesizes the topology. Runtime enforces the physics.
Hard ceilings can include budget, maximum concurrency, maximum fan-out, maximum depth, model tier, and capability families. A ceiling is permission to use capacity, not an instruction to consume it.
Hard semantic requirements are different from hard topology. “Give me five independent solutions,” “run two independent reviews,” or “explore competing hypotheses” constrains the evidence the user wants. The model can still decide how that requirement maps onto threads, children, depth, and fan-in.
Direct topology forcing belongs to advanced research and stress instrumentation, where topology itself is the independent variable. It should not be the normal product control model.
We do not yet know the natural graph shape
In many of our ordinary runs, coordinators visibly used only two or three subagents at once. We initially treated that as weak anecdotal evidence about the graph shapes models naturally prefer. Source inspection later exposed a confounder: Multi-Agent V2 defaults to four concurrent slots per session including the current agent, so a root operating at defaults has at most three simultaneous subagent slots. Effective capacity can be lower when resident threads are not yet unloadable.
For a while, we were measuring the walls of the box along with the model inside it.
That means the visible two-or-three-child pattern cannot be treated as evidence of a natural model branching preference. We do not currently have clean distributional evidence for natural fan-out or depth.
We still need to measure natural fan-out and depth by task and model, whether orchestration appetite actually changes topology, whether wider or deeper execution improves quality after fan-in cost, duplicate work, context and coordination overhead, and attested spend. We also need to know how often semantic diversity requirements improve outcomes without prescribing topology.
A product control has to earn its UI. If a “more exploratory” setting does not materially change useful behavior, it should not exist as decorative theater. If forced topology is useful only for research and stress testing, it should stay there.
The runtime should be able to survive the topology. The product should still earn the right to recommend it.
The selected model is default intelligence, not the whole factory
A model selector should not have to encode the entire execution policy of a task.
A cleaner interpretation is:
After execution evidence arrives, the system may decide that the next step needs stronger reasoning, cheaper routine inference, a parallel branch, an independent reviewer, a fresh context, a replan, or an abort.
If the only need is stronger reasoning in the same logical context, native per-turn or per-step switching is cleaner than creating a new child solely to obtain a stronger brain. If the reason is parallelism, context isolation, independent judgment, or a separate lifecycle, a child remains the right primitive.
This is the semantic-escalation idea behind the control loop:
This is the product consequence of the earlier invariant
semantic need != spend authority: models may request more compute or delegation when evidence justifies it, while runtime admission separately enforces budget, concurrency, and authority.Compute policy and delegation policy should therefore be independent. A user might allow adaptive delegation but keep compute strict, or allow temporary model escalation while keeping the task single-agent.
Where the system does adapt, a compact execution receipt should make the effective result legible: which model and effort actually ran where it matters, what topology was used, which authority and environment applied, and what spend was actually attributed where the platform can attest it.
Requested configuration is not enough.
---
Why this could be attractive for OpenAI
This section is deliberately a product and economics hypothesis, not a revenue claim.
Multi-agent value without topology expertise
Dynamic graphs become useful to ordinary users without requiring them to learn thread routing, ownership, fan-in, or recovery semantics. The graph becomes implementation detail with progressive disclosure, not the product’s primary mental model.
Coherent plan differentiation
The same policy concepts can exist across plans while the admissible envelope changes. Lower-cost plans can have tighter automatic compute and concurrency ceilings. Higher-cost plans can expose larger budgets, broader adaptive execution, and more frontier inference.
That makes an upgrade legible as a larger autonomy, intelligence, and parallelism envelope rather than only a different model name.
A natural upgrade moment
A system that can explain why additional compute would help can make the upgrade decision concrete:
That is more meaningful than a generic quota warning because the extra compute is attached to a task-level benefit.
Better allocation of frontier compute
Expensive inference does not have to sit on every routine step. Frontier reasoning can be concentrated on ambiguity, architecture, critical review, and synthesis, while cheaper models and efforts handle routine execution.
That could improve quality per unit of compute and product economics, but it must be measured rather than assumed.
Spend trust
Adaptive systems are easier to authorize when users can see the budget, the escalation policy, and what actually happened. Effective model, tier, provider, billing identity, and a compact execution receipt reduce the “what just spent my quota?” problem.
Trust in spend is itself a product feature when the product can autonomously consume meaningful compute.
Enterprise governance
Managed policy, resource- and environment-bound authority, re-attestation, and auditable receipts can make adaptive execution governable rather than opaque. A model can be semantically ambitious without being operationally unconstrained.
A better learning loop
Native telemetry can help OpenAI learn when delegation, escalation, different graph shapes, or stronger reasoning actually improve outcomes. Aggregate telemetry is not the same thing as exact per-step spend or effect proof, but it is enough to make topology and escalation policies measurable instead of aesthetic.
The product value then shifts from “access to model X” toward “this much bounded, auditable autonomous work.”
A possible composition is:
That is a product hypothesis. Current plan packaging does not prove it, and no revenue uplift is claimed.
---
What remains
The accepted V10 mechanism is intentionally narrow.
It does not provide restart-safe owned continuation. It does not establish durable Terminal -> exact recoverable Bound -> receiver ACK -> replay or dedupe. It does not prove no-loss or no-duplicate continuation across process death. It does not revive permissions after recovery. It does not prove external effects. It does not attest every effective model, provider, tier, or billing decision. It does not prove large graphs are better. It does not fix public issues by semantic resemblance.
Those gaps are useful because they define the residual kernel instead of letting “multi-agent orchestration” become an unlimited bucket.
The remaining areas worth investigating, if native Codex still leaves them open, are:
Where we go next
The next work is intentionally narrow.
First, make owner continuation survive process restart. The next real boundary is a minimal durable Terminal -> exact Bound -> receiver ACK -> replay/dedupe path, reusing native primitives first and refusing any design that expands into a generic scheduler or inbox.
Second, re-attest authority and environment at recovery. Restoring the correct owner, thread, and turn is not enough to prove that permissions, workspace, environment, provider state, or the external world are still what they were before the process died. Before continuing or retrying, the runtime should re-resolve current authority and deterministically reconcile external effects where that matters.
Third, once recovery physics is honest, measure before widening: dogfood orchestration appetite, natural fan-out and depth, adaptive compute, quality, latency, coordination overhead, and attested spend — while continuing to ask which local layers upstream now makes deletable or unnecessary.
A credential-safe strict public-issue A/B driver remains optional. We would build it only if its outcome could change an architectural, runtime, safety, deletion, spend, or release decision — not merely to upgrade a public issue label.
These are not promises to build a large second runtime.
There are also things we would now refuse to build without very different evidence: a second generic scheduler, a durable inbox by default, heartbeat-as-correctness, a poller, unconditional wake plus empty retry, duplicate native telemetry, correlation, or authority layers, authority inference from labels or configuration, restart guarantees over process-local queues, or a rebuild whose only rationale is that
mainmoved.---
The smallest remaining machine
We started by trying to add control machinery around Codex.
The useful part of the experiment was learning which machinery was unnecessary.
One original explanation was false: native suspended waiting already existed. Several green-looking candidates were not semantically safe. Several public reports could not honestly be called fixed. Several future local layers became less necessary as native substrate grew. The working multi-level graph did not prove that large graphs are generally good. The current patch still does not survive a restart in the sense we ultimately care about.
What survived was narrower:
The interesting end state is not the largest harness we can build.
It is the smallest amount of external physics still required for stock Codex to be convenient and trustworthy under sustained use.