/**
 * Leader-only orphan run cleanup.
 *
 * Periodically scans for execution runs stuck in 'running' state whose
 * coordinator orchestrator has crashed. Only the Raft leader runs recovery
 * to prevent multiple orchestrators from racing to recover the same run.
 *
 * Recovery logic:
 * 1. Find runs with status='running' and stale last update (> threshold)
 * 2. Check if the coordinator is still a connected peer
 * 3. If coordinator is disconnected/unknown, this is an orphan run
 * 4. Check job statuses: terminal jobs stay, stuck jobs get marked failed
 * 5. Finalize the run with computed overall status
 */
import type { Kysely } from 'kysely';
import type { Database } from '../db/types.js';
import type { RaftNode } from './raft.js';
import type { PeerRegistry } from './peer-registry.js';
import type { ExecutionTracker } from '../reporting/execution-tracker.js';
interface OrphanRecoveryDeps {
    db: Kysely<Database>;
    raft: RaftNode;
    peerRegistry: PeerRegistry;
    executionTracker: ExecutionTracker;
    /** Scan interval in ms. Default: 60000 (1 minute). */
    scanIntervalMs?: number;
    /** How long a run must be stale before considered orphaned. Default: 5 minutes. */
    staleThresholdMs?: number;
    /** How long a stuck job must have no heartbeat before marking as failed. Default: 3 minutes. */
    jobStuckThresholdMs?: number;
}
export declare class OrphanRecovery {
    private readonly db;
    private readonly raft;
    private readonly peerRegistry;
    private readonly executionTracker;
    private readonly scanIntervalMs;
    private readonly staleThresholdMs;
    private readonly jobStuckThresholdMs;
    private scanTimer;
    constructor(deps: OrphanRecoveryDeps);
    /**
     * Start periodic orphan recovery scans.
     * Only runs recovery logic when this node is the Raft leader.
     */
    start(): void;
    /**
     * Stop periodic orphan recovery scans.
     */
    stop(): void;
    /**
     * Scan for orphaned runs and recover them.
     * Only runs when this node is the Raft leader.
     */
    scanForOrphans(): Promise<void>;
    /**
     * Attempt to recover a single potentially orphaned run.
     */
    private recoverRun;
    /**
     * Check if a coordinator with the given routing key is still connected
     * as a peer in the cluster.
     */
    private isCoordinatorStillConnected;
}
export {};
//# sourceMappingURL=orphan-recovery.d.ts.map