feat: write parent session context into subagent session_meta for distributed tracing
Summary
When Claude Code spawns a subagent via the Task tool, it creates a new session with a separate JSONL transcript file. The subagent's transcript marks messages with isSidechain: true and an agentId, but contains no reference to the parent session that spawned it.
This makes cross-session distributed tracing impossible for observability tools — the parent and child transcripts are two isolated islands with no shared key.
Current Behavior
Parent session transcript (~/.claude/projects/<project>/<parent-session>.jsonl):
{"type":"assistant","message":{"content":[{"type":"tool_use","id":"call-xyz","name":"Task","input":{"description":"..."}}]}}
{"type":"user","message":{"content":[{"type":"tool_result","tool_use_id":"call-xyz","content":"..."}]}}
Child session transcript (~/.claude/projects/<project>/<child-session>.jsonl):
{"type":"assistant","isSidechain":true,"agentId":"subagent-1","message":{...}}
The child session has no parent_session_id, no parent_turn_id, no parent_tool_call_id. An external tool reading both files cannot deterministically link them.
Requested Change
When Claude Code creates a subagent session (i.e. spawns via Task), write the parent context into the child session's first session_meta entry:
{
"type": "session_meta",
"sessionId": "<child-session-id>",
"parentSessionId": "<parent-session-id>",
"parentTurnId": "<turn-id-of-the-spawning-turn>",
"parentToolCallId": "<tool_use_id-of-the-Task-call>",
"isSidechain": true,
...existing fields...
}
Alternatively, if session_meta is not the right place, any structured first-line entry in the JSONL that external readers can reliably locate is acceptable.
Why This Matters
Without this link, observability tools face two bad options:
- Timestamp guessing — scan sibling sessions for
isSidechain: trueentries whose start time falls within the parent's Task call window. Breaks when multiple subagents are spawned concurrently. - No linking at all — parent and child traces are forever disconnected.
With parentSessionId + parentToolCallId in the child's metadata, tools can:
- Reconstruct the full agent execution tree
- Aggregate token costs across the entire hierarchy
- Attribute failures to the correct spawning turn
- Build flame-graph style views of multi-agent workflows
Context
This request comes from Spanory, an open-source observability tool for Claude Code and other agentic runtimes. It emits OTel spans and Langfuse traces from Claude Code session transcripts. Parent-child linking is the last gap preventing full distributed tracing support.
The companion issue tracking Spanory's side of this work: https://github.com/Bububuger/spanory/issues/1
Proposed Fields (non-normative)
| Field | Type | Description |
|---|---|---|
| parentSessionId | string | Session ID of the spawning parent session |
| parentTurnId | string | Turn identifier within the parent session |
| parentToolCallId | string | tool_use_id of the Task call that created this session |
| isSidechain | boolean | Already exists on message entries; ideally also on session_meta |
| agentId | string | Already exists; the subagent's own identifier |
Backward Compatibility
Adding new fields to session_meta is additive. Existing readers that don't know these fields will ignore them. No breaking change.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗