Skip to content

Populate tool_result_events archive table from execution-graph + content sidecar #101

@willwashburn

Description

@willwashburn

Context

PR #78 created the tool_result_events table in archive.sqlite but left it empty:

tool_result_events — table reserved (created, not populated) for the future content-sidecar bridge (#33) and execution-graph work.

The table is defined at packages/ledger/src/archive.ts (schema block, with the comment Reserved for the content-sidecar bridge (#33) and the execution-graph work). Columns: source, session_id, message_id, tool_use_id, call_index, event_index, status, content_length, content_hash, subagent_session_id, agent_id, event_source, ts.

The upstream data already exists or will exist:

This issue is the thin connector: read the canonical ToolResultEventRecord lines (and optionally enrich content_length / content_hash from the content sidecar where the execution-graph record doesn't already carry them) and materialize them into the archive's tool_result_events rows during incremental build.

Proposal

  1. In archive.ts, add a third pass to buildArchive() that handles LedgerLine kind tool_result_event (added by PR Execution graph substrate: SessionRelationshipRecord + ToolResultEventRecord (#42) #77). Parse via the new isToolResultEventLine guard and INSERT OR REPLACE INTO tool_result_events keyed on (source, session_id, message_id, tool_use_id, event_index).
  2. The execution-graph record already carries contentLength and contentHash (per PR Execution graph substrate: SessionRelationshipRecord + ToolResultEventRecord (#42) #77's record shape). If a future record lacks them, fall back to reading the matching ContentRecord from the content sidecar.
  3. Track build progress through the same archive_state.ledger_offset_bytes cursor — no separate cursor needed since both turn and tool-result-event lines live in the same ledger.jsonl.
  4. On rebuild-from-zero, replay tool-result-event lines alongside turn / stamp / compaction lines.

Tests:

  • Round-trip: append ToolResultEventRecord rows, run buildArchive(), assert they show up with correct keys, statuses, and content metadata.
  • Idempotence: rebuilding twice yields the same row count.
  • Mixed source: Claude + Codex + OpenCode events all materialize correctly.
  • Schema-mismatch path: bumping ARCHIVE_VERSION clears and re-populates tool_result_events from the ledger.

Acceptance criteria

  • tool_result_events is populated incrementally during burn archive build.
  • All columns defined in the schema have non-null values where the upstream record provides them.
  • burn archive status --json row counts include tool_result_events.
  • Archive rebuild from a ledger with N tool-result events yields exactly N (deduped) rows.
  • No regression to existing archive-build behavior for ledgers that pre-date PR Execution graph substrate: SessionRelationshipRecord + ToolResultEventRecord (#42) #77.

Out of scope

Refs

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