/**
 * defense.ts — framework-agnostic port of the feedback receiver's intake defenses.
 *
 * Ports the six defense-in-depth layers of `the-portal/pages/api/instar/feedback.ts`
 * (rate-limit, agent fingerprint, honeypot, HMAC signature, input validation,
 * dedup-key/type) out of the Next.js handler into pure/injectable functions, so the
 * canonical front (whatever framework hosts it) reuses the exact same logic. The
 * HTTP wiring + the app/framework placement is deliberately NOT here (it is the
 * architecture decision in the spec's blocked list); this is the reusable core.
 *
 * Reference is TypeScript, so equivalence is by faithful transcription + exhaustive
 * both-sides-of-boundary unit tests (not a cross-runtime parity harness — those
 * apply to the Python processor ports). `now` is injected everywhere the reference
 * used `Date.now()`, so tests are deterministic.
 *
 * Convergence finding folded in: `normalizeWebhookSecret` trims the secret at load
 * so a trailing newline can't silently break the HMAC (the reference relied on a
 * "use printf not echo" warning; this makes it structural).
 */
export declare const VALID_TYPES: readonly ["bug", "feature", "improvement", "question", "hallucination", "other"];
export type FeedbackType = typeof VALID_TYPES[number];
export declare const SEMVER_RE: RegExp;
export declare const FEEDBACK_ID_RE: RegExp;
export declare const AGENT_NAME_RE: RegExp;
export declare const NODE_VERSION_RE: RegExp;
export declare const RATE_LIMITS: {
    perHour: number;
    perDay: number;
    windowHourMs: number;
    windowDayMs: number;
};
/** Trim the webhook secret so a trailing newline can't silently break the HMAC (convergence finding). */
export declare function normalizeWebhookSecret(secret: string | undefined): string | undefined;
export declare function isValidType(type: unknown): type is FeedbackType;
/** Port of extractSourceIp: first x-forwarded-for hop, else remoteAddress, else 'unknown'. */
export declare function extractSourceIp(headers: Record<string, string | string[] | undefined>, remoteAddress?: string): string;
/** Port of validateAgentFingerprint: UA must contain "instar/"; version header, if present, must be semver. */
export declare function validateAgentFingerprint(userAgent: string | undefined, headerVersion?: string): {
    valid: boolean;
    reason?: string;
};
/** Port of checkHoneypot: real agents never send `website`/`email`; presence ⇒ bot. */
export declare function checkHoneypot(body: Record<string, unknown>): boolean;
/**
 * Port of verifySignature. HMAC-SHA256 over `${timestamp}.${JSON.stringify(body)}`,
 * timing-safe compare, with a +5min / −1min replay window. `now` injected (ms).
 */
export declare function verifySignature(args: {
    signature?: string;
    timestamp?: string;
    body: unknown;
    secret: string | undefined;
    now: number;
}): boolean;
/**
 * Port of the in-memory sliding-window rate limiter (checkRateLimit + prune) as an
 * injectable class. `now()` is injectable for deterministic tests; defaults to Date.now.
 */
export declare class RateLimiter {
    private readonly limits;
    private readonly now;
    private store;
    private lastPrune;
    private readonly pruneIntervalMs;
    constructor(limits?: {
        perHour: number;
        perDay: number;
        windowHourMs: number;
        windowDayMs: number;
    }, now?: () => number);
    private prune;
    check(ip: string): {
        allowed: boolean;
        retryAfterSec?: number;
    };
}
//# sourceMappingURL=defense.d.ts.map