import type { HostHandle } from './host.js'; /** Real child-exit status, exactly as Node reports it. Codes/signals are * diagnostics only — never policy inputs (design D-4). */ export interface FleetExitStatus { code: number | null; signal: NodeJS.Signals | null; } export interface FleetEntry { /** The broker's supervised pid (never null — a launch with no pid is not * registered). */ pid: number; /** Date.now() at spawn — the respawn throttle's uptime baseline. */ launchedAt: number; /** The ChildProcess-backed handle (host.ts) whose `exited` promise is the * liveness authority. */ handle: HostHandle; /** Respawn-throttle state at registration (consecutive short-lived exits * observed before this launch). The authoritative counter lives in the * daemon implementation and survives the entry's removal at exit. */ consecutiveFailures: number; } export interface FleetRegistry { /** This daemon's epoch id — minted at boot, stamped into every broker's argv * (`--epoch `) so the next daemon's startup census can reap every * prior-epoch broker without adoption. */ epoch(): string; /** Record a just-spawned broker. Sync; THROWS if an entry already exists — * a second launch for a live node is a programming error, never silently * tolerated. */ register(nodeId: string, handle: HostHandle): void; /** The reviveNode double-launch guard: a fleet entry IS liveness. */ has(nodeId: string): boolean; /** Live-fleet checks pass (yield-stall, wedge, fatal-fault). */ get(nodeId: string): FleetEntry | undefined; /** The capacity count (design D-7: capacity = fleet.size(), exact). */ size(): number; entries(): Iterable<[string, FleetEntry]>; /** Drop an entry without policy (terminal exits + close paths). */ forget(nodeId: string): void; /** Wired by `headlessBrokerHost.launch` to the handle's `exited` promise. * Removes the entry (freeing the capacity slot), then enqueues an * exit-policy job on the daemon's serial work lane — policy never runs * inline on the Node event callback (design D-3). */ onChildExit(nodeId: string, status: FleetExitStatus): void; /** Test seam — delivers a synthetic exit through the SAME path as * onChildExit, so fabricated-row tests drive policy without a process. */ deliverExit(nodeId: string, status: FleetExitStatus): void; } /** Inject the daemon's fleet registry. Idempotent for the same instance; * throws on a conflicting rebind (one registry per process, ever). */ export declare function bindFleet(registry: FleetRegistry): void; /** The bound registry. Throws when unbound: broker launches happen only inside * crtrd (or a test harness that explicitly bound an in-process fleet). */ export declare function boundFleet(): FleetRegistry; /** Test-only: clear the process-global binding, mirroring * resetEventSourceForTests. Production processes bind exactly once. */ export declare function resetFleetForTests(): void;