import type { ReadableSpan, SpanExporter } from '../types.js'; import { type AtRestPolicy } from '../../at-rest-persistence.js'; /** Configuration for LocalLedgerExporter. */ export interface LocalLedgerConfig { /** * Absolute path to the output file (e.g. `/home/user/.goodvibes/telemetry/spans.jsonl`). */ readonly filePath: string; /** * Maximum file size in bytes before rotation. * When the file exceeds this size, it is renamed to `.1` and a * fresh file is started. Defaults to 10 MB. */ readonly maxFileSizeBytes?: number | undefined; /** * Optional path for the typed event ledger file. * When provided, `recordEvent()` appends `LedgerEntry` lines here. * Defaults to `.ledger.jsonl`. */ readonly ledgerFilePath?: string | undefined; /** * At-rest redaction + retention policy for the span and ledger files. When * omitted, the honest default applies (redaction ON; retention generous but * bounded). Wire from config via resolveAtRestPolicy(configManager.get). */ readonly atRestPolicy?: AtRestPolicy | undefined; } /** * A single typed event entry in the replay ledger. * * Each entry captures the run identifier, a monotonically increasing * revision counter, the event name, payload, and wall-clock timestamp. * The revision counter is used by the deterministic replay engine for * seek and stepwise playback. */ export interface LedgerEntry { /** Run identifier, groups entries belonging to the same recorded run. */ readonly runId: string; /** Monotonically increasing revision counter within the run (starts at 1). */ readonly rev: number; /** Event name recorded in the typed runtime ledger. */ readonly eventName: string; /** Full event payload, JSON-serialisable. */ readonly payload: unknown; /** Wall-clock timestamp (epoch ms) when the event was recorded. */ readonly ts: number; } /** * LocalLedgerExporter, writes spans as JSON lines to a rotating file. * * Usage: * ```ts * const exporter = new LocalLedgerExporter({ * filePath: '/home/user/.goodvibes/telemetry/spans.jsonl', * maxFileSizeBytes: 5 * 1024 * 1024, * }); * ``` */ export declare class LocalLedgerExporter implements SpanExporter { readonly name = "local-ledger"; private readonly filePath; private readonly maxFileSizeBytes; private readonly ledgerFilePath; private readonly atRestPolicy; constructor(config: LocalLedgerConfig); /** * Export a batch of spans as JSON lines. * * Failures are logged and isolated from callers so exporter I/O cannot break * runtime work. */ export(spans: ReadableSpan[]): Promise; /** * Record a typed event entry to the ledger file. * * Used by the deterministic replay engine to build a per-run event log. * Failures are logged and isolated from callers. * * @param entry - The ledger entry to append. * * @remarks * This method is used by the event recording integration that * wires typed runtime events to the ledger. The integration subscribes to the * runtime bus at session start and calls `recordEvent()` for each event that should * be included in the replay ledger. See `DeterministicReplayEngine.load()` * for the consumer side of this pipeline. */ recordEvent(entry: LedgerEntry): void; /** * Read all ledger entries for a given run. * * Parses the ledger file line-by-line. Malformed lines are skipped. * Returns entries sorted by revision (ascending). * * @param runId - The run to retrieve entries for. * @returns Ordered ledger entries for the run. */ readRunEntries(runId: string): LedgerEntry[]; /** * List all run IDs recorded in the ledger. */ listRunIds(): string[]; /** Flush is a no-op for synchronous append-only writes. */ flush(): Promise; /** Shutdown is a no-op for file-based exports. */ shutdown(): Promise; /** * Rotate the log file if it exceeds the configured maximum size. * Renames the current file to `.1` (overwrites any existing `.1`). */ /** * Retention enforcement point (called on every export, alongside rotation). * Applies the age + total-size caps across the span file, its rotated backup, * and the ledger file, deleting oldest-first. The freshly-written active files * carry the most recent mtime, so they are only ever reclaimed as a last * resort under extreme size pressure, a rotated backup goes first. */ private _enforceRetention; private _rotateIfNeeded; } //# sourceMappingURL=local-ledger.d.ts.map