Skip to content

Migrate burn summary to archive query (#82)#129

Merged
willwashburn merged 3 commits intomainfrom
feat/summary-from-archive-82
Apr 27, 2026
Merged

Migrate burn summary to archive query (#82)#129
willwashburn merged 3 commits intomainfrom
feat/summary-from-archive-82

Conversation

@willwashburn
Copy link
Copy Markdown
Member

@willwashburn willwashburn commented Apr 26, 2026

Summary

  • burn summary now reads from archive.sqlite on the hot path. After the per-invocation ingestAll, it calls buildArchive() (cheap incremental tail scan) and then queryAllFromArchive(query) instead of streaming the canonical ledger.jsonl. Filters lower to indexed WHERE clauses on turns; tool calls are bulk-hydrated keyed on (source, session_id, message_id). Subagent-tree (--subagent-tree) and --by-subagent-type modes consume the same archive-derived turn slice.
  • New read-side entry point queryAllFromArchive(query) + archiveAvailable() in @relayburn/ledger, returning the same EnrichedTurn[] shape as queryAll so consumers can swap implementations without touching their aggregation code. Fidelity is reconstructed from the persisted attribution_fidelity / tokens_present / cost_present columns (Add fidelity / coverage columns to archive turns and sessions #110) plus class-implied coverage defaults — class equality is the load-bearing parity contract.
  • Two escape hatches preserve the legacy behavior: a new --no-archive flag and the RELAYBURN_ARCHIVE=0 env var both revert to queryAll. If the archive throws (corrupt sqlite, schema mismatch we couldn't recover from cleanly), the command transparently falls back to the streaming reader and surfaces the reason on stderr — the archive can never wedge burn summary.

Test plan

  • pnpm run test:ts — full workspace, 520 tests pass.
  • archive-query.test.ts — parity for unfiltered queries, project + workflow filters, since window; tool-call + subagent + fidelity hydration; empty-result path; archiveAvailable() lifecycle.
  • summary.test.ts--json parity between archive and ledger paths, text-mode parity (preamble-stripped), auto-build of archive.sqlite on first run, --no-archive flag does not build, RELAYBURN_ARCHIVE=0 does not build.
  • Spot-check on a real ~/.relayburn/ledger.jsonl: burn summary --since 7d and burn summary --since 7d --no-archive produce matching byModel / totalCost blocks.

Refs

Closes #82, refs #40, #78.

Generated with Claude Code


Open in Devin Review

Replaces the per-invocation `queryAll` ledger walk with `queryAllFromArchive`
that issues SQL against `archive.sqlite`. Filters lower to indexed `WHERE`
clauses; tool calls are bulk-hydrated; subagent-tree and `--by-subagent-type`
modes consume the same archive-derived turn slice. JSON + text output stays
parity-identical against the legacy reader for the load-bearing blocks
(`byModel`, `totalCost`, `fidelity`).

Two escape hatches preserve the old behavior: `--no-archive` flag and
`RELAYBURN_ARCHIVE=0` env var both revert to `queryAll`. If the archive
build/read throws (corrupt sqlite, schema mismatch we couldn't recover from
cleanly), the command transparently falls back to the streaming reader and
surfaces the reason on stderr — the archive can never wedge `burn summary`.

Tests cover parity (text + JSON), auto-build behavior, both fallback paths,
and the new `archive-query` reader (filters, tool-call hydration, fidelity
class round-trip, subagent block hydration).

Closes #82, refs #40, #78.
devin-ai-integration[bot]

This comment was marked as resolved.

Resolve conflicts between #82 (summary from archive) and #97 (MCP from
archive). Both PRs added a read-side helper to packages/ledger/src/archive-query.ts
under different names; keep both:

- queryAllFromArchive (this PR) — full EnrichedTurn shape with synthesized
  fidelity. Used by burn summary's archive hot path.
- queryTurnsFromArchive (main, from #97) — same shape minus fidelity
  synthesis. Used by the MCP tool handlers.

Both share buildSelect, loadToolCallsForKeys, and rowToEnrichedTurn, with
fidelity skipped via an opts flag for queryTurnsFromArchive.

Address Devin review on #129: subagent.description archive parity
(packages/ledger/pull/129#discussion_r3144029656).

- Add subagent_description TEXT column to the turns table (additive
  migration via ensureColumn — ARCHIVE_VERSION stays at 2).
- writeTurn persists t.subagent?.description.
- archive-query rowToEnrichedTurn populates subagent.description on the
  way back out, so burn summary --subagent-tree --json no longer silently
  drops the field on the default archive path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

After merging origin/main (which carried the 0.30.0 release), the
queryAllFromArchive / archiveAvailable bullet for #82 ended up filed
under the already-released 0.27.0 section. Move it back to [Unreleased]
where unreleased work belongs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@willwashburn willwashburn merged commit 49b7e2e into main Apr 27, 2026
1 check passed
@willwashburn willwashburn deleted the feat/summary-from-archive-82 branch April 27, 2026 13:08
willwashburn added a commit that referenced this pull request Apr 27, 2026
…hive-88

Resolve [Unreleased] CHANGELOG conflict in packages/analyze: keep the
compareFromArchive (#88) entry under [Unreleased] alongside the new
0.27.0 release block from main.

Also fix unescaped backticks in packages/ledger/src/archive.ts (introduced
on main via the #129 merge) — the SCHEMA_SQL template literal contained
`burn summary --subagent-tree --json` in a SQL comment, which
prematurely closed the literal and broke `tsc`. Replaced with single
quotes inside the comment so the schema string parses cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate burn summary from ledger walk to archive query

1 participant