Expose root/subagent metadata in hook payloads

Resolved 💬 6 comments Opened May 1, 2026 by raine Closed Aug 5, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What variant of Codex are you using?

CLI

What feature would you like to see?

Codex hook payloads identify the emitting session and turn, but they do not say whether the hook came from the root agent or from a spawned subagent.

This matters for hook integrations that update shared external state. For example, workmux marks a tmux window working on UserPromptSubmit and done on Stop. If a subagent finishes before its parent, the subagent Stop marks the window as done while the parent is still running. (Claude Code does not behave like this, subagents don't trigger hooks at all.)

The parent and subagent have distinct session_id and turn_id values, but the hook payload does not expose a root/subagent indicator, parent id, depth, or agent path. A hook handler therefore cannot tell whether a Stop event belongs to the root agent or a child agent.

Codex appears to already track this internally via subagent session metadata:

ThreadSpawn {
    parent_thread_id: ThreadId,
    depth: i32,
    agent_path: Option<AgentPath>,
    agent_nickname: Option<String>,
    agent_role: Option<String>,
}

My request is to include some kind of stable root/subagent relationship metadata in hook payloads, for example:

{
  "agent_path": "/root/task_1",
  "parent_session_id": "019de386-3b26-7a10-9109-fff7621fd637",
  "depth": 1,
  "is_subagent": true
}

This would let hook integrations handle nested Codex agent flows without parsing transcripts or relying on (session_id, turn_id) heuristics.

Related https://github.com/raine/workmux/commit/309188b764f8cbffbc07cb4d8aba698a6b576b0d

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #18105

Powered by Codex Action

founderaideps · 3 months ago

This is a real external-state problem, not just a hook payload nicety.

If a hook updates shared state, it needs to know whether the event came from the root agent, a child agent, or a nested worker. Otherwise “done” becomes ambiguous and downstream orchestration lies.

We’re seeing the same pattern in agent workflow tracking: agent identity, parent run, packet ID, and approval state need to be first-class fields, not inferred from session IDs. Would parent_session_id be enough for workmux, or do you also need a stable root/workflow id?

oxysoft · 3 months ago

Indexed this hook ticket in the umbrella tracker: #21753

Goal: collect the scattered Codex hook requests and bugs into one parity matrix for Full Claude Code Hook Parity (29+), while preserving this issue as the detailed thread for its specific behavior.

AgenticThinkingUK · 3 months ago

Agree with this. For audit and orchestration, subagent identity needs to be first class rather than inferred.

The minimum shape I would want in hook payloads is:

{
  "root_session_id": "...",
  "parent_session_id": "...",
  "agent_session_id": "...",
  "agent_path": "/root/task_1",
  "depth": 1,
  "agent_role": "builder",
  "cwd": "...",
  "terminal_state": "running|stopped|failed"
}

Without that, external subscribers cannot tell root done from worker done. Status boards, approval workflows and audit logs can all end up lying by accident.

This is also needed for neutral runtime evidence formats such as AgentHook. Multi agent events need stable lineage so downstream systems can reconstruct who did what, under which parent task, and whether the overall workflow is still active.

Keesan12 · 3 months ago

The hook payload really needs both lineage and terminal intent. parent_session_id and depth help attribution, but the operational field I keep missing is a stable oot_session_id plus an ^Ggent_path or lineage array so external runtimes can aggregate spend, stops, and receipts across the whole tree. Otherwise you can tell that a child stopped without knowing whether the root is still healthy or whether that stop should roll up into a shared halt summary. We have been hitting the same seam in MartinLoop when wrapping multi-agent runs. If you end up shaping this, I would also expose whether the current event is terminal for the child only versus terminal for the full run, because that is where a lot of false done state comes from.

etraut-openai contributor · 23 days ago

Hooks now expose child metadata and dedicated SubagentStop.