/**
* localObservability — Tier-3 (Debug) observability: RETAIN a live run model,
* render it live, and snapshot it for offline replay.
*
* One handle, two outputs:
* - LIVE — `onLive(graph)` fires per event with a fresh `StepGraph`; hand
* it to your own renderer, or read `handle.getSnapshot()` /
* `handle.boundary` whenever you like.
* - OFFLINE— `getTrace()` (any time) and `onRecorded(trace)` (auto, at run
* exit) freeze the model into a JSON-lossless `Trace`.
*
* This handle is NOT a Lens recorder. `` wants a
* `LensRecorder` — a different object with a different surface — and passing
* this one gives a component with none of the members it calls. To put a run
* in front of Lens, record it and hand the recording over:
*
* const stop = recordRun(agent); // agentfootprint/observe
* await agent.run({ message });
* const recording = stop.toRecording(); // { snapshot, events, structure }
*
* // …in the viewer:
* const { recorder, runner } = observeRecording(recording); // lens
*
*
* Contrast with `enable.observability({ strategy })` (Tier-4 / Monitor), which
* ships each event to a vendor and FORGETS. localObservability KEEPS the model
* so you can look at it — locally, with full content. See
* `docs/design/local-observability-and-pii.md`.
*
* It's a thin wrapper over `enable.flowchart` (the existing live StepGraph) +
* `serializeTrace` (the snapshot). UI-free: returns data, never React.
*/
import type { CombinedRecorder } from 'footprintjs';
import type { EventDispatcher } from '../../events/dispatcher.js';
import type { DomainEvent } from './BoundaryRecorder.js';
import { type FlowchartHandle, type StepGraph } from './FlowchartRecorder.js';
import { type SerializeTraceOptions, type Trace } from './trace.js';
export interface LocalObservabilityOptions {
/** LIVE recording — called with a fresh StepGraph on every event. */
readonly onLive?: (graph: StepGraph) => void;
/** At run exit — called once with the finalized recording (a Trace, auto-serialized) to replay offline. */
readonly onRecorded?: (trace: Trace) => void;
/**
* Default serialize-time redaction, applied to BOTH `onRecorded` and
* `getTrace()` (overridable per `getTrace` call). Runs once per event so PII
* never enters the Trace — see the trust-boundary note in the design doc.
* Pass `redactContent` for a ready-made redactor.
*/
readonly redact?: (event: DomainEvent) => DomainEvent;
/**
* Carry the run's footprintjs snapshot (state + commit log + recorder
* data) in the Trace. Default `false`.
*
* A Trace WITHOUT it draws a chart and a timeline and nothing else: the
* commit axis, ExplainableShell's memory and provenance panels, and
* WhereFrom all read the commit log, which lives in the snapshot and
* appears nowhere in the event log. Turn this on and the Trace can feed
* them.
*
* Off by default because of `redact`, not because of size. `redact` is a
* per-DOMAIN-EVENT function — it cannot reach inside a snapshot, whose
* `sharedState` is the run's raw working memory. Filling this field
* automatically would have widened what a carefully redacted Trace
* exports without a line of code changing at any call site, which is the
* kind of quiet trust-boundary move a library has no business making.
* When you turn it on, redaction for the snapshot half is footprintjs's
* `setRedactionPolicy()` at run time — the run's own policy, applied when
* the values were written.
*
* For a viewer, prefer `recordRun()`: `{ snapshot, events, structure }`
* is the shape the UIs consume, and it is explicit about carrying state.
*/
readonly includeSnapshot?: boolean;
}
/**
* The three things a live runner knows that a recorder cannot see for
* itself. Each one lights a different surface of the stored Trace, and a
* missing one degrades exactly that surface:
*
* - `getStructure` → the chart. Nothing else can draw it.
* - `getSnapshot` → state, commit log, every attached recorder's data.
* - `getCommitCount` → where each boundary sits on the commit axis.
*
* All three are read lazily, at the moment they are needed, because all
* three answer differently before, during and after a run.
*
* @internal Supplied by `RunnerBase.enable.localObservability`.
*/
export interface RunAccess {
/** `() => runner.getSpec().buildTimeStructure` — the static chart. */
readonly getStructure?: () => unknown;
/** `() => runner.getLastSnapshot()` — the footprintjs run snapshot. */
readonly getSnapshot?: () => unknown;
/** `() => runner.getCommitCount()` — sampled live on every boundary. */
readonly getCommitCount?: () => number;
}
/** A `FlowchartHandle` (live) plus `getTrace()` (offline snapshot). */
export interface LocalObservabilityHandle extends FlowchartHandle {
/** Freeze the current model into a JSON-lossless Trace. Safe during or after a run. */
getTrace(options?: SerializeTraceOptions): Trace;
}
/**
* Attach a local-observability handle. `now` is injectable for tests (the
* library otherwise stamps `Date.now()` at serialize time).
*
* @internal Called from `RunnerBase.enable.localObservability`.
*/
export declare function attachLocalObservability(runnerAttach: (recorder: CombinedRecorder) => () => void, dispatcher: EventDispatcher, options?: LocalObservabilityOptions, now?: () => number, access?: RunAccess): LocalObservabilityHandle;