import type { ComponentHealth, ScannerComponentHealthStatus, ScannerSystemState } from "../health/types.js"; import type { ScannerDataProviders } from "./engine/data-providers.js"; import { type ScannerRegistrationSummary } from "./engine/engine.js"; import type { ScannerComposition } from "../runtime/scanner-composition.js"; import type { IdentityEnvelope } from "../telemetry/identity.js"; import type { ExternalScannerIngestRequest, ExternalScannerIngestResult } from "./external-scanner-receiver.js"; import type { ScannerSupervisionRow, ScannerSupervisionSource } from "./supervision.js"; import { type ScannerRuntimeEventMap, type ScannerRuntimeEventName } from "./events.js"; import type { ScannerLogger } from "./protocol/context.js"; import type { ScannerScheduleMode } from "./scanner-definition.js"; import { type ScannerFactory } from "./prepare-scanner-inputs.js"; import type { ReadSignalsFilter, ScanResult, ScannerId, Signal, StrategyRegistration } from "./types.js"; /** Factory that creates one scanner instance for one strategy registration. */ export type { ScannerFactory } from "./prepare-scanner-inputs.js"; /** * Scanner registration input accepted by module bootstrap. * Each entry must build a fresh scanner instance for each strategy registration. */ export type ScannerInput = ScannerFactory; /** Runtime-module bootstrap options for scanner registration and state wiring. */ export interface ScannerRuntimeModuleOptions { stateDir: string; strategy: StrategyRegistration; scanners: ScannerInput[]; /** Explicit scanner dependency composition — required so callers declare the dependency graph upfront. */ composition: ScannerComposition; providers?: ScannerDataProviders; logger?: ScannerLogger; now?: () => number; /** Lazy runtime identity builder; used to stamp per-trace identity at the scanner.run seam. */ identity?: () => IdentityEnvelope; } /** Public control surface exposed by the standalone scanner runtime module. */ export interface ScannerRuntimeModule { /** Starts interval scheduling for all enabled scanner registrations. */ start(): Promise; /** Stops interval scheduling; in-flight runs are allowed to finish. */ stop(): Promise; /** Runs one scanner immediately for one strategy. */ runOnce(address: string, scannerId: ScannerId): Promise; /** Runs one scanner and its configured dependency chain immediately in order. */ runChain(address: string, scannerId: ScannerId): Promise; /** Lists registered scanners and enablement state, optionally filtered by address. */ listScanners(address?: string): Promise; /** Enables one scanner registration for future scheduled/manual runs. */ enableScanner(address: string, scannerId: ScannerId): Promise; /** Disables one scanner registration for future scheduled/manual runs. */ disableScanner(address: string, scannerId: ScannerId): Promise; /** Reads current persisted config for one scanner registration. */ getScannerConfig(address: string, scannerId: ScannerId): Promise; /** Writes validated config for one scanner registration. */ setScannerConfig(address: string, scannerId: ScannerId, config: unknown): Promise; /** Reads the latest committed retained context for one scanner registration. */ getScannerContext(address: string, scannerId: ScannerId): Promise; /** * Accepts one externally supplied signal/context payload for a push-driven * scanner. * * Successful ingests are normalized and committed through the standard * engine lifecycle and retained-context store so runtime consumers observe * the same event and context semantics as built-in scanners. */ ingestExternalScannerData(address: string, request: ExternalScannerIngestRequest): Promise; /** * Records a scaffold-reported tick failure (a scan() that threw, timed out, or * failed to persist state) for a push-driven external scanner into run * telemetry, without an ingest. Resolves by (address, scanner NAME); returns * false for an unknown/ineligible scanner. The failure feeds the same * error-counting path as an interval scanner's thrown run, so * consecutiveErrorCount/lastRunStatus reflect it and push-driven health * derivation can no longer fall open to "healthy" while every tick is failing. */ recordExternalScannerError(address: string, scannerName: ScannerId, error: { type: string; error_type?: string; message?: string; tick_id?: string; }): boolean; /** * Attaches the supervision fact source produced outside the module (intake * liveness clock + process supervisor). The module is the single consumer: * health/state calls read it lazily to join per-external-scanner liveness and * supervisor verdicts onto their rows. Replaces any previously attached source. */ attachSupervisionSource(source: ScannerSupervisionSource): void; /** Queries persisted latest signals. */ querySignals(filter?: ReadSignalsFilter): Promise; /** Subscribes one event listener to runtime lifecycle events. */ on(eventName: Name, listener: (event: ScannerRuntimeEventMap[Name]) => void): void; /** Unsubscribes one event listener from runtime lifecycle events. */ off(eventName: Name, listener: (event: ScannerRuntimeEventMap[Name]) => void): void; /** Lightweight health summary for the scanners component. */ getHealthStatus(): Promise; /** Full configuration/runtime snapshot for the scanners component. */ getSystemState(): Promise; } /** * Creates a standalone scanner runtime module with strategy-scoped scanner instances. * Registered scanners are supplied as factories so the module never reuses mutable scanner objects. */ export declare function createScannerRuntimeModule(options: ScannerRuntimeModuleOptions): ScannerRuntimeModule; /** Health-derivation inputs for one scanner, snapshotted at query time. */ export interface ScannerHealthFacts { enabled: boolean; scheduleMode: ScannerScheduleMode; /** Configured interval; 0 for external (push-driven) scanners. */ intervalSeconds: number; /** Next scheduled interval run (interval scanners only); null otherwise. */ nextRunAt: number | null; /** Wall clock at derivation. */ now: number; telemetry: { inFlight: boolean; lastRunStartedAt: number | null; lastRunFinishedAt: number | null; lastRunStatus: string | null; consecutiveErrorCount: number; }; /** Supervision row for this scanner (external scanners with a source attached). */ supervision?: ScannerSupervisionRow; } /** * Derives one scanner's health, fail-closed for push-driven (external) scanners: * a state that cannot be proven by a successful read or a recent clean tick never * renders "healthy" — "unknown" is the honest answer, "healthy" is a claim. * * Pure and total: identical facts always yield the same verdict. Exported so the * rules table can be pinned directly rather than through module setup. */ export declare function deriveScannerHealthFromFacts(facts: ScannerHealthFacts): ComponentHealth; /** * Builds a scanner composition from scanner factories. * * Convenience wrapper for the programmatic API: instantiates each factory once * to extract definitions, validates the dependency graph, and returns both the * composition and deduplicated factories ready to pass to `createScannerRuntimeModule`. * * Scanner definitions that consume shared artifacts from other scanners must * declare `dependsOn` explicitly — no auto-inference is performed. */ export declare function buildCompositionFromScanners(scanners: ScannerInput[]): { composition: ScannerComposition; scanners: ScannerInput[]; }; //# sourceMappingURL=runtime-module.d.ts.map