import type { AgentSession, RecordedEvent, SessionView, WorkUnit } from '../core/types.js'; export type { RecordedEvent }; /** * The run evidence bundle — everything an operator needs to audit a finished run, * in one downloadable JSON document (`GET /runs/:id/evidence`). * * `events` is core's DURABLE EVENT LOG for the run, read back verbatim. It used to * be re-derived here from the unit records, because the daemon persisted no log of * its own — which meant an exported bundle carried a handful of pseudo-events in a * vocabulary this file invented (`routingDecided`) instead of what actually * happened. Re-derivation cannot recover what it never saw: council deliberation * and votes, gate depth, escalations, fallbacks, and every timestamp were simply * absent, and nothing in the bundle said so. (FINDING-014) * * Nothing was lost by dropping the derived events: `routing`, `assigned_cli`, * `denial_reason`, `phase_status` and `conformance_ref` were their only inputs and * they ride in `units` verbatim already. */ export interface EvidenceBundle { /** When the bundle was assembled (ISO-8601). */ exportedAt: string; /** The run itself, verbatim from the run DTO. */ session: AgentSession; /** The run's units in `ord` order, each with its captured transcript. */ units: EvidenceUnit[]; /** * The run's recorded event history, oldest first — the same frames `/ws` carried * live, each with a capture-time `ts` and an ordering `seq`. */ events: RecordedEvent[]; /** * Why `events` is empty, present ONLY when it is. An empty trail must never be * indistinguishable from a run that genuinely decided nothing — the same posture * `transcriptError` takes for a unit. */ eventsUnavailable?: string; /** * Structured assumptions re-parsed from the transcripts (the external-transform * convention): third-party payload transformations agents relied on. Entries with * `known: false` are needs-research placeholders awaiting human review. */ assumptions: EvidenceAssumption[]; } /** One external-transform assumption parsed from a unit transcript. */ export interface EvidenceAssumption { ord: number; kind: 'external-transform'; library: string; transform: string; known: boolean; detail: string; } /** A unit as it appears in the bundle: the run DTO's unit plus its captured transcript. */ export interface EvidenceUnit extends WorkUnit { /** The unit's captured transcript, or `null` when core captured none. */ transcript: string | null; /** * Why the transcript is `null` when the read itself failed — present ONLY on * failure, so a missing transcript is never silently indistinguishable from a * unit that legitimately produced no output. */ transcriptError?: string; } /** Loads one unit's captured transcript (the adapter's `workOutput`). */ export type TranscriptLoader = (coreUnitId: string) => Promise; /** * Loads a run's recorded event history (the adapter's `runEvents`). * * `null` means the engine has no event-log binding at all — a capability gap, not an empty run. * The adapter returns it rather than `[]` so this module can say which of the two happened. */ export type EventLoader = (runId: string) => Promise; /** * The id core keys the transcript store by. Unit ids are already `:`; * fall back to the free-text `u` form for any unit that lacks the prefix. * * EXPORTED so `/runs/:id/units/:unitKey/output` calls THIS rather than re-deriving the * key from the caller's path segment. It used to be private and the route built its own * `:` string from whatever the operator typed, which meant the two surfaces * could disagree about which unit a key names — and did: a key the bundle resolved * answered `null` on the endpoint (FINDING-006). One derivation, from the unit record. */ export declare function coreUnitId(runId: string, unit: WorkUnit): string; /** * Assemble a run's evidence bundle. * * Every read degrades in place rather than failing the export: an unreadable * transcript becomes `transcript: null` + `transcriptError` on that unit, and an * unreadable event history becomes `events: []` + `eventsUnavailable`. A partial * bundle that says which part is missing beats no bundle at all — but it must say * so, or the gap reads as a fact about the run. */ export declare function buildEvidenceBundle(view: SessionView, loadTranscript: TranscriptLoader, loadEvents: EventLoader): Promise; /** * Parse external-transform markers from one transcript — mirrors wicked-core's * `assumptions::parse` (same grammar, same malformed→needs-review posture) so the * bundle matches what the live event stream reported. */ export declare function parseAssumptions(ord: number, transcript: string | null): EvidenceAssumption[]; /** * `-evidence.json`, safe to interpolate into a `Content-Disposition` * header. Run ids are client-supplied (`sessionId` on launch), so anything * outside the filename-safe set is folded to `_` — a quote or CR in a run id * must never break out of the header. */ export declare function evidenceFilename(runId: string): string; //# sourceMappingURL=evidence.d.ts.map