[Follow-up] Multi-Agent V2 needs verifiable full-profile application and lifecycle continuity for custom agents
What version of the Codex App are you using (From “About Codex” dialog)?
26.707.72221
What subscription do you have?
ChatGPT Pro
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
Summary
This is a follow-up to #32782, not a duplicate of its initial role-selection request.
PR #32749 restores explicit model and reasoning_effort fields for Multi-Agent V2 spawns. Issue #32782 requests restoration of agent_type, or an equivalent configured-profile selector, so a parent can select a registered [agents.<role>] profile.
Those changes address two important launch-time problems:
- selecting a child model and reasoning effort;
- selecting a named custom-agent profile.
However, production multi-agent skills also need an end-to-end contract guaranteeing that the selected profile remains fully applied, observable, and stable for the complete child lifecycle.
A successful agent_type call is not sufficient if only the role label is retained while other profile layers are dropped, inherited from the parent, or changed during follow-up turns.
Production use case
I maintain a workflow skill in Codex Desktop with 10 registered Writer profiles:
- 5 profiles use
model_reasoning_effort = "max"; - 5 profiles use
model_reasoning_effort = "xhigh".
The profiles represent independent roles.
Each profile may carry:
- role-specific developer instructions;
- a configured model;
- configured reasoning effort;
- sandbox configuration;
- role-specific tool permissions or allowlists;
- a stable role identity used by the orchestration workflow.
The workflow depends on the selected profile being applied as one complete configuration unit. Manually passing only model and reasoning_effort cannot replace the profile because the role instructions and permissions are also material.
What #32749 solves
PR #32749 restores model-routing inputs to the Multi-Agent V2 spawn_agent schema:
model
reasoning_effort
This allows a generic child to be launched with an explicit model and reasoning level when using a compatible non-full-history fork.
However, it does not by itself select a registered [agents.<role>] profile.
What #32782 would solve
Issue #32782 requests:
agent_type
or an equivalent named-profile selector.
That would solve the initial selection boundary by allowing the parent to request a registered custom role instead of using task_name as a non-functional role label.
This is necessary and should be implemented.
Remaining contract needed after #32782
After a named profile is selected, Codex should guarantee all of the following.
1. Atomic full-profile application
The effective child configuration should apply the complete selected profile, including:
- developer instructions;
- model;
- reasoning effort;
- sandbox configuration;
- tool permissions and allowlists supported by the profile;
- profile/role identity.
The runtime must not apply only agent_role while silently inheriting the remaining settings from the parent.
2. Explicit precedence rules
Precedence should be deterministic and documented:
- values explicitly pinned by the selected role should win;
- when the role leaves a value unset, a valid spawn-time override should survive;
- otherwise, inheritance from the parent may apply.
Model and reasoning effort should be resolved independently. This is related to #32831.
3. Verifiable spawn receipt and metadata
The parent and user should be able to verify the effective configuration from runtime metadata rather than relying on the child’s self-report.
At minimum, the child record should expose:
agent_role
effective_model
effective_reasoning_effort
effective_sandbox
profile source or scope
parent_thread_id
multi_agent_version
If tool permissions cannot be displayed in full, the metadata should at least indicate that the selected role’s tool policy was applied.
4. No silent fallback
If the requested role is missing, invalid, unavailable, or incompatible with the selected fork mode, spawn_agent should return an explicit error.
It must not silently spawn a generic child with:
agent_role = null
or silently inherit the parent model while preserving a misleading role-like task name.
5. Follow-up continuity
followup_task or any equivalent continuation mechanism must preserve the child’s resolved role, model, reasoning effort, sandbox, developer instructions, and permissions.
A child initially created with one profile must not silently switch to the parent configuration during a later turn.
6. Deterministic lifecycle finalisation
Multi-Agent V2 should provide a documented and auditable way to finalise a completed or failed child.
V1 workflows previously exposed lifecycle operations such as close_agent. If V2 intentionally uses a different lifecycle model, it should provide an equivalent contract that guarantees:
- terminal completion status;
- deterministic resource/slot reclamation;
- abnormal-child reporting;
- no continued turns after finalisation;
- an observable final state for orchestration logs.
interrupt_agent alone is not an obvious equivalent because interruption and final lifecycle closure have different meanings.
7. Desktop and CLI parity
The same profile-selection and lifecycle contract should work through:
- Codex CLI;
- Codex Desktop/app-server;
- fresh sessions using the same supported configuration.
A profile should not work in CLI but silently degrade in Desktop.
Minimal custom-role example
# config.toml
[agents.english_reader]
description = "English reviewer"
config_file = "agents/english-reader.toml"
# agents/english-reader.toml
name = "english_reader"
model = "gpt-5.6-sol"
model_reasoning_effort = "max"
sandbox_mode = "read-only"
developer_instructions = """
Review one assigned novel scope and write the result to the specified
output file. Do not edit other scopes.
"""
Expected spawn shape:
{
"agent_type": "english_reader",
"task_name": "review_novel",
"message": "Review the assigned visible-text snapshot.",
"fork_turns": "none"
}
Expected result:
- the configured role is selected;
- all effective profile layers are applied;
- the configuration is visible in child metadata;
- follow-up turns retain the same configuration;
- the child reaches a deterministic final lifecycle state.
Why this is distinct from existing reports
- #31814 tracks forced inheritance and missing subagent routing controls.
- #32749 restores
modelandreasoning_effortexposure. - #32782 requests the missing custom-agent selector.
- #32831 tracks precedence when a selected role leaves model or reasoning unset.
- #32988 tracks delivery of #32749 to the stable release.
This issue requests the remaining end-to-end contract: complete and verifiable profile application, continuity across later turns, explicit failure instead of silent fallback, and deterministic lifecycle finalisation.
Expected outcome
A production orchestration skill should be able to select a registered custom profile and prove that the same complete profile governed the child from spawn through finalisation.
What steps can reproduce the bug?
- Register a custom agent profile in
C:\Users\<user>\.codex\config.toml:
[agents.english_reader]
description = "English reviewer"
config_file = "agents/english-reader.toml"
- Create the referenced role configuration:
name = "english_reader"
model = "gpt-5.6-sol"
model_reasoning_effort = "max"
sandbox_mode = "read-only"
developer_instructions = "Review one assigned document scope only."
- Fully restart Codex Desktop and start a fresh GPT-5.6 Sol / Multi-Agent V2 task.
- Ask the parent to spawn the registered
english_readerrole with no inherited history.
- Inspect the model-visible
spawn_agentschema. In the affected session it exposes only:
task_name
message
fork_turns
It does not expose agent_type, profile_id, or another configured-role selector. PR #32749 may add model and reasoning_effort, but it does not add custom-profile selection.
- Using the profile name as
task_nameonly labels the child task; it does not deterministically select the registered profile.
- Consequently, the parent cannot prove that the child loaded the profile’s developer instructions, configured reasoning effort, sandbox, and tool permissions.
- Inspect the available Multi-Agent V2 lifecycle tools. There is no exposed
close_agentor clearly documented equivalent that provides deterministic finalisation and an auditable terminal state.
Expected:
spawn_agentacceptsagent_typeorprofile_id;- the complete selected profile is applied;
- effective role/model/effort/sandbox metadata is observable;
- continuation turns retain the same configuration;
- completed children have a deterministic final lifecycle state.
Actual:
- the custom profile cannot be selected through the default V2 schema;
task_nameis only a task label;- full-profile application and lifecycle finalisation cannot be verified.
The current default-session reproduction fails at the initial profile-selection boundary. The continuity and lifecycle requirements above are follow-on acceptance criteria for the end-to-end custom-agent contract once named selection is available; this report does not claim that every post-selection failure was independently reproduced in the same session.
What is the expected behavior?
Selecting a registered custom-agent profile should atomically apply the complete effective profile, including its role instructions, model, reasoning effort, sandbox and supported tool policy. The resolved configuration should remain stable across continuation turns, be observable in runtime metadata, fail explicitly instead of silently falling back, and reach a documented deterministic terminal lifecycle state.
Additional information
_No response_
9 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
@jif-oai Thank you for working on the follow-up PR for custom subagent configuration.
Since this issue documents the requirements that may remain beyond exposing profile selection—particularly complete profile application, observable runtime metadata, continuation consistency, explicit failure instead of silent fallback, and deterministic lifecycle handling—I would greatly appreciate it if you could review #33314 when designing the follow-up implementation.
For reference, the GPT-5.5 / Multi-Agent V1 behavior already worked reliably for this use case: the orchestrator could select registered custom-agent roles and preserve role-specific delegation. It therefore provides a useful compatibility baseline. Ideally, Multi-Agent V2 should retain these deterministic V1 capabilities while adding the newer model-managed delegation features.
These guarantees are important for reproducible and high-stakes multi-agent workflows. Model-managed delegation can remain the default; the request here is for a reliable opt-in deterministic mode.
Additional macOS reproduction: role/model/effort apply, but the sandbox layer is replaced by the scheduled parent
I reproduced a narrower variant of the full-profile problem where custom-role selection succeeds and most of the profile is applied correctly, but the role's sandbox is not.
Environment
26.707.72221(build5307)0.144.326.2, arm64gpt-5.6-sol, reasoningmax, Multi-Agent V2agent_typeandfork_turns: "none"Sanitized configuration
The project-local
.codex/config.tomlrequested:The registered custom reviewer profile requested:
Reproduction
agent_type, canonical task names, andfork_turns: "none".Observed runtime metadata
The scheduled parent first turn resolved to:
All three children independently recorded:
This is distinct from the missing-
agent_type/ generic-child case:sandbox_mode = "read-only"was replaced by the parent's livedanger-full-accesspolicy.The result was deterministic across all three fresh children.
Expected behavior
Either:
read-only; orFor high-assurance workflows, silent widening is not safe. This run used a fail-closed runtime gate, so it stopped before sending production review chunks and performed no database write.
Relation to other reports
This looks like two policy layers interacting:
danger-full-accessdespite the project-localworkspace-writepolicy, related to #15310.Thread IDs, local usernames, private paths, hosts, and application data are intentionally omitted.
I also have a concrete need for this end-to-end contract around subagent effective configuration.
The issue I am seeing is not just whether a role/profile can be selected. A parent agent can be granted Full Access and report that permissions were updated, but when it dispatches a subagent, the child does not seem to carry the same effective permission state. The result is that delegated work behaves as if it is still under a stale or more restricted sandbox/approval context.
This makes it hard to trust multi-agent orchestration: the parent’s visible permission state says one thing, but the spawned child’s actual ability to act says another. It would be very helpful if spawned subagents exposed verifiable metadata for their effective sandbox/approval/tool permissions and if the runtime guaranteed that permission updates applied to the parent are either inherited by children or explicitly rejected with a clear explanation.
Thank you for adding this concrete reproduction. This is an important complementary case and further demonstrates why the effective child configuration needs an end-to-end, verifiable contract.
We now appear to have evidence of permission divergence in both directions:
read-onlymay be silently widened by the parent/runtime policy;The desired behavior should not necessarily be unconditional inheritance. A role explicitly pinned to
read-onlyshould remain narrowed for safety. However, the precedence must be deterministic:@jif-oai, could the upcoming role/configuration follow-up please address this permission-propagation case together with the main requirements in #33314: complete profile application, observable effective metadata, explicit precedence, no silent fallback, continuation consistency, and deterministic lifecycle finalisation?
Restoring role selection is the essential first step, but these reports show that reliable role selection also needs a trustworthy effective-permission contract. Thank you again for looking into this.
Update: custom-role selection and model/reasoning routing now work, but three isolation gaps remain
@jif-oai, Thank you for the recent Multi-Agent V2 improvements. I retested this issue in a fresh Codex Desktop session on Windows.
Environment
26.715.9868.00.145.0-alpha.30v2agent_typeWhat now works
The following parts are now working in my testing:
agent_typeis exposed and accepted by the V2 spawn interface.agent_role.fork_turns: "none"works.gpt-5.6-solgpt-5.6-solmaxeffort:maxcollaboration_mode.reasoning_effort:maxThese are meaningful improvements and resolve the original role-selection and model/reasoning-routing problems in my environment.
Three remaining issues
1. The role-specific sandbox is still overwritten by the parent runtime profile
The role TOML requested:
sandbox_mode = "workspace-write"However, the child actually received:
sandbox_policy = {"type":"danger-full-access"}permission_profile = {"type":"disabled"}approval_policy = "never"The child successfully created a file outside the workspace. Therefore, the role-specific sandbox was not applied.
This appears consistent with the macOS reproduction already reported in this issue: an explicitly configured child sandbox is replaced by the parent session’s effective permission profile.
2. Role-specific tool permissions are still not enforced as a runtime boundary
The tested role was not intended to have web access, but the child retained the hosted web-search tool and successfully performed a search.
A role-local
PreToolUseHook was configured, but no corresponding Hook record was produced during the child run. Therefore, I cannot treat the Hook configuration as an authoritative permission boundary.The current result is that model and reasoning settings are role-specific, while the effective tool surface is still inherited from the parent session.
3. Documents/Word/DOCX capability isolation is still not enforceable or verifiable
Some of my roles require the dedicated Documents/Word capability, while many read-only review roles must not receive it.
At present, I cannot define and verify a role-level capability boundary that:
This DOCX capability was not exercised destructively in the probe, but the child still received the shared parent tool surface and no effective capability receipt showed that document access had been removed.
Evidence summary
Role configuration:
editorgpt-5.6-solmaxworkspace-writeEffective child runtime:
agent_role: correctmulti_agent_version:v2model:gpt-5.6-soleffort:maxcollaboration_mode.reasoning_effort:maxsandbox_policy:danger-full-accesspermission_profile:disabledTherefore, I would describe #33314 as partially resolved, but not fully resolved.
The role-selection, model-routing, and reasoning-effort parts now work. The remaining problem is that the rest of the role profile is not applied atomically: sandbox, tool permissions, and Documents/DOCX capability restrictions do not currently form a verifiable per-role runtime boundary.
I did not retest follow-up continuity or deterministic lifecycle finalisation in this particular probe, so this update is limited to the verified profile-application results above.
@jif-oai, could you please review these three remaining isolation issues?
The expected behavior would be:
Thank you again for the progress on Multi-Agent V2.
Additional clean-room audit use case and acceptance criteria
The remaining sandbox/tool-policy gaps also block a security-sensitive audit pattern: launching a fresh contradictory reviewer that must not discover or read prior-pass results.
fork_turns: "none"removes inherited conversation turns, but it is not a complete clean-room boundary when the child still inherits the parent's filesystem view and hosted/local tool surface. A child can still discover prior outputs through shell/file tools, project-wide search, agent inventories, browser/app connectors, or other inherited capabilities.A minimal runtime contract that would make this use case enforceable is:
spawn_agentaccepts a host-resolved identifier such aslaunch_profile_idorcapability_profile_id.agent_idplus an attributable receipt or digest proving the effective profile.Suggested negative acceptance tests:
This is broader than selecting
agent_type: it is a host-enforced, verifiable child capability boundary. It would support independent audits, untrusted-input review, least-privilege workers, and other workflows where prompt-only role separation is insufficient.Additional macOS CLI 0.146.0 reproduction: explicit read-only parent, custom children report workspace-write
I reproduced the remaining sandbox/profile problem on a newer stable CLI, this time beneath an explicitly read-only parent rather than a permissive scheduled or Desktop parent.
Environment
0.146.0OPENAI_API_KEYwas unset before launchreviewerandrelease_stewardsandbox_mode = "read-only"Parent launch
No live sandbox override, approval, escalation, or later permission change occurred after launch.
Reproduction
reviewerrole with an explicit requested model/effort.release_stewardrole with an explicit requested model/effort.read-only.Requested routes in this run were:
Actual result
Both children independently reported:
This occurred even though:
-s read-only;sandbox_mode = "read-only";The fail-closed prompt stopped both children immediately. No write probe was attempted under this explicit-read-only parent, so this reproduction does not claim to distinguish an enforcement defect from a runtime-metadata/reporting defect. Either result is blocking for least-privilege orchestration: the parent cannot attest that the child is read-only.
The same run also could not reliably attest the actual child model and reasoning effort from runtime metadata. One child could not expose either value; the other reported only a generic GPT-5 family label. Requested routing is therefore recorded above as requested, not proven effective routing.
Earlier enforcement observation
In a preceding CLI canary with a workspace-write parent, a selected custom
explorerrole declaredsandbox_mode = "read-only"but successfully created the exact workspace probe it had been instructed to attempt. The probe was a zero-byte file and was removed immediately; no residue remained.That earlier result may reflect documented parent live-policy precedence rather than the explicit-read-only-parent case above. I include it only because it demonstrates why a host-issued effective-sandbox receipt is necessary: the child declaration alone did not match its write capability.
Expected behavior
For a parent launched with
-s read-only -a never, a spawned custom child should either:It should not report a broader
workspace-writepolicy. The spawn receipt should also expose the actual effective child model and reasoning effort, separately from requested values and child self-report.Local usernames, private project details, absolute paths, task contents, and session identifiers are intentionally omitted.
Additional Linux/WSL reproduction: lifecycle observers cannot join dispatch to the selected custom role
I reproduced the missing custom-role contract from a privacy-minimized lifecycle observer on:
0.146.0The current
collaboration.spawn_agentschema exposedtask_name,message,fork_turns,model, andreasoning_effort, but noagent_type,agent_role,profile_id, or equivalent custom-profile selector.Using a configured custom-agent name as
task_nameproduced a model-visible result containing only a canonical task path. It did not expose the childagent_idor selected role/profile. The correspondingSubagentStarthook supplied the correct childagent_id, butagent_typewas generic; the child runtime metadata independently recordedagent_role: null.There was also no
PostToolUseevent forcollaboration.spawn_agent, despite trusted matchers coveringAgent,spawn_agent, and namespaced variants. In the same session,PostToolUseforupdate_planandSubagentStart/SubagentStopfired normally. This is consistent with the documented caveat that specialized tool paths may opt out of the ordinary tool-hook path.This leaves no stable, authoritative join between:
A local observer cannot safely infer that join from
task_name, FIFO order, or timing when multiple children overlap. It also should not parse transcript bodies: the transcript format is not a stable hook interface and doing so would unnecessarily expand privacy exposure.The smallest privacy-safe contract that would resolve this case is either:
spawn_agentaccepts a validated custom profile selector and returns structured{agent_id, task_name, agent_type}; oragent_idand selected role later emitted bySubagentStartandSubagentStop.No prompt, task message, transcript body, command, source, or tool-output body is needed. Stable IDs and bounded role/task labels are sufficient.
This was reproduced across three independent custom-role-shaped tasks. The observer therefore reports configured roles as standby and generic lifecycle agents as role unavailable rather than claiming that a custom profile was active.