/**
 * Per-key brute-force protection limiter.
 *
 * Semantics:
 *   - `fail(key)` records a failed attempt; reaching `maxFailures` within
 *     `windowMs` triggers a `blockDurationMs` lockout.
 *   - `succeed(key)` clears all state for the key (a successful auth wipes the
 *     bucket so legitimate users aren't punished for prior typos).
 *   - `check(key)` is read-only — returns the current block status.
 *   - Failures from the same key within `burstCoalesceMs` collapse to a single
 *     attempt. This absorbs SPA fan-out / SDK auto-retry storms without
 *     weakening protection: a deliberate attacker is rate-limited to ~1
 *     attempt/s per key, still astronomically slow against any token of
 *     meaningful entropy.
 *
 * Pure counter — no policy knowledge (loopback exemption, key formatting,
 * etc. all live in the policy layer that calls into this limiter).
 */
import { type Clock } from './keyed-store.js';
export type FailureLimiterConfig = {
    maxFailures: number;
    windowMs: number;
    blockDurationMs: number;
    /** @default 1000 */
    burstCoalesceMs?: number;
    /** Retain idle keys for this long. @default `windowMs + blockDurationMs` */
    staleAfterMs?: number;
    clock?: Clock;
};
export type FailureCheck = {
    blocked: false;
} | {
    blocked: true;
    retryAfterSec: number;
};
export declare class FailureLimiter {
    private readonly store;
    private readonly clock;
    private readonly maxFailures;
    private readonly windowMs;
    private readonly blockDurationMs;
    private readonly burstCoalesceMs;
    constructor(cfg: FailureLimiterConfig);
    check(key: string): FailureCheck;
    fail(key: string): void;
    succeed(key: string): void;
    /** @internal Test hook. */
    resetForTests(): void;
    destroy(): void;
}
