Skip to content

fix(server): preserve parentAgentId for Codex tasks discovered via activity - #167

Draft
pandec wants to merge 2 commits into
mainfrom
upstream/codex-parent-agent-id
Draft

fix(server): preserve parentAgentId for Codex tasks discovered via activity#167
pandec wants to merge 2 commits into
mainfrom
upstream/codex-parent-agent-id

Conversation

@pandec

@pandec pandec commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Note

Preview of an upstream PR for pingdotgg/t3code. Never merge this; main here is a clean upstream mirror. Close once the upstream PR is open.

Problem

A Codex child task discovered only through a collabAgent/activity notification loses its parent. The activity fallback path built task.started without parentAgentId, while the collabAgent/started path preserved it (apps/server/src/provider/Layers/CodexAdapter.ts). Children that surface this way render as roots, so the task hierarchy breaks.

Fix

The subAgentActivity item itself carries no parent field, but the enclosing notification envelope's threadId is the spawning thread for a started activity (per the app-server emission path; verified against the generated schema and the captured multi-agent wire fixture). So:

  • CodexSessionRuntime records that envelope threadId as the child's parent when registering a child from a started activity — authoritative thread/started spawn metadata always outranks it — and forwards it on the synthetic events, including the shared childIdentity used by turn/status lifecycle rows.
  • CodexAdapter carries parentAgentId in statusLinkage, so it is repeated on started, updated, token-usage, and item progress rows alike. This follows the contract's requirement (packages/contracts/src/providerRuntime.ts) that identity linkage rides every lifecycle row: with the 500-row activity retention cap, a child whose task.started ages out is reconstructed from later rows, and the parent must survive that. The two task.started builders are also deduped into one helper so the paths cannot drift apart again.
  • Registration now uses a single Ref.modify instead of update-then-read.

Verification

  • New tests: child discovered via started activity emits task.started with the right parent; interacted activity emits no start; both task.started routes carry the parent; status and both progress-row builders repeat it; explicit spawn metadata beats the envelope inference; nested root → A → B linkage attributes B to A, not the root.
  • Guards are mutation-proofed: deleting the started-only condition or the existing-parent precedence each turns a test red.
  • Focused suites: 35 tests pass. vp check and vp run typecheck clean.

[screenshot placeholder, optional: agents sidebar showing a Codex subagent nested under its parent after the fix, flat at root level before]

Notes

  • Client classification: subagentRuntime treats any parentAgentId as workflow_agent. Activity-discovered children now get the same classification the collabAgent/started path already produced; no rendering site keys off that kind today, and such children stay in the direct list. Making the client represent native (non-workflow) hierarchies is a separate discussion.

Relationship to pingdotgg#6416

pingdotgg#6416 also carries parentAgentId through the activity path, as one piece of a 23-file feature surfacing managed Codex runs; it is currently conflicting and has unresolved review findings. This PR fixes only the hierarchy defect, mergeable independently. Happy to close this one if pingdotgg#6416 lands first. Related child-task work: pingdotgg#7507, pingdotgg#7585.

Implemented by gpt-5.6-sol, orchestrated and reviewed (opus + sol panel) in Claude Code (Fable 5).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant