/**
 * LiveTailBuffer — the standby-side persisted live-tail with sequence-dedup
 * (spec §8 G3b). The holder pushes monotonic-sequence flushes of the live
 * conversation tail; the standby applies a flush ONLY if its sequence is
 * lastAppliedSeq + 1, coalescing/holding out-of-order flushes and dropping
 * duplicates — so an at-least-once tunnel redelivery cannot double-append and
 * corrupt the persisted context window (which would make a post-failover reply
 * misrepresent history, violating acceptance criterion 3).
 *
 * Out-of-order flushes are held only until liveTailOutOfOrderTimeoutMs; if the
 * gap is never filled (sender died mid-sequence) the buffer DECLARES THE GAP
 * UNFILLABLE, discards the held flushes, and proceeds with the last contiguous
 * sequence as its resumable tail — bounding the holdout buffer and never
 * wedging the standby behind a gap the at-least-once channel will re-present.
 *
 * Bounded by liveTailMaxBytesPerTopic (drop-oldest). Pure logic — the encrypted
 * transport feeds applyFlush(); persistence is the caller's (an injected sink).
 */
export interface LiveTailFlush {
    seq: number;
    topic: string;
    /** Already-redacted, already-decrypted tail content for this flush. */
    content: string;
    /** Bytes (for the cap); defaults to content length. */
    bytes?: number;
    receivedAtMs?: number;
}
export interface LiveTailBufferConfig {
    outOfOrderTimeoutMs: number;
    maxBytesPerTopic: number;
    now?: () => number;
    logger?: (msg: string) => void;
}
export interface ApplyResult {
    applied: boolean;
    reason: 'applied' | 'duplicate' | 'held-out-of-order' | 'gap-discarded-then-applied';
}
export declare class LiveTailBuffer {
    private readonly cfg;
    private topics;
    constructor(cfg: LiveTailBufferConfig);
    private now;
    private log;
    private topic;
    /**
     * Apply a flush. Returns whether it was applied (or held/dropped). Enforces
     * exactly-once contiguous application: dup dropped, out-of-order held, gap
     * timed-out and discarded.
     */
    applyFlush(flush: LiveTailFlush): ApplyResult;
    /** Discard held flushes whose gap has exceeded the out-of-order timeout. */
    private evictTimedOutGaps;
    /** A periodic tick the caller invokes to time out gaps even without new flushes. */
    tick(topic: string): void;
    private commit;
    /** The resumable tail for a topic (the contiguous applied content). */
    getTail(topic: string): {
        lastAppliedSeq: number;
        content: string;
    };
    getLastAppliedSeq(topic: string): number;
    heldCount(topic: string): number;
}
//# sourceMappingURL=LiveTailBuffer.d.ts.map