feat: agent hierarchy tracking (human -> agent -> sub-agent)#76
Merged
feat: agent hierarchy tracking (human -> agent -> sub-agent)#76
Conversation
Data model: - 4 new fields on audit Entry: parent_agent, agent_instance_id, root_agent, agent_depth - New agent_hierarchy table tracking parent-child relationships per session with tool counts and block counts - Schema migration: additive columns + new table, zero downtime Hooks handler: - Session state tracking via sync.Map (session_id -> sessionState) - getSessionState() resolves parent, root, and depth for each event - Root agent (depth 0) detected when no agent_type present - Sub-agents get parent = root agent, depth = parent + 1 - UpsertHierarchy called on each event to maintain the tree Dashboard: - Session trace shows agent tree panel above timeline when hierarchy data exists. Each node shows role icon, agent name, tool count, block count. Indented by depth. - AI session analysis prompt includes hierarchy tree for better attribution of who spawned whom Template: - seq() function for generating indent levels
Live feed: - Sub-agents (depth > 0) display with "└" indent prefix - Agent column widened to 20 chars for indent space Event detail: - Shows "Parent: <agent>" when event is from a sub-agent - Shows "(sub-agent, depth N)" next to agent name - Empty lines suppressed when no parent
- TraceStep now carries ParentAgent and AgentDepth from audit entry - Session trace timeline shows "sub-agent" tag (not "agent") when depth > 0, with muted color to indicate lower responsibility - Builds on hierarchy data populated by hooks handler
Root cause: Claude Code sets X-Oktsec-Agent header to "claude-code" for ALL events, but resolves agent names in the JSON body (via agent_type or config matching). The header is always the root agent. Fix: compare the resolved agent name (ev.Agent) with the header value. If they differ, the event is from a sub-agent. Set parentAgent = header value, depth = 1. Also: only set Agent from header if the JSON body didn't provide one (prevents header from overwriting body-resolved agent names).
Query: auditSelectCols now includes parent_agent, agent_instance_id, root_agent, agent_depth. Scan reads all 4 new columns. Without this, TraceStep.AgentDepth was always 0 because the Query method never read the fields from the DB, even though they were written correctly. TUI: event detail uses dynamic line array instead of JoinVertical with empty strings, preventing blank line when no parent agent.
Agent detail page: - Shows "Sub-agent of: claude-code" with link for sub-agents - Shows "Sub-agents spawned: explore (10 calls), plan (6 calls)" as clickable cards for parent agents - Data from agent_hierarchy table aggregated by agent name Store: - Uses existing DB() method for direct hierarchy queries TUI: - Event detail uses dynamic line array to prevent empty line when no parent agent exists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Track parent-child relationships between agents. When Claude Code spawns sub-agents (Explore, Plan, custom), oktsec records the hierarchy.
Data layer
Detection
Dashboard
TUI
Known issues (follow-up)
Test plan