Comprehensive guide to tracing Claude Code sessions in Braintrust, including sub-agent correlation.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionbraintrust-tracingExecute the skills CLI command in your project's root directory to begin installation:
Fetches braintrust-tracing from parcadei/continuous-claude-v3 and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate braintrust-tracing. Access via /braintrust-tracing in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
3.7K
GitHub stars
0
upvotes
Run in your terminal
0
installs
0
this week
3.7K
stars
Comprehensive guide to tracing Claude Code sessions in Braintrust, including sub-agent correlation.
PARENT SESSION
+---------------------+
| SessionStart |
| (creates root) |
+----------+----------+
|
+----------v----------+
| UserPromptSubmit |
| (creates Turn) |
+----------+----------+
|
+--------------------+--------------------+
| | |
+---------v--------+ +--------v--------+ +--------v--------+
| PostToolUse | | PostToolUse | | PreToolUse |
| (Read span) | | (Edit span) | | (Task - inject) |
+------------------+ +-----------------+ +--------+--------+
|
+----------v----------+
| SUB-AGENT |
| SessionStart |
| (NEW root_span_id)|
+----------+----------+
|
+----------v----------+
| SubagentStop |
| (has session_id) |
+---------------------+
| Hook | Trigger | Creates | Key Fields |
|---|---|---|---|
| SessionStart | Session begins | Root span | session_id, root_span_id |
| UserPromptSubmit | User sends prompt | Turn span | prompt, turn_number |
| PreToolUse | Before tool runs | (modifies Task prompts) | tool_input.prompt |
| PostToolUse | After tool runs | Tool span | tool_name, input, output |
| Stop | Turn completes | LLM spans | model, tokens, tool_calls |
| SubagentStop | Sub-agent finishes | (no span) | session_id of sub-agent |
| SessionEnd | Session ends | (finalizes root) | turn_count, tool_count |
Session (task span) - root_span_id = session_id
|
+-- Turn 1 (task span)
| |
| +-- claude-sonnet (llm span) - model call with tool_use
| +-- Read (tool span)
| +-- Edit (tool span)
| +-- claude-sonnet (llm span) - response after tools
|
+-- Turn 2 (task span)
| |
| +-- claude-sonnet (llm span)
| +-- Task (tool span) -----> [Sub-agent session - SEPARATE trace]
| +-- claude-sonnet (llm span)
|
+-- Turn 3 ...
SessionStart doesn't receive the Task prompt.
We tried injecting trace context into Task prompts via PreToolUse:
# PreToolUse hook injects:
[BRAINTRUST_TRACE_CONTEXT]
{"root_span_id": "abc", "parent_span_id": "xyz", "project_id": "123"}
[/BRAINTRUST_TRACE_CONTEXT]
But SessionStart only receives session metadata, not the modified prompt. The injected context is lost.
Task spans in parent session contain everything:
agentId - identifier for the sub-agent runtotalTokens, totalToolUseCount - metricscontent - full agent response/summarytool_input.prompt - original task prompttool_input.subagent_type - agent type (e.g., "oracle")SubagentStop hook receives the sub-agent's session_id:
root_span_idCurrent state: Sub-agents create orphaned traces (new root_span_id).
Correlation method:
agentId or timing with orphaned tracessession_id = its trace's root_span_idFuture solution (not yet implemented):
SubagentStop fires -> writes session_id to temp file
PostToolUse (Task) -> reads temp file -> adds child_session_id to Task span metadata
This would link: Task.agentId + Task.child_session_id -> orphaned trace root_span_id
~/.claude/state/braintrust_sessions/
{session_id}.json # Per-session state
Each session file contains:
{
"root_span_id": "abc-123",
"project_id": "proj-456",
"turn_count": 5,
"tool_count": 23,
"current_turn_span_id": "turn-789",
"current_turn_start": 1703456789,
"started": "2025-12-24T10:00:00.000Z",
"is_subagent": false
}
~/.claude/state/braintrust_global.json # Cached project_id
~/.claude/state/braintrust_hook.log # Debug log
# View hook logs in real-time
tail -f ~/.claude/state/braintrust_hook.log
# Check if session has state
cat ~/.claude/state/braintrust_sessions/*.json | jq -s '.'
# Verify environment
echo "TRACE_TO_BRAINTRUST=$TRACE_TO_BRAINTRUST"
echo "BRAINTRUST_API_KEY=${BRAINTRUST_API_KEY:+set}"
# List recent sessions
uv run python -m runtime.harness scripts/braintrust_analyze.py --sessions 5
# Analyze last session
uv run python -m runtime.harness scripts/braintrust_analyze.py --last-session
# Replay specific session
uv run python -m runtime.harness scripts/braintrust_analyze.py --replay <session-id>
# Find sub-agent traces (orphaned roots)
uv run python -m runtime.harness scripts/braintrust_analyze.py --agent-stats
# Enable verbose logging
export BRAINTRUST_CC_DEBUG=true
# Test hooks manually
echo '{"session_id":"test-123","type":"resume"}' | \
bash "$CLAUDE_PROJECT_DIR/.claude/plugins/braintrust-tracing/hooks/session_start.sh"
# Test PreToolUse (Task injection)
echo '{"session_id":"test-123","tool_name":"Task","tool_input":{"prompt":"test"}}' | \
bash "$CLAUDE_PROJECT_DIR/.claude/plugins/braintrust-tracing/hooks/pre_tool_use.sh"
No traces appearing:
TRACE_TO_BRAINTRUST=true in .claude/settings.local.jsonecho $BRAINTRUST_API_KEYtail -20 ~/.claude/state/braintrust_hook.logSub-agents not linking:
--agent-stats to find agent activityagentId in parent Task spanMissing spans:
current_turn_span_id in session stateState corruption:
rm ~/.claude/state/braintrust_sessions/*.jsonrm ~/.claude/state/braintrust_global.json| File | Purpose |
|---|---|
.claude/plugins/braintrust-tracing/hooks/common.sh |
Shared utilities, API, state management |
.claude/plugins/braintrust-tracing/hooks/session_start.sh |
Creates root span, handles sub-agent context |
.claude/plugins/braintrust-tracing/hooks/user_prompt_submit.sh |
Creates Turn spans per user message |
.claude/plugins/braintrust-tracing/hooks/pre_tool_use.sh |
Injects trace context into Task prompts |
.claude/plugins/braintrust-tracing/hooks/post_tool_use.sh |
Creates tool spans, captures agent/skill metadata |
.claude/plugins/braintrust-tracing/hooks/stop_hook.sh |
Creates LLM spans, finalizes Turns |
.claude/plugins/braintrust-tracing/hooks/session_end.sh |
Finalizes session, triggers learning extraction |
scripts/braintrust_analyze.py |
Query and analyze traced sessions |
~/.claude/state/braintrust_sessions/ |
Per-session state files |
~/.claude/state/braintrust_hook.log |
Debug log |
| Variable | Required | Default | Description |
|---|---|---|---|
TRACE_TO_BRAINTRUST |
Yes | - | Set to "true" to enable |
BRAINTRUST_API_KEY |
Yes | - | API key for Braintrust |
BRAINTRUST_CC_PROJECT |
No | claude-code |
Project name |
BRAINTRUST_CC_DEBUG |
No | false |
Verbose logging |
BRAINTRUST_API_URL |
No | https://api.braintrust.dev |
API endpoint |
Attempted: Inject trace context via PreToolUse into Task prompts.
Result: Failed - SessionStart only receives session metadata, not the prompt.
Discovery: Task spans already contain rich sub-agent data:
metadata.agent_type - agent type from subagent_typemetadata.skill_name - skill from Skill tooltool_input - full prompt sent to agenttool_output - agent responseCurrent correlation path:
agentId and timingroot_span_id = session_idsession_idsession_id linkFuture work: Write child_session_id to Task span metadata from PostToolUse after SubagentStop.
agentId, sub-agent has separate session_id1. Prompt injection via PreToolUse
SessionStart hook only receives session metadata (session_id, type, cwd), NOT the prompt. Injected trace context is never seen.
The hook receives:
{
"session_id": "...",
"type": "start|resume|compact|clear",
"cwd": "...",
"env": {...}
}
No prompt field exists - context injection is impossible at SessionStart.
2. SubagentStop → PostToolUse file handoff
Race condition. These are independent async hooks with no timing guarantees:
3. PreToolUse correlation files
SessionStart can't access the task_span_id because it has no context about which Task spawned it. PreToolUse modifies prompts but doesn't create a reliably accessible state file that SessionStart can find.
Post-hoc matching for dataset building:
Parent session Task spans contain:
agentId - identifier for the sub-agent runtotalTokens, totalToolUseCount - aggregated metricscontent - full agent response/summarytool_input.prompt - original task prompttool_input.subagent_type - agent type (e.g., "oracle")Sub-agent sessions contain:
session_id (equals orphaned trace root_span_id)Correlation strategy:
root_span_id)subagent_type from Task promptsession_id (can be captured and logged)SessionStart input is intentionally minimal - it contains no prompt or tool context:
interface SessionStartInput {
session_id: string;
type: "start" | "resume" | "compact" | "clear";
cwd: string;
env: { [key: string]: string Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
parcadei/continuous-claude-v3
parcadei/continuous-claude-v3
jwynia/agent-skills
mindrally/skills
github/awesome-copilot
kostja94/marketing-skills
braintrust-tracing has been reliable in day-to-day use. Documentation quality is above average for community skills.
braintrust-tracing reduced setup friction for our internal harness; good balance of opinion and flexibility.
Keeps context tight: braintrust-tracing is the kind of skill you can hand to a new teammate without a long onboarding doc.
braintrust-tracing fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
braintrust-tracing has been reliable in day-to-day use. Documentation quality is above average for community skills.
braintrust-tracing reduced setup friction for our internal harness; good balance of opinion and flexibility.
Solid pick for teams standardizing on skills: braintrust-tracing is focused, and the summary matches what you get after install.
braintrust-tracing reduced setup friction for our internal harness; good balance of opinion and flexibility.
braintrust-tracing is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
braintrust-tracing has been reliable in day-to-day use. Documentation quality is above average for community skills.
showing 1-10 of 63