/** * causalEvidenceRecorder — the evidence bridge (backlog Phase-1 #5). * * Harvests, DURING the run, everything a causal snapshot needs beyond * (query, finalContent) — from events the engine already fires: * * stream.tool_start/tool_end → ToolCallRecord (name, args, resultPreview, errored) * stream.llm_end → tokenUsage accumulation + iteration high-water * agent.turn_start/turn_end → durationMs (+ authoritative totals when seen) * FlowRecorder.onDecision → DecisionRecord with footprintjs decide()/select() * operator-level evidence (rule, conditions, chosen) * context.evaluated routing → DecisionRecord per skill the graph routed to * * Pattern: CombinedRecorder (Convention 1 — single purpose: evidence * accumulation); per-turn reset anchored on `agent.turn_start` * (Convention 4 — executor `clear()` resets between runs; same- * executor pause/resume PRESERVES pre-pause evidence by design). * PII note: tool args/results and decide() evidence persist into snapshots. * footprintjs `RedactionPolicy.emitPatterns` redacts the emit channel * BEFORE this recorder IF the consumer configures one on the executor * — the Agent does NOT configure one by default. Values are bounded * (`maxPreviewChars` for results, `maxFieldChars` for args/evidence); * treat the snapshot store as PII-bearing and protect it accordingly. * * The Agent attaches this automatically when a CAUSAL memory is mounted and * threads `collect` into the memory write mount (`evidenceSource`) — so * `writeSnapshot` persists real evidence instead of zeros. */ import type { FlowDecisionEvent, FlowSelectedEvent } from 'footprintjs'; import type { DecisionRecord, ToolCallRecord } from './types.js'; /** What the bridge delivers to `writeSnapshot` for one run. */ export interface RunEvidence { readonly iterations: number; readonly decisions: ReadonlyArray; readonly toolCalls: ReadonlyArray; readonly durationMs: number; readonly tokenUsage: { readonly input: number; readonly output: number; }; } export interface CausalEvidenceRecorderOptions { /** Recorder id (default 'causal-evidence'). */ readonly id?: string; /** Max chars kept of each tool result preview. Default 200. */ readonly maxPreviewChars?: number; /** Max serialized chars kept of tool ARGS and decision EVIDENCE (the * PII-dense fields). Oversized values are replaced by a truncated * preview marker. Default 2000. */ readonly maxFieldChars?: number; } export interface CausalEvidenceRecorderHandle { readonly id: string; /** Snapshot the evidence accumulated for the CURRENT run. */ collect(): RunEvidence; clear(): void; onEmit(event: { name: string; payload: unknown; }): void; onDecision(event: FlowDecisionEvent): void; onSelected(event: FlowSelectedEvent): void; } /** Build the evidence-harvesting recorder. Attach via `.recorder(rec)` (the * Agent does this automatically for CAUSAL memories). */ export declare function causalEvidenceRecorder(options?: CausalEvidenceRecorderOptions): CausalEvidenceRecorderHandle;