braintrust-tracing
Braintrust tracing for Claude Code - hook architecture, sub-agent correlation, debugging
By parcadei · 491 installs
npx skills add parcadei/continuous-claude-v3 --skill braintrust-tracing
Source repository · Upstream listing
Braintrust Tracing for Claude Code
Comprehensive guide to tracing Claude Code sessions in Braintrust, including sub agent correlation.
Architecture Overview
Hook Event Flow
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
Trace Hierarchy
Sub Agent Tracing: What Works and What Doesn't
What Doesn't Work
SessionStart doesn't receive the Task prompt.
We tried injecting trace context into Task prompts via PreToolUse:
But SessionStart only receives session metadata, not the modified prompt. The injected context is lost.
What DOES Work
Task spans in parent session contain everything:
agentId identifier for the sub agent run
totalTokens , totalToolUseCount metrics
content full agent response/summary
tool input.prompt original task prompt
tool input.subagent type agent type (e.g., "oracle")
SubagentStop hook receives the sub agent's session id :
This equals the sub agent's orphaned trace root span id
Allows correlation between parent Task span and child trace
The Correlation Pattern
Current state: Sub agents create orphaned traces (new root span id ).
Correlation method:
1. Query parent session's Task spans for agent metadata
2. Match agentId or timing with orphaned traces
3. Sub agent's session id = its trace's root span id
Future solution (not yet implemented):
This would link: Task.agentId + Task.child session id orphaned trace root span id
State Management
Per Session State Files
Each session file contains:
Global State
Debugging Commands
Check if Tracing is Active
Query Braintrust Directly
Debug Hook Execution
Troubleshooting Checklist
1. No traces appearing:
Check TRACE TO BRAINTRUST=true in .claude/settings.local.json
Verify API key: echo $BRAINTRUST API KEY
Check logs: tail 20 ~/.claude/state/braintrust hook.log
2. Sub agents not linking:
This is expected sub agents create orphaned traces
Use agent stats to find agent activity
Correlate via timing or agentId in parent Task span
3. Missing spans:
Check current turn span id in session state
Ensure Stop hook runs (turn finalization)
Look for "Failed to create" errors in log
4. State corruption:
Remove session state: rm ~/.claude/state/braintrust sessions/ .json
Clear global cache: rm ~/.claude/state/braintrust global.json
Key Files
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
Environment Variables
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
Session Learnings
What We Learned About Sub Agent Tracing (Dec 2025)
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 type
metadata.skill name skill from Skill tool
tool input full prompt sent to agent
tool output agent response
Current correlation path:
1. Parent session Task span has agentId and timing
2. Sub agent creates orphaned trace with root span id = session id
3. SubagentStop provides the sub agent's session id
4. Manual correlation: match timing or use session id link
Future work: Write child session id to Task span metadata from PostToolUse after SubagentStop.
What We Learned About Sub Agent Correlation
The Problem
Sub agents spawned via Task tool create orphaned Braintrust traces
Parent session has Task spans with agentId , sub agent has separate session id
No built in link between them
What DOESN'T Work
1. 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:
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:
SubagentStop fires when sub agent session ends
PostToolUse (Task) fires when Task tool completes
No ordering guarantee between them
Writing to a correlation file creates a race
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.
What DOES Work
Post hoc matching for dataset building:
Parent session Task spans contain:
agentId identifier for the sub agent run
totalTokens , totalToolUseCount aggregated metrics
content full agent response/summary
tool input.prompt original task prompt
tool input.subagent type agent type (e.g., "oracle")
Start/end timestamps
Sub agent sessions contain:
session id (equals orphaned trace root span id )
Start/end timestamps
All internal spans and tool calls
Correlation strategy:
1. Export parent session traces (query parent root span id )
2. Export sub agent traces (query all sessions created within parent's time window)
3. Match by:
Timing: Task span end ≈ sub agent session end
Metadata: subagent type from Task prompt
IDs: SubagentStop hook provides session id (can be captured and logged)
Architecture Insight
SessionStart input is intentionally minimal it contains no prompt or tool context:
This design boundary prevents real time correlation at hook time.
Recommendation
For building agent run datasets with sub agent correlation:
1. In session logging: Capture SubagentStop session id in logs or state
2. Post session export: Query Braintrust API for parent and sub agent traces
3. Offline correlation: Match traces by timing and metadata in a script
4. Don't try real time linking: Hooks don't have necessary context
Example script pattern:
This approach is reliable, testable, and doesn't require hooks to maintain implicit state.