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.