/**
 * RegistrySyncDebouncer — G2 automated state sync (durable half).
 *
 * Spec: docs/specs/CROSS-MACHINE-SEAMLESSNESS-SPEC.md §8 G2.
 *
 * The Phase-0 root cause: a running server changed its registry (role/lease)
 * but NOTHING pushed that change to git, so cross-machine state only ever
 * propagated by hand. This component closes that: a marked-dirty registry is
 * debounced and committed+pushed to git — but ONLY the authoritative machine
 * (lease holder / awake) writes durable authority-bearing state (single-writer,
 * removing the O(N) thundering-herd of every machine pushing a corrected
 * registry).
 *
 * This is the DURABLE path only. High-frequency liveness/heartbeat (ephemeral)
 * never comes through here — it travels over the tunnel and stays out of git
 * history, so steady-state healthy operation produces ~0 commits (the
 * ephemeral-vs-durable split, spec §Design Principles).
 *
 * Push contention: commitAndPush performs `git push` which fails (returns
 * false) on a non-fast-forward — we never force-push. Repeated failures past a
 * threshold emit a sync-health signal so the lease layer can self-suspend
 * ingress (a machine that cannot prove it is visible must not serve). The
 * pull/rebase reconciliation itself lives in the periodic GitSync.sync cycle.
 */
export interface SyncHealthState {
    healthy: boolean;
    consecutiveFailures: number;
    lastError?: string;
    lastPushAt?: string;
    lastAttemptAt?: string;
}
export interface RegistrySyncDeps {
    /** Commit + push the given paths. Returns true if a commit was pushed. */
    commitAndPush: (message: string, paths: string[]) => boolean;
    /** Absolute path of the registry file to stage. */
    registryAbsPath: string;
    /**
     * Single-writer gate: only flush when THIS machine has authority to write
     * durable registry state (holds the lease / is awake). A standby marking
     * dirty is a no-op push (it still updates its own liveness elsewhere).
     */
    isAuthoritative: () => boolean;
    /** Debounce window (registrySyncDebounceMs). */
    debounceMs: number;
    /** Failures before the sync-health signal flips unhealthy. Default 3. */
    maxConsecutiveFailures?: number;
    /** Sync-health signal consumer (lease layer self-suspends ingress on unhealthy). */
    onSyncHealth?: (s: SyncHealthState) => void;
    logger?: (msg: string) => void;
    now?: () => number;
}
export declare class RegistrySyncDebouncer {
    private readonly deps;
    private readonly maxFailures;
    private timer;
    private pendingReasons;
    private flushing;
    private health;
    private stopped;
    constructor(deps: RegistrySyncDeps);
    private now;
    private log;
    /**
     * Mark the registry as needing a durable push. Debounced — many rapid marks
     * within the window coalesce into a single commit (coarse, not per-tick).
     */
    markRegistryDirty(reason: string): void;
    /**
     * Flush immediately (also used by stop()). Returns true if a commit was
     * pushed. A non-authoritative machine returns false without pushing
     * (single-writer). Re-entrancy guarded.
     */
    flush(): Promise<boolean>;
    getHealth(): SyncHealthState;
    stop(): void;
}
//# sourceMappingURL=RegistrySyncDebouncer.d.ts.map