/** * The supervised-scanner substrate's telemetry bridge: it translates the vendor-neutral * `LongRunningSupervisor "event"` channel into our catalog events and health metrics, the only * catalog/metric-aware seam (the supervisor stays vendor-neutral). {@link buildScannerLifecycleEvent} * maps the channel into the `scanner.*` catalog family so the boundary — child spawn/exit/crash-loop/ * silence-kill — is observable (graceful `stopped` is intentionally not catalogued; it is covered by * `runtime.stopped`). {@link buildScannerLaunchFailedEvent} covers the launcher-side failures that * never reach the supervisor's channel: a scanner that fails to wire up at all, or fails to re-mint * its id on relaunch. {@link recordScannerLifecycleMetrics} is the metric side — the restart counter * and degraded gauge that page an operator without a trace or log scan. * * The builders are pure `(input) => EmittableEvent | null`; the launcher emits the result through * `emitEvent`'s guard, so a throwing build or a telemetry failure can never disturb the supervisor's * run loop or the wiring. The metric recorder is a guarded side-effect (the instruments swallow throws). */ import type { LongRunningEvent } from "../../runtime/supervisor/long-running-supervisor.js"; import { EVENT_NAME } from "../../utils/event-catalog.js"; import type { EmittableEvent } from "../../actions/event-derivation.js"; /** The catalog names this bridge emits. */ type ScannerLifecycleName = typeof EVENT_NAME.scannerSpawned | typeof EVENT_NAME.scannerExited | typeof EVENT_NAME.scannerRestarted | typeof EVENT_NAME.scannerDegraded | typeof EVENT_NAME.scannerRecovered | typeof EVENT_NAME.scannerSilenceKilled | typeof EVENT_NAME.scannerOrphanSwept; /** The scanner-instance identity the launcher pins onto every lifecycle event. */ export interface ScannerLifecycleContext { /** The recipe-declared scanner name (stable across relaunch). */ scannerName: string; /** The current ephemeral scanner id (re-minted on relaunch — read at emit time). */ scannerId: string; /** The owning supervisor's id — the join key to its free-text logs. */ supervisorId: string; /** Strategy wallet; omitted/empty → not stamped. */ wallet?: string; } /** * Map one supervisor lifecycle event to its event-log record, or `null` for `stopped` (not * catalogued). The switch is exhaustive over {@link LongRunningEvent}: a new transition added to the * union without a case here is a compile error. */ export declare function buildScannerLifecycleEvent(event: LongRunningEvent, ctx: ScannerLifecycleContext): EmittableEvent | null; /** * Record the metric side of a lifecycle event: the `scanner.restarts` counter on each restart, and * the `scanner.degraded` up/down gauge across the crash-loop edge (+1 on `degraded`, −1 on * `recovered`). A teardown while degraded never emits `recovered`, so `stopped` carries `wasDegraded` * and balances the gauge with its own −1 — otherwise a partial teardown (hot-uninstall, single-scanner * stop) would leak a permanent +1 for that name+wallet. Dimensioned by the stable scanner name + * wallet, not the ephemeral id. Other transitions carry no metric. */ export declare function recordScannerLifecycleMetrics(event: LongRunningEvent, ctx: ScannerLifecycleContext): void; /** A launcher-side wiring failure — the scanner produces no signals. */ export interface ScannerLaunchFailure { scannerName: string; /** `wire` (initial launch) | `remint` (relaunch id rotation). */ phase: "wire" | "remint"; wallet?: string; /** The old id + owning supervisor — known only on a `remint` failure. */ scannerId?: string; supervisorId?: string; error: unknown; } /** Build the `scanner.launch_failed` event (warn) for a launch/remint failure, with the exception attached. */ export declare function buildScannerLaunchFailedEvent(failure: ScannerLaunchFailure): EmittableEvent; export {}; //# sourceMappingURL=supervisor-events.d.ts.map