export interface StreamTicket {
    ticket: string;
    /** The peer this ticket was minted FOR (must match the WS upgrade's authed sender). */
    forMachineId: string;
    /** ms epoch when the ticket stops being valid. */
    expiresAtMs: number;
}
export type ConsumeResult = {
    ok: true;
    forMachineId: string;
} | {
    ok: false;
    reason: 'unknown' | 'expired' | 'already-consumed' | 'wrong-machine';
};
export interface StreamTicketStoreDeps {
    /** Absolute path to the persistence file. */
    filePath: string;
    now: () => number;
    /** Mint a fresh opaque ticket string (crypto-random in prod; deterministic in tests). */
    mintId: () => string;
    /** Ticket lifetime (ms). Default 60_000. */
    ttlMs?: number;
    /** How long a CONSUMED/expired record is retained for replay rejection before GC (ms). Default 1h. */
    retentionMs?: number;
    logger?: (line: string) => void;
}
export declare class StreamTicketStore {
    private readonly d;
    private tickets;
    private loaded;
    constructor(d: StreamTicketStoreDeps);
    private ttl;
    private retention;
    private ensureLoaded;
    /** Mint a single-use ticket for `forMachineId`. */
    mint(forMachineId: string): StreamTicket;
    /**
     * Consume a ticket presented on the WS upgrade. The ticket is an unguessable
     * single-use bearer credential minted ONLY to an authenticated peer (over the
     * machine-authed `pool-stream-ticket` mesh verb), so possession authorizes;
     * the consumed `forMachineId` (bound at mint) tells the server which peer it
     * is — never an unverified claim from the upgrade. `presentedBy` is OPTIONAL
     * defense-in-depth: when the upgrade independently proves identity, the ticket
     * must also have been minted for exactly that machine (rejects a stolen ticket
     * replayed by a different authenticated machine).
     */
    consume(ticket: string, presentedBy?: string): ConsumeResult;
    /** Drop expired-past-retention and consumed-past-retention records. */
    private gc;
    /** Count of live (unconsumed, unexpired) tickets — tests/observability. */
    liveCount(): number;
    private persist;
}
//# sourceMappingURL=StreamTicketStore.d.ts.map