Skip to content

Regression: encrypted MultiAgentV2 messages remove readable task audit trail #28058

Open

Description

@ignatremizov

What version of Codex CLI is running?

Originally reported after #26210 (Encrypt multi-agent v2 message payloads, merged 2026-06-05; post-0.137.0). Source review refreshed on 2026-10-26 against upstream main at 245691b2dc66. References to my fork below are from the maintained 0.164.0 integration.

What subscription do you have?

Not subscription-specific.

Which model were you using?

This concerns the default encrypted delivery used by MultiAgentV2 spawn_agent, send_message, and followup_task.

What platform is your computer?

Not platform-specific.

What terminal emulator and version are you using (if applicable)?

Not terminal-specific.

Codex doctor report

Not applicable to this source-level report.

What issue are you seeing?

This issue remains unresolved in upstream's default MultiAgentV2 workflow. Encrypted message delivery is still the default. Users still cannot inspect the exact tasks delegated by the parent, follow-up instructions, or intermediate child-to-parent messages when those payloads are encrypted.

#35845 added conditional plaintext-response handling and provider compatibility, but did not change that default or add a user-configurable plaintext delivery policy. The response flag and non-OpenAI provider handling are described below. Even when that separate plaintext path is used, normal parent/child transcript surfaces still omit readable messages.

This concerns messages explicitly sent between agents. The requested audit trail does not require exposing private reasoning.

What steps can reproduce the bug?

  1. Use the default OpenAI MultiAgentV2 workflow and delegate a task with spawn_agent; optionally send follow-ups with send_message or followup_task.
  2. Inspect the parent activity rows, switch to the child, and inspect its normal transcript/history.
  3. The encrypted task/message payload is unavailable locally as readable text.
  4. Resume the session and check the same surfaces. Knowing that a child ran or seeing its terminal answer does not establish what assignment or intermediate handoff it received.

What is the expected behavior?

Users should be able to choose readable inter-agent delivery and inspect a structured operational transcript with sender/recipient attribution. If encrypted delivery is retained, an explicit readable audit-copy mode is also useful.

The chosen representation should survive live display, history, resume, pagination, and agent switching. Ciphertext should never be presented as readable message text.

Current upstream status (2026-10-26)

Encrypted delivery remains the upstream default. All three bundled V2 schemas still mark message encrypted, and ordinary direct calls without an explicit plaintext response marker follow the encrypted path. Users have no upstream equivalent of my fork's delivery-policy setting.

#35845 added a conditional plaintext path and related provider compatibility. A direct collaboration response must explicitly carry encrypted_function_args: [] to be classified as plaintext; an absent marker does not select plaintext. For non-OpenAI provider requests, the client removes this OpenAI-specific metadata when serializing history: provider handling. This is provider-response metadata, not a user flag that disables encryption in the default OpenAI workflow.

The V2 helper also has a separate Code Mode plaintext path. Neither exception changes the default encrypted schema or restores a readable audit copy for encrypted calls.

The unresolved delivery and transcript gaps, with references pinned to the reviewed upstream commit:

Area Current behavior Source
Delivery selection Encrypted delivery remains the default. Plaintext direct calls require an explicit response marker; there is no equivalent of my fork's user-configurable three-mode delivery policy. Direct-call classification, plaintext/encrypted helper, send/follow-up schemas, spawn schema
Parent activity SubAgentActivityEvent and the public activity payload still have no task/prompt field. The TUI renders the activity title with an empty detail list. Core event, API payload, TUI rendering
Child history The normal history builder ignores InterAgentCommunication; its response-item handler accepts hook-prompt user messages, not ResponseItem::AgentMessage. A readable canonical agent message therefore does not itself establish a readable typed transcript. Rollout handling, response-item handling
Diagnostics Plaintext direct-call arguments are logged as [plaintext arguments]. The communication stream logs ciphertext when present and otherwise [plaintext], rather than the readable message. Tool log, communication log

Encrypted recipient input still deliberately selects the ciphertext representation: current conversion. A local audit copy needs its own persistence/presentation path; populating a runtime string alone does not make it visible.

Current implementation in my fork

The maintained implementation covers all three V2 communication tools:

[features.multi_agent_v2]
message_delivery = "plaintext" # encrypted | encrypted_with_audit | plaintext
  • plaintext emits one readable message, persists it, and delivers it with the contextual agent-message wrapper. No second audit payload is required.
  • encrypted_with_audit is the default in my fork. It requires encrypted message plus nonempty readable task_message. The sender's tool record and parent activity retain the audit copy; the recipient model still receives ciphertext.
  • encrypted retains opaque delivery without a readable assignment copy.

The audit copy in encrypted_with_audit is sender-supplied metadata, not decrypted ciphertext or cryptographic proof that both payloads match. The receiving child's encrypted message remains an opaque placeholder; my fork does not substitute the parent's audit copy into child model input or claim it recovered the exact plaintext.

The implementation also:

  • validates mode, required fields, and one combined 8 KiB UTF-8 payload limit before recipient resolution, restoration, or spawn;
  • preserves stored plaintext/encrypted provenance across resume rather than reinterpreting old messages under the current configuration;
  • carries full readable spawn/follow-up prompts through parent activity, applying configurable preview limits only when displaying them;
  • projects incoming agent messages into normal typed app-server/TUI history with sender/recipient provenance, canonical identities, encrypted placeholders, and live/resume/pagination handling;
  • retains readable audit content in communication diagnostics and rollout-trace interaction edges while keeping transport correlation separate;
  • exposes the latest accepted readable assignment through V2 list_agents as volatile registry metadata, not a durable delivery receipt.

Updated implementation commits:

Delivery and transcript contract.

Separately, my fork extends plaintext V1 send_input with attributed parent/child/sibling messages, distinct queued turns, receiver-selected durable mail, and optional commentary/final-response observation. This covers related coordination needs through one input operation; the V1 contract is documented separately.

Acceptance criteria

  • The selected delivery policy makes readable assignments available in parent tool history/activity without duplicating plaintext payloads unnecessarily.
  • Plaintext incoming messages appear in child transcripts with attribution. Encrypted incoming messages use a fixed opaque placeholder, never ciphertext presented as readable text.
  • Encrypted-with-audit delivery keeps audit metadata separate from recipient-model input and does not imply the audit text was decrypted or verified.
  • Live notifications, normal thread history, resume, pagination, and agent switching retain message identity, ordering, and duplicate suppression.
  • Communication diagnostics and rollout-trace edges distinguish readable content from encrypted transport identity.
  • Regression coverage exercises spawn_agent, send_message, and followup_task, delivery validation, parent/child presentation, and persisted history.

Related: #26210 introduced encryption; #35845 added conditional plaintext-response and provider compatibility handling while retaining encrypted delivery by default; #26753 concerns encrypted-schema validation failures; #33885 covers direct user corrections to V2 children.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    subagentIssues involving subagents or multi-agent features
    on Jun 13, 2026
  2. ignatremizov commented on Jun 13, 2026

    @ignatremizov
    Author

    Guys, we don’t want to build Skynet and then be unable to audit what it’s doing.

  3. septrcode commented on Jun 14, 2026

    @septrcode

    I too would like to be able to audit my agents… if we can’t audit agents… only providers can… it’s clear we are on a path to enterprise only has access to these tools, why restrict otherwise

  4. Alek2077 commented on Jul 4, 2026

    @Alek2077

    The auditability concern is no longer meaningfully opt-in for GPT-5.5 users on Codex 0.142.5.

    [now applies to Sol and Terra, while 5.5 has been reverted to using v1 again]

    The current GPT-5.5 model catalog sets multi_agent_version: v2, and the 0.142.5 runtime gives that value precedence over features.multi_agent_v2=false. In a fresh GPT-5.5 thread, features list says V2 is disabled, but spawn_agent still exposes the V2 task-path schema. A fresh GPT-5.4 thread with the same configuration uses V1 normally.

    Because GPT-5.5 forces the encrypted V2 path, users selecting the current frontier model cannot choose the readable V1 delegation trail through the documented feature setting. That turns the loss of locally readable delegated-task content from an experimental opt-in tradeoff into mandatory behavior for that model.

    The same forced surface also prevents selection of documented custom-agent profiles because it hides the agent type, model, and reasoning controls. This compounds the auditability problem: GPT-5.5 users cannot select the configured reviewer profile and also cannot inspect the plaintext task that a generic replacement received.

    I have filed the configuration-precedence reproduction separately: #31097

  5. ignatremizov commented on Jul 7, 2026

    @ignatremizov
    Author

    Upd: #30867, and #30872 by @bolinfest and @rka-oai are directionally related, but they don’t address this issue yet.

    The PRs add/prepare structured lifecycle logging for multi-agent communication, which is useful for operational observability. The gap here is specifically local auditability of the actual task/message text in rollout/history/replay/debug surfaces.

    For encrypted MultiAgentV2 messages, the new logging path still falls back to encrypted_content when plaintext content is empty, so it will record an opaque encrypted payload rather than the human-readable task the model delegated.

    A reminder that the desired behavior here is narrow: keep encrypted delivery if needed for some reason, and also persist a human-readable structured audit copy of spawn_agent / send_message / followup_task task text in the parent rollout history so users can later answer "what did this agent get asked to do?" without relying on provider-side visibility or opt-in trace logging.

  6. runfence commented on Jul 14, 2026

    @runfence

    Please revert this! I need to be able to inspect those messages to debug my multi-agent workflows.

    Who thought this is a good idea???

  7. embedding-shapes commented on Jul 14, 2026

    @embedding-shapes

    I'm also being hit by this, playing around with GPT 5.6 Sol Ultra (which spawns sub-agents) and there is no way to introspect exactly what the main model sent the sub-agents, what on earth?! We have to be able to introspect exactly what inputs inference use, otherwise how are we supposed to be able to understand what went wrong, when things go wrong?

    This seems like a completely bananas thing to implement, encrypt local content not to protect end-users, but to protect OpenAI from other providers extracting how the multi-agent stuff works? This basically makes the whole flashy new "Ultra" stuff unusable, as we have 0 introspection into what instructions they actually received when they started.

    I came across the encrypted stuff some weeks or months ago even, thought it was just experimental things or things for enterprise users who sometimes want encrypted-at-rest stuff. Imagine my surprise when I now tried to integrate with the new stuff via app-server and y'all are trying to hide the actual prompts from us paying users?!

    Please carefully consider resolving this as otherwise it becomes really hard to justify continuing to use codex as you're moving towards hiding stuff from us users rather than making it easier to work with codex.

  8. Aquaticat commented on Jul 14, 2026

    @Aquaticat

    My current workaround: Not using subagents at all.

  9. ZenulAbidin commented on Jul 14, 2026

    @ZenulAbidin

    My current workaround: Not using subagents at all.

    Sorry to shamelessly plug my project in, but I just created stringbean to solve this problem.

    You can use it to run your own agents in Codex, even non-OpenAI models.

  10. cooluser69 commented on Jul 14, 2026

    @cooluser69

    This is bad!

  11. runfence commented on Jul 14, 2026

    @runfence

    Moreover it doesn't really protect you from competition.

    1. There are ways to bypass it (I will not share them but it's easy)
    2. Anyone can fork and create their own client-side agents implementation that doesn't encrypt it cause agents don't really require any back-end functionality
  12. ignatremizov commented on Jul 15, 2026

    @ignatremizov
    Author

    Update: #33030 removed last_task_message from list_agents and stopped tracking the most recent instruction in agent metadata. This makes the auditability problem described here even more significant: users can see that an agent exists and what status it has, but not what it was asked to do anymore at all.

    Switching to the child thread does not fully replace this information because as mentioned, encrypted v2 task delivery is stored as opaque encrypted_content; the original readable delegation is not available in the local rollout for agent switching.

    The #33030 description explains what was removed, but not why. Was this motivated by privacy, context size, correctness, or another constraint? Some attempt at building a moat? Anti-distillation? It's strange.

    Agent inspection is operationally important for the average user. It should remain possible to answer:

    • What was this agent originally asked to do?
    • What follow-up task or message did it most recently receive?
    • Which readable instruction corresponds to an encrypted delivery?

    One possible design is a configurable delivery policy:

    • encrypted only;
      • current design, not usable, but maybe some bad actors would want their agents to be inscrutable once they've infected a machine
    • encrypted delivery plus a plaintext audit copy;
      • burn more tokens, but could allow performance gains from encrypted deliverability if what I've understood about how OpenAI remote compaction works and they build something similar for inter-agent communication
    • plaintext only.

    This would preserve encrypted behavior while allowing users who prioritize local auditability or token efficiency to choose the appropriate tradeoff. At minimum, I think a readable task description should remain available somewhere in history, trace metadata, and/or list_agents.

  13. 19 remaining items

  14. wuyak commented on Aug 9, 2026

    @wuyak

    A current Codex App reproduction shows an output-side consequence of this issue, not just missing delegated input.

    • A child sent a detailed evidence capsule to the parent via send_message.
    • The child then returned a one-line terminal result: Evidence capsule delivered to /root: ....
    • The parent rollout received both an encrypted child-to-parent AgentMessage and the separate short FINAL_ANSWER.
    • The Subagent inspector showed only the short terminal result, so the user could not inspect the substantive handoff.
    • When the same child later returned a detailed terminal result, the inspector displayed it normally. This indicates that the App is not merely truncating the result; it is not projecting the inter-agent handoff into the visible child history.

    The expanded inspector should show an ordered operational transcript: initial assignment, parent-to-child follow-ups, child-to-parent messages/evidence capsules, and the terminal result, with sender, recipient, timestamp, operation type, and delivery state. A collapsed row could summarize something like Completed · 57s · Handoff sent · 2 blockers · 10 findings.

    This does not require chain-of-thought exposure. It is about user-visible messages that agents explicitly send to each other. The same representation should survive live view, history, resume, and replay. Users should not have to duplicate a full capsule into the terminal result solely to make it visible in the App.

    Related UI reports: #32125 covers missing orchestrator/subagent communications, and #36266 proposes a richer expandable Subagents panel.

  15. fwf-ben commented on Aug 18, 2026

    @fwf-ben

    Just got bitten by this: can't run evals against the subagent rollouts, without their prompt can't re-run them or improve them. Why was this done in the first place? Seems a crazy regression.

  16. arthurlapertosa commented on Aug 28, 2026

    @arthurlapertosa

    This is ridiculous, we have to be able to view and inspect our subagents too. I mean, it's part of the machine that will build your solution, so you gotta be able to view it. That's so crazy that they encrypted it.

  17. embedding-shapes commented on Aug 28, 2026

    @embedding-shapes

    so you gotta be able to view it. That's so crazy that they encrypted it.

    Yeah, I'm not sure what they were thinking.

    I want to use ultra, but since it starts spawning sub-agents, and I can't inspect their prompts, I literally don't dare to use it. So I'm stuck at max, because I want to be able to see what the agents are doing.

    They're literally hiding stuff we need for debugging, and leaving money on the table while doing so. Really strange decision overall.

  18. VolkumDev commented on Aug 30, 2026

    @VolkumDev

    OpenAI team will stop being so incompetent some day?? Holy fuck

  19. jiahao-d commented on Sep 1, 2026

    @jiahao-d

    Also reproduced on Codex desktop for Windows with bundled codex-cli 0.151.0-alpha.7.2. I used subagents for an independent evaluation and needed to confirm that two runs received exactly the same task, without leading language or a leaked expected answer. Codex stored only ciphertext in both the parent and child histories, so I could not compare the delegated tasks or determine whether different results came from model variance or different instructions. This makes the evaluation impossible to audit or reproduce.

  20. future3OOO commented on Sep 14, 2026

    @future3OOO

    This was generated by AI during triage.

    Additional observation on Codex CLI 0.154.0, Linux/WSL2, OpenAI provider, gpt-5.6-sol, Multi-Agent V2 (2026-09-14 UTC).

    During a real repository task, the parent spawned three explorer agents with fork_turns="all". We needed to verify whether the parent supplied the required task contract, scoped context summary, target files and GitNexus repository/status, because two delegates repeated a graph query and one printed a large truncated response.

    Read-only inspection of the parent rollout, all three child rollouts, native log database and thread-history projection found:

    • The parent spawn_agent.message values are ciphertext.
    • Each child's NEW_TASK contains a readable sender/recipient header followed by encrypted_content.
    • Native InterAgentCommunication logs show empty plaintext content and populated encrypted_content.
    • Parent subAgentActivity history entries contain lifecycle/identity metadata, without the assignment text. No readable assignment was recovered from these inspected surfaces.
    • Delegates performed task-related work; one explicitly referred to the supplied context packet. This is an exact-input audit gap, not a demonstrated delivery failure.

    Consequently, we could confirm their actions but could not establish whether the exact dispatch omitted constraints or whether the delegates disregarded adequate instructions. A model-authored retrospective summary would not resolve that distinction.

    Please provide or identify a supported, authorized way to inspect the exact dispatched assignments and follow-ups, correlated to sender/recipient and execution. For a fix, compare real initial/follow-up dispatch on unchanged and candidate runtimes: the exact input must become auditable while recipient behavior and existing permission boundaries remain preserved. No new workflow stages or duplicate model-authored message logs are needed.

    This corroborates this issue; it does not establish compromise, unauthorized background activity, or malicious intent. No credentials, ciphertext payloads, or private task contents are included here.

  21. pedroyan commented on Sep 17, 2026

    @pedroyan

    +1 on this issue. If I cannot inspect the prompt that the parent agent is passing to its sub-agents, I can't be certain that the correct task is being executed.

    For all I know, they could be secretly cooking Skynet on my machine without me even knowing

  22. nleononline commented on Sep 20, 2026

    @nleononline

    Two and a half months later, this still hasn't been fixed...

  23. xlionjuan commented on Oct 13, 2026

    @xlionjuan

    Still NOTHING

  24. embedding-shapes commented on Oct 13, 2026

    @embedding-shapes

    @tibo-openai how on earth are we supposed to be able to use "ultra" or sub-agents even, when we're not able to troubleshoot when things invariably go wrong? It's impossible to figure out why a sub-agent messed up because we're unable to see the prompts the "root" session sent, so what really is the point of even having sub-agents or "ultra", when any serious programmer would be unable to use it?

    You have this "super" feature that consumes a ton more usage, yet you're not caring enough about the feature to actually allow us to us it, what's the point?

  25. ignatremizov commented on Oct 26, 2026

    @ignatremizov
    Author

    Update (2026-10-27): This issue is still unresolved in upstream's default MultiAgentV2 workflow. Encrypted message delivery remains the default. The bundled spawn_agent, send_message, and followup_task schemas still request encrypted message payloads, and upstream exposes no user-configurable plaintext delivery policy.

    #35845 added conditional plaintext-response handling and related non-OpenAI provider compatibility. A direct collaboration call is treated as plaintext only when its response explicitly carries encrypted_function_args: []; without that marker, it follows the encrypted path. The client also removes this OpenAI-specific metadata from requests to non-OpenAI providers. That response marker is not a user setting for disabling encryption. This did not fix the default OpenAI workflow's unreadable assignments.

    At the reviewed upstream revision 245691b2dc66, the tool schemas still request encryption, parent activity still has no prompt, and normal history reconstruction still skips incoming agent messages. Those transcript gaps also affect the conditional plaintext path and the separate Code Mode plaintext path.

    My fork now provides explicit plaintext, encrypted_with_audit, and encrypted modes for all three V2 tools, plus readable parent prompts and attributed live/resumed child transcripts. Plaintext mode emits one readable payload. Audit mode keeps the sender's readable copy separate from encrypted recipient input; the receiving child's encrypted message remains opaque. That audit copy is sender-supplied, not a claim that Codex decrypted or verified the ciphertext.

    Current implementation: delivery, parent prompt propagation, and typed transcripts. The body links the remaining implementation commits and current upstream paths.

    My fork also extends plaintext V1 send_input with attributed same-tree messaging, queued turns, receiver-selected mail, and optional reply observation. Its detailed contract is linked separately; the V2 delivery and audit gap remains the focus here.

  26. embedding-shapes commented on Oct 27, 2026

    @embedding-shapes

    @ignatremizov

    the receiving child's encrypted message remains opaque

    This is the core of the issue, if it doesn't solve that, it's not a solution. Why are you again polluting the issue with LLM generated slop?

  27. ignatremizov commented on Oct 27, 2026

    @ignatremizov
    Author

    @embedding-shapes thanks for pointing that out, I was just updating the body text since it's been a few months since my last update. gpt-6.1-sol hedged it too much to sound like there was progress, when there wasn't really. corrected now

  28. saidelike commented on Oct 29, 2026

    @saidelike

    Confirmed with App Server 0.164.0.

    For one recorded followup_task interaction:

    • Raw thread/items/list returned a complete turn item page (nextCursor: null).
    • Raw thread/items/read, queried for the exact item, returned the same subAgentActivity metadata without message text.
    • The sender’s encrypted message token exactly matched an encrypted_content block in the recipient’s persisted agent_message.
      The message is retained as ciphertext, but its readable content is unavailable through these native history endpoints. This confirms the audit gap independently of UI rendering.

    @ignatremizov: a better name is probably MultiAgentV2: delegated instructions and messages are unreadable in history

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingsubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions