/**
 * UpdateRestartHandshake — version-skew restart verification.
 *
 * PROBLEM (codex-instar audit Item 4): AutoUpdater currently notifies the
 * user "Just updated to vX. Restarting..." BEFORE the restart actually
 * takes effect. If the restart fails (binary mismatch, supervisor stall,
 * any reason the new process doesn't come up on the new code), the user
 * has been told the update is live when it isn't. Operators assume fixes
 * are deployed; they aren't.
 *
 * SOLUTION: A two-phase handshake.
 *
 * Phase 1 (before restart, inside the OLD process):
 *   AutoUpdater calls writePendingHandshake({
 *     expectedVersion: newVersion,
 *     previousVersion: currentVersion,
 *     deferredNotification: "Just updated to vX. ...",
 *   }).
 *   The notification is NOT sent yet — it's stashed in the handshake file.
 *
 * Phase 2 (server startup, inside the NEW process):
 *   On boot, verifyRestartHandshake() reads the file and compares
 *   ProcessIntegrity.runningVersion against expectedVersion.
 *   - Match: emit the deferredNotification (now truthful), clear the file.
 *   - Mismatch: emit an honest failure notification ("Update applied but
 *     restart didn't take effect — still running stale vY") and increment
 *     retryCount. After N failures, escalate via IMMEDIATE channel.
 *
 * File: `<stateDir>/state/restart-handshake.json`
 * Persistence: survives process restart (that's the whole point).
 */
export interface HandshakeState {
    /** Version we expected to be running after the restart we triggered. */
    expectedVersion: string;
    /** Version we were on before applying the update. */
    previousVersion: string;
    /** Notification text the OLD process WOULD have sent immediately; we
     * deferred it so we could only send after verifying the restart took. */
    deferredNotification: string;
    /** When the handshake was written (ISO). */
    triggeredAt: string;
    /** Boot-count check attempts. Incremented each time the NEW process
     * comes up still showing runningVersion !== expectedVersion. */
    retryCount: number;
}
export interface HandshakeWriteInput {
    expectedVersion: string;
    previousVersion: string;
    deferredNotification: string;
}
export declare class UpdateRestartHandshake {
    private readonly filePath;
    constructor(stateDir: string);
    /**
     * Phase 1 — called in the OLD process before requesting a restart.
     * Atomic write: tmp + rename.
     */
    writePendingHandshake(input: HandshakeWriteInput): void;
    /**
     * Phase 2 — called in the NEW process at server startup.
     * Returns null when no handshake is pending.
     */
    readPendingHandshake(): HandshakeState | null;
    /** Phase 2 — successful verification, clear the marker. */
    clearHandshake(): void;
    /**
     * Phase 2 — failed verification. Bump retryCount and persist.
     * Returns the new retryCount.
     */
    bumpRetryCount(): number;
}
/**
 * Outcome enum from verifyRestartHandshake — callers branch on this to
 * decide what to send and at what priority.
 */
export type HandshakeVerificationOutcome = {
    kind: 'no-handshake';
} | {
    kind: 'verified';
    expectedVersion: string;
    previousVersion: string;
    deferredNotification: string;
} | {
    kind: 'failed';
    expectedVersion: string;
    previousVersion: string;
    runningVersion: string;
    retryCount: number;
    escalate: boolean;
};
/**
 * Verify a pending handshake at server startup.
 *
 * - No handshake → `{kind: 'no-handshake'}`. Caller does nothing.
 * - runningVersion === expectedVersion → `{kind: 'verified', ...}`.
 *   Caller sends the deferred notification and clears the handshake.
 * - runningVersion !== expectedVersion → `{kind: 'failed', ...}`.
 *   `bumpRetryCount` is called automatically. `escalate: true` when
 *   retryCount has reached the escalation threshold (default 2 — first
 *   boot logs the failure, second boot escalates loud).
 *
 * The function does NOT clear the handshake on failure; the marker
 * persists so the NEXT boot can also verify (and escalate sooner).
 */
export declare function verifyRestartHandshake(opts: {
    handshake: UpdateRestartHandshake;
    runningVersion: string;
    escalationThreshold?: number;
}): HandshakeVerificationOutcome;
//# sourceMappingURL=UpdateRestartHandshake.d.ts.map