Scope
Lineage only: who a subagent's parent is, what the root session is, and the parent-of-subagent chain. Operator/user identity is out of scope for agent-bundle by maintainer decision (2026-09-03, see #391); this issue tracks no identity fields.
What the host exposes (2026-09-03, live capture)
Evidence: docs/audits/2026-09-03-host-lineage-matrix.md §1–§5 and fixtures/host-lineage/codex-0.147.0.ndjson (PR #421). Real Codex 0.147.0, codex exec --json --dangerously-bypass-hook-trust, [features] multi_agent, one collaborationspawn_agent thread that spawned a nested thread (depth 2, max_depth = 3).
| Fact |
Observed |
| Root id on every hook payload |
session_id (the root thread), plus turn_id |
| Subagent id on its own events |
agent_id (= thread id) + agent_type: default + its own turn_id; transcript_path is the subagent's own rollout |
Parent on SubagentStart |
absent. Only SubagentStop hints at it: transcript_path there is the parent's rollout and agent_transcript_path the child's. |
spawn_agent hook payload |
tool_input.message arrives encrypted (gAAAA…), so hooks cannot read the child task; PostToolUse returns {"task_name": …} with no child id, and it fires before SubagentStart |
MCP tools/call _meta |
x-codex-turn-metadata with session_id, thread_id, turn_id, parent_thread_id, forked_from_thread_id, thread_source, subagent_kind, sandbox, workspaces, model — the complete lineage, natively |
| Environment |
hooks inherit the operator environment (CODEX_HOME, PLUGIN_ROOT, PLUGIN_DATA, CLAUDE_PLUGIN_ROOT, CLAUDE_PLUGIN_DATA); MCP servers receive only the manifest env |
What the framework does about it
request.lineage (#421) is the single surface for parent/root/subagent on every host. On Codex it resolves MCP calls natively from _meta.x-codex-turn-metadata (thread_id, parent_thread_id, session_id; a grandchild whose parent thread the registry never saw stays id-not-resolvable rather than guessed) and hook events through the registry, claiming the newest unclaimed collaborationspawn_agent call under the same root as the parent (Codex closes that call before SubagentStart, so the claim window is independent of the open-call window); it refuses when two different parents have unclaimed spawns. The capability-table lineage reasons cite this issue and the observations record since #444 (merged as 284141958).
Host-side gap (recorded for reference; not submitted to the host — maintainer decision 2026-09-03)
Hook-side parent/depth stay degraded (inferred) until a Codex build carries parent_thread_id (already in x-codex-turn-metadata) on SubagentStart and on every hook payload inside a subagent; the MCP side is already native. No feedback is sent to OpenAI; the per-host write-up was removed in #467 (merged as 9d4fbd867) per maintainer decision, and docs/audits/2026-09-03-host-lineage-matrix.md plus the capability tables are the record a newer build is re-checked against.
Scope
Lineage only: who a subagent's parent is, what the root session is, and the parent-of-subagent chain. Operator/user identity is out of scope for agent-bundle by maintainer decision (2026-09-03, see #391); this issue tracks no identity fields.
What the host exposes (2026-09-03, live capture)
Evidence:
docs/audits/2026-09-03-host-lineage-matrix.md§1–§5 andfixtures/host-lineage/codex-0.147.0.ndjson(PR #421). Real Codex 0.147.0,codex exec --json --dangerously-bypass-hook-trust,[features] multi_agent, onecollaborationspawn_agentthread that spawned a nested thread (depth 2,max_depth = 3).session_id(the root thread), plusturn_idagent_id(= thread id) +agent_type: default+ its ownturn_id;transcript_pathis the subagent's own rolloutSubagentStartSubagentStophints at it:transcript_paththere is the parent's rollout andagent_transcript_paththe child's.spawn_agenthook payloadtool_input.messagearrives encrypted (gAAAA…), so hooks cannot read the child task;PostToolUsereturns{"task_name": …}with no child id, and it fires beforeSubagentStarttools/call_metax-codex-turn-metadatawithsession_id,thread_id,turn_id,parent_thread_id,forked_from_thread_id,thread_source,subagent_kind,sandbox,workspaces,model— the complete lineage, nativelyCODEX_HOME,PLUGIN_ROOT,PLUGIN_DATA,CLAUDE_PLUGIN_ROOT,CLAUDE_PLUGIN_DATA); MCP servers receive only the manifestenvWhat the framework does about it
request.lineage(#421) is the single surface for parent/root/subagent on every host. On Codex it resolves MCP calls natively from_meta.x-codex-turn-metadata(thread_id,parent_thread_id,session_id; a grandchild whose parent thread the registry never saw staysid-not-resolvablerather than guessed) and hook events through the registry, claiming the newest unclaimedcollaborationspawn_agentcall under the same root as the parent (Codex closes that call beforeSubagentStart, so the claim window is independent of the open-call window); it refuses when two different parents have unclaimed spawns. The capability-tablelineagereasons cite this issue and the observations record since #444 (merged as284141958).Host-side gap (recorded for reference; not submitted to the host — maintainer decision 2026-09-03)
Hook-side
parent/depthstaydegraded(inferred) until a Codex build carriesparent_thread_id(already inx-codex-turn-metadata) onSubagentStartand on every hook payload inside a subagent; the MCP side is already native. No feedback is sent to OpenAI; the per-host write-up was removed in #467 (merged as9d4fbd867) per maintainer decision, anddocs/audits/2026-09-03-host-lineage-matrix.mdplus the capability tables are the record a newer build is re-checked against.