/**
 * Cross-Machine Seamlessness — config resolution + invariant validation.
 *
 * Spec: docs/specs/CROSS-MACHINE-SEAMLESSNESS-SPEC.md §9 (Tunability).
 *
 * Resolves the optional `multiMachine` seamlessness knobs to concrete values
 * with sane 2-machine-personal-use defaults, auto-derives the standby pull
 * cadence, and enforces the cross-knob invariants. A violating config is
 * REJECTED with a clear message rather than degrading silently — so a user
 * widening `ingressHeartbeatMs` (which widens `leaseTtlMs`) cannot quietly
 * invalidate the RPO bound the spec promises (§3).
 */
import type { MultiMachineConfig } from './types.js';
/**
 * The mesh protocol version this build speaks. A machine below this version
 * is ineligible for the awake lease during a seamless handoff (spec §11
 * partial-migration safety). Bump only on a breaking coordination change.
 *
 * v2 (WS1.2, MULTI-MACHINE-SEAMLESSNESS-SPEC): the `drain` mesh verb — an
 * active-topic transfer now drains the owner's live session through an
 * authorized, epoch-bound signal. Verb-level skew is additionally handled by
 * the 501/no-handler degrade (an old owner falls back to today's
 * idle-closeout-only transfer), so mixed pools keep working; the version
 * gates only lease eligibility during a handoff window.
 */
export declare const SEAMLESSNESS_PROTOCOL_VERSION = 2;
/** Fully-resolved seamlessness knobs (every field concrete). */
export interface ResolvedSeamlessnessConfig {
    ingressHeartbeatMs: number;
    registrySyncDebounceMs: number;
    standbyPullIntervalMs: number;
    /** Cross-Machine Coherence — active lease-PULL cadence over the tunnel. */
    leasePullIntervalMs: number;
    failoverThresholdMs: number;
    leaseTtlMs: number;
    liveTailTransport: 'tunnel' | 'git';
    liveTailMaxStalenessMs: number;
    liveTailPushRateMs: number;
    liveTailOutOfOrderTimeoutMs: number;
    liveTailMaxBytesPerTopic: number;
    handoffAckTimeoutMs: number;
    minHandoffIntervalMs: number;
    splitBrainEscalationCooldownMs: number;
    handoffBar: 'near-instant' | 'relaxed';
    maxProcessingMs: number;
    /**
     * Exactly-once ingress (spec §8 G3a). When true, the inbound forward path
     * gates each message through the MessageProcessingLedger (dedup redeliveries)
     * and the outbound reply path commits reply_committed. DEFAULT false — ships
     * dark; flip ON only after a live test-as-self confirms no false-drops, since
     * this is the most critical path (every user message).
     */
    exactlyOnceIngress: boolean;
    protocolVersion: number;
}
export declare class SeamlessnessConfigError extends Error {
    constructor(message: string);
}
/**
 * Resolve the failover threshold (ms) from the existing config field.
 * `failoverTimeoutMinutes` is the canonical knob; default 15 min.
 * Nullish-coalescing (not ||) so an explicit 0 isn't clobbered — but 0 is
 * itself invalid and caught by validation.
 */
export declare function resolveFailoverThresholdMs(mm?: MultiMachineConfig): number;
/**
 * Resolve all seamlessness knobs to concrete values. Auto-derives
 * `standbyPullIntervalMs` (failoverThresholdMs/4) and the tail/lease-linked
 * defaults. Does NOT validate — call validateSeamlessnessInvariants() after.
 */
export declare function resolveSeamlessnessConfig(mm?: MultiMachineConfig): ResolvedSeamlessnessConfig;
/**
 * Validate the cross-knob invariants (spec §9). Returns the list of
 * violations (empty = valid). Callers that want hard-rejection use
 * assertSeamlessnessInvariants().
 *
 * Invariants:
 *  1. standbyPullIntervalMs < failoverThresholdMs / 3
 *     — a standby must pull often enough to notice a dead holder well
 *       before the failover threshold, or failover races stale data.
 *  2. standbyPullIntervalMs < leaseTtlMs
 *     — a standby must refresh its git-committed epoch view at least once
 *       per lease lifetime, or it decides max(tunnel,git) on a stale git floor.
 *  3. liveTailPushRateMs ≤ liveTailMaxStalenessMs
 *     — the holder must push tail flushes at least as often as the RPO bound,
 *       or the promised RPO is unachievable.
 *  Plus basic positivity (a 0/negative cadence is never valid).
 */
export declare function validateSeamlessnessInvariants(c: ResolvedSeamlessnessConfig): string[];
/**
 * Resolve + validate in one step, throwing SeamlessnessConfigError on any
 * invariant violation. Use at server startup so a bad config is rejected
 * loudly rather than degrading silently.
 */
export declare function assertSeamlessnessInvariants(mm?: MultiMachineConfig): ResolvedSeamlessnessConfig;
//# sourceMappingURL=seamlessnessConfig.d.ts.map