You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(lineage): Codex stop correction reads the child rollout for exact depth; a recorded agent path never claims a differently-pathed spawn
Review threads on #480: (1) reparenting to a parent the registry never
placed kept the inferred depth; the same SubagentStop names the child's own
rollout in agent_transcript_path, so exact parent and depth are read from it
first, with the parent-rollout basename as the fallback. (2) with an exact
agent path from the rollout, pending spawns recorded with a different path
are excluded; only matching or pathless (response missed) calls remain
eligible.
| Claude | Yes, with the parent inferred |`SubagentStart` names the child (`agent_id`). The parent is not in the payload; it is the agent whose `Agent`/`Task``PreToolUse` is open when `SubagentStart` fires (root when none is open) — re-verified live at depth 1 and 2 in all three runs, including two spawns issued in one message (the host serialises them: each `SubagentStart` fires before the next `Agent``PreToolUse` opens). The host then confirms the link on the parent's `Agent``PostToolUse` (`tool_response.agentId` = the child, `status``async_launched` or `completed`). `Stop`/`SubagentStop` list the children still running **in the background** in `background_tasks[]` (empty when every child ran in the foreground). |
317
-
| Codex | Yes |`SubagentStart` names the child thread and its rollout (`transcript_path`); the rollout's `session_meta` head records `source.subagent.thread_spawn.{parent_thread_id, depth, agent_path}` (§10), so the parent is read, not inferred. The `collaborationspawn_agent` call is matched to the child by `agent_path` (= the call's `PostToolUse``tool_response.task_name`, rows 16/27). With the rollout unreadable, the parent is inferred from the newest unclaimed spawn call and corrected at `SubagentStop`by the parent rollout in `transcript_path`. MCP calls carry `parent_thread_id` directly. |
317
+
| Codex | Yes |`SubagentStart` names the child thread and its rollout (`transcript_path`); the rollout's `session_meta` head records `source.subagent.thread_spawn.{parent_thread_id, depth, agent_path}` (§10), so the parent is read, not inferred. The `collaborationspawn_agent` call is matched to the child by `agent_path` (= the call's `PostToolUse``tool_response.task_name`, rows 16/27). With the rollout unreadable, the parent is inferred from the newest unclaimed spawn call and corrected at `SubagentStop`— from the child's own rollout (`agent_transcript_path`) when readable by then, else from the parent rollout in `transcript_path`. MCP calls carry `parent_thread_id` directly. |
318
318
| Cursor | Yes for the spawn, weakly for the child's traffic |`subagentStart` carries `parent_conversation_id`, `subagent_id`/`tool_call_id`, `is_parallel_worker`. The child's own `conversation_id` is not in that payload, so the first event with an unseen conversation id after a `subagentStart` is bound to it (unambiguous when children start sequentially; ambiguous for parallel workers). |
319
319
320
320
**Can a plugin running under a subagent know its parent/root?**
@@ -481,4 +481,6 @@ places the thread with `resolution: 'transcript'`; the MCP `_meta` lineage
481
481
(§3) and the hook-side lineage therefore agree by construction. What stays
482
482
host-side: the payload itself still carries no `parent_thread_id`, so a hook
483
483
that cannot read `CODEX_HOME/sessions` (or a rollout not yet flushed) falls
484
-
back to spawn-ordering inference and is corrected at `SubagentStop`.
484
+
back to spawn-ordering inference and is corrected at `SubagentStop` (from the
485
+
child's own rollout when readable by then, else from the parent rollout's
Copy file name to clipboardExpand all lines: packages/agent-bundle/src/adapters/capabilities/codex-0.147.0.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -446,7 +446,7 @@
446
446
"state": "supported",
447
447
"evidence": [
448
448
"2026-09-03: SubagentStart names no parent thread (#423), but names the new thread's rollout in transcript_path — as does every hook fired inside the thread; SubagentStop moves it to agent_transcript_path — and that rollout's session_meta head records source.subagent.thread_spawn.parent_thread_id, present on every thread-spawn rollout observed for cli 0.130.0 through 0.152.0 (fixtures/host-lineage/codex-0.147.0-rollouts). The registry reads it at SubagentStart, on the first hook of a thread seen mid-flight, and at SubagentStop (resolution: transcript, provenance derived); standalone hooks read it the same way. tools/call _meta.x-codex-turn-metadata carries parent_thread_id natively.",
449
-
"2026-09-03: with the rollout unreadable the registry falls back to claiming the newest unclaimed collaborationspawn_agent call under the same root (resolution: registry; refused when two parents have unclaimed spawns) and corrects that parent at SubagentStop from the parent rollout named in transcript_path (rollout-<timestamp>-<thread id>.jsonl). The spawn call's PostToolUse tool_response.task_name (/root/<task>/…) equals the child rollout's agent_path, so the spawning tool call is matched by path rather than by order."
449
+
"2026-09-03: with the rollout unreadable the registry falls back to claiming the newest unclaimed collaborationspawn_agent call under the same root (resolution: registry; refused when two parents have unclaimed spawns) and corrects that parent at SubagentStop: from the child's own rollout in agent_transcript_path (exact parent and depth) when readable, else from the parent rollout named in transcript_path (rollout-<timestamp>-<thread id>.jsonl). The spawn call's PostToolUse tool_response.task_name (/root/<task>/…) equals the child rollout's agent_path, so the spawning tool call is matched by path rather than by order."
0 commit comments