Repository navigation
[G1] Tool-result fidelity: output bytes, truncation markers, content hash, ordering indexes, out-of-band error status, subagent-notification linkage #171
Copy link
Copy link
Closed
Description
Part of #160 (group 1 — independent).
Problem
burn's hotspots, tool_output_bloat, context_delta, and span-tree features are driven by per-tool-result facts that relayhistory does not record. relayhistory stores a tool result as a session_events row (role='tool_result', kind='tool_result', text=<content>) and sets tool_calls.is_error (crates/ai-hist/src/lib.rs Claude :3142-3298, Codex :2101-2508). Missing, with burn's reader/consumer for each (crates/relayburn-sdk/src/):
| Fact | burn producer | burn consumer |
|---|---|---|
output_bytes / content_length of the raw result payload (before any truncation relayhistory applies to text) |
reader/claude/tool_results.rs:25-112 |
analyze/tool_output_bloat.rs (Signal B), analyze/context_delta.rs:48-68 (÷4 token estimate), hotspots --rank-by bytes |
output_truncated — harness truncation markers: <system-truncated>, [truncated], output truncated, result truncated, response truncated, truncated to |
tool_results.rs:163-176 |
bloat detection |
content_hash (sha256 of stable-stringified content, 16 hex) |
reader/hash.rs:32-38 |
dedup / edit-revert detection |
call_index (n-th result for the same tool_use_id) + event_index (global order in the transcript) |
tool_results.rs:25-112 |
span tree ordering when timestamps tie |
| `status: running | completed | errored |
| `event_source: tool_result | subagent_notification | queue_event |
Codex out-of-band error back-patching: exec_command_end.exit_code != 0, patch_apply_end.success == false applied to buffered results at task_complete |
codex/incremental.rs:294-319 |
is_error correctness |
Subagent notification → {subagent_session_id, agent_id} on the result |
tool_results.rs:178-240 |
subagent tree |
usage / usage_attribution per result (OpenCode even-split) |
opencode.rs:724-828 |
stays in burn (derived) |
UserTurnRecord blocks: per-user-row `{kind: tool_result |
text, tool_use_id, byte_len, approx_tokens, is_error}` | reader/user_turn.rs |
Also: relayhistory's Claude is_error comes only from the tool_result block; Codex's from exit_code/patch_apply_end.success/mcp_tool_call_end.result.Err — good, but the event row does not say which signal set it.
Scope
- Schema: add to
session_events(tool_result rows)payload_bytes INTEGER,payload_truncated INTEGER,payload_hash TEXT,call_index INTEGER,event_index INTEGER,result_status TEXT,event_source TEXT,error_signal TEXT(tool_result.is_error | exit_code | patch_apply | mcp_err | subagent_status),subagent_session_id TEXT,agent_id TEXT. Migration marker +HYDRATION_PARSER_VERSIONbump. - Claude: compute bytes/hash/truncation over the raw
content(string or array, stable-stringified with sorted keys to match burn'sstable_stringify), before thetextcolumn is filled; maintain per-tool_use_idcall_indexand a transcript-globalevent_indexcounter (persist the last index in the hydration checkpoint so incremental hydration continues the sequence — coordinate with the incremental-hydration issue). - Codex: buffer results per turn and back-patch
error_signal/result_statusattask_completeexactly as burn does;function_call_outputrows getevent_source='function_call_output'. - OpenCode/Grok/Cursor: same columns from their parsers (lands with each parity issue; this issue provides the helper
ToolResultFacts::from_payload(&Value)in core they all call). - Per-user-row blocks: expose
session_user_turns_page(source, session_id)returning, per user message, the ordered[{kind, tool_use_id, byte_len, is_error}]— derivable fromsession_events(no new table) but computed once in core so every consumer agrees.approx_tokensis not computed here (burn's heuristic; a real tokenizer can be added later). SessionEventstruct, napi, TS contracts,docs/session-catalog.mdmatrix.
Acceptance
- Corpus
oversized-bash-output: the tool_result event haspayload_bytesequal to burn's value for the same fixture (assert the number, taken from burn'sreader/claude/tests.rs),payload_truncated = 1. replacement-meta:event_sourceand marker linkage present.- Codex
oversized-shell-output+with-tool-call:error_signal = 'exit_code'on the failing call;result_status = 'errored'. system-subagent-notification: result row withevent_source='subagent_notification',subagent_session_idset.session_user_turns_pageonuser-turn-blocks(Claude, Codex, OpenCode) returns the same block sequence burn'sUserTurnRecordtests assert.
Out of scope
Token estimation, usage attribution to tool calls, cost.
Reactions are currently unavailable
Activity
Correct the writer-boundary, trajectory and tool-result claims
feat(ingest): tool-result fidelity for Cursor, Grok and OpenCode