Skip to content

Execution graph for passive readers: session relationships and tool-result event chronology #42

@willwashburn

Description

@willwashburn

Context

Burn's normalized TurnRecord is intentionally compact, but it is now too lossy for the backlog that depends on historical / passive ingest.

What is currently lost or flattened:

  • session relationships beyond a flat subagent.isSidechain
  • parent / child session structure for forks, continuations, and subagents
  • tool-result chronology and terminal status
  • mapping from a tool call to the subagent session it spawned
  • richer passive-reader evidence already present in logs from Claude, Codex, and OpenCode-style sources

This matters because several backlog items implicitly assume those facts exist:

  • #8 subagent tree wants parent -> child -> grandchild attribution
  • #11 waste-pattern detection wants retries, failure streaks, and compaction / failure context
  • #3 waste / attribution gets better if tool-result events exist, not just tool-call names
  • archive work needs stable normalized tables for relationships and tool-result events

Agentsview's strongest parser lesson is that historical logs already carry much more structure than burn currently preserves. We should not make rich relationships depend only on hook path #7.

Goal

Define and preserve a normalized execution graph from passive readers.

This is not raw-content storage. It is structured metadata:

  • how sessions relate to each other
  • how tool calls and tool results unfold over time
  • which tool call spawned which subagent session
  • which events completed, errored, cancelled, or just streamed progress

Why #8 is not sufficient

#8 is about surfacing subagent trees from the current flat isSidechain model.

That is necessary, but it is still Claude-centric and mostly focused on the final tree view.

This issue is broader and lower-level:

  • not just subagents, but forks and continuations
  • not just final tree shape, but event chronology
  • not just Claude, but passive readers across Claude / Codex / OpenCode / future collectors

Think of this as the normalized substrate that #8 and #11 should consume.

Proposed record types

Do not overload TurnRecord with every field. Add sibling normalized record types.

A. SessionRelationshipRecord

One row / event per discovered session relationship.

type RelationshipType = 'root' | 'continuation' | 'fork' | 'subagent';

interface SessionRelationshipRecord {
  v: 1;
  source: SourceKind;
  sessionId: string;
  relatedSessionId?: string;
  relationshipType: RelationshipType;
  ts?: string;

  // provenance
  sourceSessionId?: string;
  sourceVersion?: string;
  parentToolUseId?: string;
  agentId?: string;
  subagentType?: string;
  description?: string;
}

B. ToolResultEventRecord

Canonical chronological tool-output / terminal-status events.

type ToolResultStatus = 'running' | 'completed' | 'errored' | 'cancelled' | 'unknown';

interface ToolResultEventRecord {
  v: 1;
  source: SourceKind;
  sessionId: string;
  messageId?: string;
  toolUseId: string;
  callIndex?: number;
  eventIndex: number;
  ts?: string;

  status: ToolResultStatus;
  eventSource: 'tool_result' | 'subagent_notification' | 'queue_event' | 'progress_event' | 'function_call_output';

  contentLength?: number;
  contentHash?: string;
  isError?: boolean;

  subagentSessionId?: string;
  agentId?: string;
}

These records can live beside TurnRecord in the ledger or in the future derived archive. The key point is that they are normalized and append-only.

Source-specific expectations

Claude passive reader

Historical Claude logs already expose more than burn uses today.

Reader should preserve when available:

  • parentUuid chain information relevant to forks / continuations
  • queue-operation / enqueue evidence mapping tool_use_id -> task_id
  • newer progress / agent_progress evidence mapping parentToolUseID -> agentId
  • source-session metadata when file session id and in-log session id differ
  • compaction boundaries as distinct events rather than only inferred later

Codex passive reader

Reader should preserve:

  • function_call_output as tool-result events
  • spawn_agent / wait relationships to subagent ids
  • terminal subagent notifications as chronological events attached to the originating tool call when possible
  • result status transitions instead of only the final tool-call name list

OpenCode / future SQLite-backed readers

Reader should preserve:

  • parent session ids / relationship metadata when available
  • tool-result sizes and statuses where exposed
  • chronology sufficient to rank failures and retries

Design constraints

  • This issue is about metadata, not full content. contentHash and contentLength are enough for most of the intended analyses.
  • Hook-based ingest (#7) may produce cleaner data, but passive readers must still populate the same normalized records where historical logs support it.
  • The contract must be cross-source. Do not invent a Claude-only side structure.

Query surface this should enable

Not necessarily in this issue, but this is the substrate for:

burn summary --subagent-tree <session>
burn diagnose <session>
burn waste --patterns
burn summary --by-relationship

Examples of questions that become answerable:

  • which subagent invocation cost the most?
  • which sessions were forks vs continuations?
  • which tool calls errored three times before succeeding?
  • how many spawned subagents never completed successfully?

Acceptance

  • Claude passive ingest can preserve fork / continuation / subagent relationships without relying on hook path #7.
  • Codex passive ingest can preserve function_call_output and subagent terminal status as ToolResultEventRecords.
  • The normalized execution graph is additive; existing TurnRecord consumers keep working.
  • The graph is rich enough that #8 can consume it instead of reconstructing everything from isSidechain and parentUuid alone.
  • The graph is rich enough that #11 can compute failures / retries / subagent terminal outcomes without source-specific hacks.

Depends on

  • none strictly, though archive work will want this normalized before locking schema

Unblocks

  • #8 subagent tree with real historical structure
  • #11 failure / retry / terminal-outcome analysis
  • derived archive issue for stable relationship and event tables
  • future search / analytics without needing hook-only data

Priority

High. This is the missing passive-reader substrate for several of burn's most interesting analyses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions