/** * Darwin — Metrics Sink (v0.14.0) * * Every evolution decision as a typed event. The loop emits; you decide where * it goes — a JSONL file (built in, zero deps), Prometheus, OpenTelemetry * (see `examples/otel-bridge.ts`), or your own dashboard. * * Design rules, same as the rest of Darwin: * - Zero hard deps. The sink is INJECTED (`DarwinLoopDeps.metrics`) or * wired from the environment (`DARWIN_METRICS_JSONL=path`). * - Fire-and-forget. A throwing/rejecting sink must never break the * evolution loop — {@link emitMetric} swallows sink errors by contract. * - Events are facts, not aggregates. Counters/histograms are the * consumer's job; Darwin reports what happened, with enough payload to * build any aggregate downstream. */ export type DarwinMetricEventType = 'run_recorded' | 'rollback' | 'ab_test_started' | 'ab_test_completed' | 'ab_test_timeout' | 'evolution_skipped'; export interface DarwinMetricEvent { /** What happened. */ type: DarwinMetricEventType; /** Which agent it happened to. */ agent: string; /** ISO timestamp, stamped at emit time. */ at: string; /** * Event payload — intentionally loose. Stable keys per type (see the emit * sites in `evolution/loop.ts`): scores, versions, winner, failures, reason. */ data: Record; } export interface MetricsSink { /** Receive one event. May be sync or async; errors are swallowed by {@link emitMetric}. */ emit(event: DarwinMetricEvent): void | Promise; } /** * Emit `event` on `sink` without ever throwing — sync throws are caught, * async rejections attached. The evolution loop calls THIS, never * `sink.emit` directly, so a broken sink can not fail a run or an A/B * decision. No sink → no-op. */ export declare function emitMetric(sink: MetricsSink | undefined, type: DarwinMetricEventType, agent: string, data?: Record): void; /** * Append-only JSONL file sink — one event per line. The zero-dep default: * `tail -f` it, ship it with any log collector, or load it into a notebook. * * Writes are synchronous appends (events are small and rare — a handful per * agent run); the parent directory is created on first construction. */ export declare class JsonlMetricsSink implements MetricsSink { private readonly path; constructor(path: string); emit(event: DarwinMetricEvent): void; } /** * Build the sink the environment asks for, or `undefined` for none. * `DARWIN_METRICS_JSONL=` → {@link JsonlMetricsSink} at that path. * Invalid paths fail loudly HERE (at wiring time), not silently per event. */ export declare function metricsSinkFromEnv(env?: NodeJS.ProcessEnv): MetricsSink | undefined; //# sourceMappingURL=sink.d.ts.map