/** * Bot-wall / CAPTCHA classification (#86). * * Promoted from the cohort's per-MCP duplicates: zillow-mcp's * PerimeterX detection (#91) and compass's confirmed AWS-WAF block. * Every portal MCP sees responses that may be a bot-wall interstitial * rather than real content, and misclassifying one as "not found" is * the silent-data-corruption failure class rounds 2-3 stamped out. A * shared classifier keeps detection in one place so no MCP reinvents it. * * Detection keys on the response BODY primarily — a PerimeterX * interstitial can be served as HTTP 200 (zillow #91), so requiring a * 4xx would miss it — with status and headers as additional signal for * vendors (AWS WAF) that only block with a 403. * * Pure: no I/O, no logging. The caller decides what to do with a * positive result (typically: back off via {@link backoffDelayMs} and * retry, surfacing the {@link FetchErrorKind} `'bot_challenge'`). */ /** Bot-wall vendor a positive classification attributes the block to. */ export type BotWallVendor = 'perimeterx' | 'aws_waf' | 'cloudflare' | 'datadome' | 'unknown'; /** * Discriminated result of {@link classifyBotWall}. `blocked: false` * carries no vendor; a positive result always names a vendor (falling * back to `'unknown'` only if a future arm detects a wall it can't * attribute). */ export type BotWallResult = { blocked: true; vendor: BotWallVendor; } | { blocked: false; }; /** * Classify a response as a bot-wall interstitial or genuine content. * * Detection is body-first (so a 200-status PerimeterX wall is caught), * with status/headers as additional signal for vendors that only block * with a 403. Arms are ordered most-specific first: PerimeterX (the * strongest, body-keyed signal) wins over a generic header. * * A plain 403 with no bot-wall markers stays `blocked: false` — it's a * hard auth error, not a transient wall, and callers must not back off * on it. * * @param body Response body text. * @param status HTTP status code. * @param headers Optional response headers (case-insensitive lookup). */ export declare function classifyBotWall(body: string, status: number, headers?: Record): BotWallResult;