github AgentWorkforce/burn relayburn-v3.0.0
relayburn@3.0.0

6 hours ago

Packages

  • relayburn@3.0.0 (tag: relayburn-v3.0.0)
  • @relayburn/sdk@3.0.0 (tag: sdk-v3.0.0)
  • @relayburn/mcp@3.0.0 (tag: mcp-v3.0.0)
  • @relayburn/cli-darwin-arm64@3.0.0 (tag: cli-darwin-arm64-v3.0.0)
  • @relayburn/cli-darwin-x64@3.0.0 (tag: cli-darwin-x64-v3.0.0)
  • @relayburn/cli-linux-arm64-gnu@3.0.0 (tag: cli-linux-arm64-gnu-v3.0.0)
  • @relayburn/cli-linux-x64-gnu@3.0.0 (tag: cli-linux-x64-gnu-v3.0.0)
  • @relayburn/sdk-darwin-arm64@3.0.0 (tag: sdk-darwin-arm64-v3.0.0)
  • @relayburn/sdk-darwin-x64@3.0.0 (tag: sdk-darwin-x64-v3.0.0)
  • @relayburn/sdk-linux-arm64-gnu@3.0.0 (tag: sdk-linux-arm64-gnu-v3.0.0)
  • @relayburn/sdk-linux-x64-gnu@3.0.0 (tag: sdk-linux-x64-gnu-v3.0.0)

Crates

Release Notes

Added

  • burn overhead deltas: per-inference context-window attribution. New --session, --top, --min-delta, --owner, --explain, --json flags surface "what blew up my context between inference N and inference N+1?" — pairs same-rail Inference spans, attributes the delta in input + cache_read + cache_write to intervening ToolResult / UserPrompt / SystemReminder leaves, surfaces compaction events as their own row (never a negative delta), and isolates main-rail deltas from subagent rails. SDK entry point: LedgerHandle::context_delta(opts). (#432)
  • burn flow --session <id>: inference-flow DAG over a session's span
    trees. One column per turn on the main rail; dispatched subagents
    branch onto their own rails inheriting the dispatching inference's
    Y, with dispatch / return edges between rails and unattached
    edges for orphan subagents. Renders Mermaid (default), SVG
    (--output flow.svg), and JSON (--json). --max-turns defaults
    to 50. New SDK surface: LedgerHandle::flow_graph(session, opts)
    and free-function flow_graph_from_trees. (#431)
  • relayburn-sdk: per-turn span tree as derived analytical primitive.
    New LedgerHandle::turn_span_tree(session_id, turn_id) and
    session_span_trees(session_id) verbs project TurnRecord +
    tool_result_event rows + Claude subagent sidecars into an
    OTel-style TurnSpanTree { Turn -> { UserPrompt, Inference -> ToolUse -> { ToolResult, Subagent } } }. Pure projection — no schema change,
    no caching. Orphan subagents surface as sibling Subagent spans
    with unattached=true. Locked attribute keys (tokens.*, model,
    request_id, tool_use_id, agent_id, stop_reason) for
    downstream consumers (inference-flow DAG, context-delta attribution).
    (#430)
  • relayburn-sdk: ingest_claude_transcript_path(ledger, path, opts)
    per-transcript Claude fast-path used by burn ingest --hook claude so
    the hook ingests only the one JSONL the payload points at instead of a
    full sweep.

Changed

  • relayburn-cli: burn ingest --hook claude now drives the new
    single-transcript fast-path, bounding per-hook cost to one JSONL parse.
  • relayburn-cli: burn ingest --quiet is now accepted in default
    (one-shot) and --watch modes (no longer hook-only). Suppresses the
    progress spinner, watch banner, and per-tick summaries; one-shot mode
    still writes its final summary line to stdout for pipeline capture.
  • relayburn-sdk: Inference aggregate keys per-API-call rollups by
    (source, session_id, request_id) with merged usage and kind
    (reasoning / message / tool-use / mixed). Read via
    LedgerHandle::inferences(opts) (free function inferences() too);
    persisted at ingest into the new inferences table. Falls back to
    message_id for harnesses without a requestId (Codex, opencode,
    older Claude). (#434)
  • burn summary: one-line Turn outcomes: … breakdown of assistant
    stop_reason counts, plus a stopReasons block in --json. (#437)
  • Ledger fingerprint primitive ({count}:{maxMtimeUnix}:{totalBytes}) for
    cheap "did anything change" polling. Exposed as LedgerHandle::fingerprint
    on the Rust SDK, sdk.fingerprint() on @relayburn/sdk,
    burn state fingerprint [--session | --project] on the CLI, and
    burn__fingerprint on the MCP server. Optional Session(id) /
    Project(path) scopes; all-sessions is the default. (#440)
  • burn hotspots: new Bytes column on the per-tool tables and --rank-by bytes mode rank tools by raw output payload size, so a 4 MB Bash result that got truncated to a small token count still surfaces alongside small-bytes / large-tokens reads. JSON output gains totalOutputBytes, maxOutputBytes, and truncatedCount on every aggregation row. (#436)
  • relayburn-sdk: ToolResultEventRecord carries new outputBytes and outputTruncated fields populated at ingest from content.as_bytes().len() plus Claude truncation-marker detection; ToolAttribution / FileAggregation / BashAggregation / BashVerbAggregation / SubagentAggregation expose the rolled-up total_output_bytes, max_output_bytes, and truncated_count. (#436)
  • relayburn-sdk: Claude Task subagent sidecar discovery + pairing. New discover_subagents / pair_to_main / count_subagents_under helpers under crate::reader::claude::subagents walk <sessionId>/subagents/agent-*.jsonl, pair each sidecar against the parent's toolUseResult.agentId, and surface unpaired sidecars (slash-command synthetic dispatches and crash-mid-dispatch) as the UnattachedGroup bucket. Discovery is lazy — the directory is only stat'd when something asks for it. (#435)
  • burn summary: new subagents: X paired, Y orphan line (and matching subagents key in --json) populated by a lazy walk over ~/.claude/projects/. Skipped entirely when no sidecars exist anywhere reachable so pre-#435 outputs stay byte-identical. Honors BURN_CLAUDE_PROJECTS_DIR for test sandboxing. (#435)
  • Ledger schema bumped to v4 — new nullable turns.subagent_id TEXT column denormalizes TurnRecord.subagent.agent_id so subagent rows are queryable without re-deserializing record_json. Migrated in place by ALTER TABLE … ADD COLUMN; pre-v4 rows stay NULL and are backfilled by burn state rebuild. (#435)
  • relayburn-sdk: Claude slash-command triads (/review, /init, custom skills) now collapse into one synthetic Skill activity instead of inflating the activity count three rows at a time. Detection pins on the caveat → invocation → stdout parent-UUID chain shape with <command-name> / <local-command-stdout> purpose checks, so real user prompts that happen to look structurally similar are not misdetected. Token attribution stays on the underlying assistant rows — Skill is a view, not a billing reattribution. New ActivityCategory::Skill variant and detect_slash_triads helper. (#438)
  • relayburn-sdk: Claude Code parser now skips harness-injected
    <task-notification> rows when emitting UserTurnRecords. The detector
    matches shape AND purpose across three envelope variants
    (type: "queue-operation" + content prefix, origin.kind, and
    queued_command attachment with commandMode), so a real prompt that
    literally types <task-notification> is not filtered. Drops user-turn
    inflation from background Bash completions.
  • relayburn-sdk: Claude Code activity classifier now associates each
    assistant turn with its user prompt by walking the parentUuid chain
    to the nearest user-prompt ancestor, instead of file order. Fixes
    mis-classification of late-arriving assistant rows under out-of-order
    JSONL flushes and interrupt + resume sessions. Falls back to the
    previous file-order map for legacy/malformed rows without UUIDs.
    Codex and opencode readers are unaffected — their rollouts don't carry
    an equivalent chain field. (#433)
  • BREAKING relayburn-sdk: TurnRecord.stop_reason is now an
    Option<StopReason> enum (kebab-case wire form); deserialization is
    lenient so pre-3.0 ledgers replay cleanly. (#437)
  • relayburn-sdk ledger schema bumps to v3: turns gains a stop_reason TEXT column (#437) and tool_result_events gains nullable output_bytes
    / output_truncated columns (#436). Both are migrated in place on
    Ledger::open; existing rows leave the new columns NULL. Run burn state rebuild to backfill an older ledger.
  • relayburn-sdk ledger schema bumps to v5: adds the inferences
    derived table for per-API-call aggregates. Created idempotently on
    open; rebuilt by burn state rebuild. Pre-v5 ledgers stay empty
    until rebuild or the next ingest run. (#434)
  • relayburn-sdk: Claude Code parser now correctly merges usage
    from the carrier row of a multi-block assistant message. Previously,
    if the row carrying the usage block was not the first row for a
    given message_id, its tokens were dropped. The new merge adopts
    the carrier row's usage values whichever row owns them. (#434)

Package Changelogs

@relayburn/sdk

Added

  • fingerprint({ session?, project?, ledgerHome? }) returns a
    {count}:{maxMtimeUnix}:{totalBytes} polling primitive over turns.
    Sub-millisecond per session-scope call; suitable for "did anything
    change" gates without re-querying or re-ingesting. (#440)

@relayburn/mcp

Added

  • createFingerprintTool() factory + burn__fingerprint tool wrapping the
    SDK's new fingerprint primitive ({count}:{maxMtimeUnix}:{totalBytes}).
    Accepts optional sessionId / project to scope, mutually exclusive. (#440)

Don't miss a new burn release

NewReleases is sending notifications on new releases.