/** * manager.ts, the trigger supervisor. * * Owns all three watcher kinds over one spine: the same backoff ladder, the * same strike breaker, the same persisted ring buffer, the same recovery * housekeeping. The kinds differ only in how an observation is produced, * a probe, a matched stream batch, or a child process ending. * * Everything with an effect is injected (probe I/O, process host, stream host, * action executor, clock), so the policy in this file is exercisable end to end * without a network, a subprocess or a real daemon. */ import { type RegisterGrantInput } from './grants.js'; import type { TriggerActionGrant, TriggerRecord, TriggerRecoveryReport, TriggerRunRecord } from './types.js'; import { type TriggerManagerOptions } from './manager-types.js'; export * from './manager-types.js'; export declare class TriggerManager { private readonly options; private readonly records; private readonly grants; private readonly streams; private eventLog; private policy; private retention; private readonly daemonBootId; private sweepTimer; private supervisionTimer; private inFlight; private loaded; private lastRecovery; constructor(options: TriggerManagerOptions); private now; private get config(); private requireEnabled; /** The last recovery/sweep report, what was reaped, and why. */ get recoveryReport(): TriggerRecoveryReport | null; get bootId(): string; /** * Loads persisted state, content-validates it, sweeps it, and reconciles any * on-exit trigger left over from a previous daemon boot. Safe to call twice. */ load(): TriggerRecoveryReport; /** * Any on-exit trigger whose tracked process belongs to a previous daemon boot * fires exactly once with an explicit unknown / daemon-restart state. A * trigger that silently evaporated would be worse than one that fires with * honest uncertainty, so this deliberately never adopts the old pid. */ private reconcileOnExitAfterRestart; /** * The daemon lifecycle entry point: recover persisted state, start the * recurring housekeeping sweep, and start the supervision tick that polls * supervised children and runs due condition checks. * * Without this, on-exit triggers would only fire if something happened to * call pollProcesses(), which is the "correct code nothing calls" shape. * Safe to call when the family is disabled: the tick body no-ops on the live * config, so flipping the flag on later starts real work without a restart. */ start(): TriggerRecoveryReport; /** One supervision pass: reap finished children, then run due checks. */ supervisionTick(): Promise; /** Starts the recurring housekeeping sweep. A daemon that only sweeps at boot never sweeps. */ startSweep(): void; stopSweep(): void; /** Reap + bound + disclose. Idempotent; safe to run alongside another process. */ sweep(): TriggerRecoveryReport; /** Stops timers and supervised streams. Persisted state is left intact. */ shutdown(): void; private persist; registerGrant(input: RegisterGrantInput): TriggerActionGrant; listGrants(): TriggerActionGrant[]; create(input: unknown): Promise; /** * Refuses at creation time, not at fire time. A trigger pinned to a grant * that does not exist would sit there looking healthy until the moment it * mattered, so the pin is verified while a person is still present. */ private assertActionIsFireable; list(): TriggerRecord[]; get(id: string): TriggerRecord | null; /** Run history for one trigger, newest last. */ history(id: string): readonly TriggerRunRecord[]; /** Cancels a trigger. An on-exit trigger's supervised child is terminated. */ cancel(id: string): TriggerRecord | null; remove(id: string): boolean; /** Explicit breaker reset. The breaker never closes on its own. */ reset(id: string): TriggerRecord | null; /** Runs every condition trigger that is due. Respects the concurrency cap. */ tick(): Promise; /** Runs one condition check now, ignoring its schedule. */ runCheck(id: string): Promise; private applyObservation; private applyCheckFailure; private appendEvent; private fireAction; private defaultPrompt; private executeAction; private startOnExit; /** * Polls supervised on-exit children and fires the ones that finished. * Exactly once: the record moves to `fired` under the same synchronous check * that decides to fire, so a second poll cannot fire it again. */ pollProcesses(): Promise; /** * The single on-exit fire path. Claims the record by moving it out of * `running` BEFORE awaiting the action, so a concurrent poll or a * daemon-restart reconciliation cannot produce a second payload. */ private fireOnExit; private startStream; private drainStream; /** The narrow view manager-streams.ts operates through. */ private streamOwner; } //# sourceMappingURL=manager.d.ts.map