blackveil-dns 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/stdio.js +5 -1
- package/dist/stdio.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/dns-types.ts","../src/lib/config.ts","../src/schemas/dns.ts","../src/lib/dns-transport.ts","../src/lib/dns-records.ts","../src/lib/adaptive-weights.ts","../src/lib/sanitize.ts","../src/lib/server-version.ts","../src/schemas/primitives.ts","../src/schemas/tool-args.ts","../src/schemas/tool-definitions.ts","../src/tools/check-bimi.ts","../src/tools/check-caa.ts","../src/tools/check-dkim.ts","../src/tools/check-dmarc.ts","../src/tools/check-dnssec.ts","../src/tools/lookalike-analysis.ts","../src/tools/check-lookalikes.ts","../src/tools/check-mta-sts.ts","../src/lib/provider-signature-source.ts","../src/lib/provider-signatures.ts","../src/tools/check-mx.ts","../src/tools/check-ns.ts","../src/tools/check-spf.ts","../src/tools/check-ssl.ts","../src/tools/check-subdomain-takeover.ts","../src/tools/check-tlsrpt.ts","../src/lib/output-sanitize.ts","../src/tools/explain-finding-data.ts","../src/tools/explain-finding.ts","../src/lib/category-interactions.ts","../src/lib/log.ts","../src/lib/cache.ts","../src/tools/check-http-security.ts","../src/tools/check-dane.ts","../src/tools/check-dane-https.ts","../src/tools/check-svcb-https.ts","../src/tools/check-subdomailing.ts","../src/tools/scan/post-processing.ts","../src/tools/scan/maturity-staging.ts","../src/tools/scan/format-report.ts","../src/tools/scan-domain.ts"],"names":["topCat","topDelta","z","makeQueryDNS","createFinding","buildCheckResult","checkDnssec","normalizeDomain","checkSubdomainTakeoverPkg","lines","scoreToGrade","checkSubdomailingCore","evidence","getParentDomain","hasDnssec","result","detectDomainContext","getProfileWeights"],"mappings":"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","file":"index.js","sourcesContent":["// SPDX-License-Identifier: BUSL-1.1\n\n/** Standard DNS record type codes */\nexport const RecordType = {\n\tA: 1,\n\tAAAA: 28,\n\tCNAME: 5,\n\tMX: 15,\n\tTXT: 16,\n\tNS: 2,\n\tSOA: 6,\n\tCAA: 257,\n\tTLSA: 52,\n\tDNSKEY: 48,\n\tDS: 43,\n\tRRSIG: 46,\n\tPTR: 12,\n\tSRV: 33,\n\tHTTPS: 65,\n} as const;\n\nexport type RecordTypeName = keyof typeof RecordType;\n\n/** A single DNS answer record from the DoH JSON response */\nexport interface DnsAnswer {\n\tname: string;\n\ttype: number;\n\tTTL: number;\n\tdata: string;\n}\n\n/** A single DNS authority record */\nexport interface DnsAuthority {\n\tname: string;\n\ttype: number;\n\tTTL: number;\n\tdata: string;\n}\n\n/** Cloudflare DoH JSON wire-format response */\nexport interface DohResponse {\n\tStatus: number;\n\tTC: boolean;\n\tRD: boolean;\n\tRA: boolean;\n\tAD: boolean;\n\tCD: boolean;\n\tQuestion: Array<{ name: string; type: number }>;\n\tAnswer?: DnsAnswer[];\n\tAuthority?: DnsAuthority[];\n}\n\n/** Configuration for a custom secondary DoH resolver (e.g., bv-dns on Oracle Cloud). */\nexport interface SecondaryDohConfig {\n\t/** DoH endpoint URL (e.g. https://doh.example.com/dns-query) */\n\tendpoint: string;\n\t/** Optional auth token sent as X-BV-Token header */\n\ttoken?: string;\n}\n\nexport interface QueryDnsOptions {\n\ttimeoutMs?: number;\n\tretries?: number;\n\tconfirmWithSecondaryOnEmpty?: boolean;\n\t/** When true, skip secondary resolver confirmation on empty results. Used in scan context for speed. */\n\tskipSecondaryConfirmation?: boolean;\n\t/** Scan-scoped DNS query cache. Stores Promises keyed by `domain:type:dnssecCheck` to deduplicate concurrent and sequential identical queries within a single scan. */\n\tqueryCache?: Map<string, Promise<DohResponse>>;\n\t/** Custom secondary DoH resolver. When set, used instead of Google DoH for empty-result confirmation. Falls back to Google if this resolver fails. */\n\tsecondaryDoh?: SecondaryDohConfig;\n}","// SPDX-License-Identifier: BUSL-1.1\n\nimport type { Tier } from '../schemas/primitives';\n\n/**\n * Centralized configuration for domain normalization and validation.\n */\nexport const BLOCKED_SUFFIXES = [\n\t'.local',\n\t'.localhost',\n\t'.internal',\n\t'.example',\n\t'.invalid',\n\t'.test',\n\t'.onion',\n\t'.lan',\n\t'.home',\n\t'.corp',\n\t'.intranet',\n];\nexport const BLOCKED_HOSTS = ['localhost', 'localhost.localdomain'];\nexport const BLOCKED_IP_PATTERNS = [\n\t/^127\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^10\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^169\\.254\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^0\\.0\\.0\\.0$/,\n\t/^::1$/,\n\t/^fc00:/i,\n\t/^fd[0-9a-f]{2}:/i,\n\t/^fe[89ab][0-9a-f]:/i,\n];\nexport const BLOCKED_DNS_REBINDING = ['.nip.io', '.sslip.io', '.xip.io', '.nip.direct'];\nexport const MAX_DOMAIN_LENGTH = 253;\nexport const MAX_LABEL_LENGTH = 63;\nexport const LABEL_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i;\n\n/** Hard limit on incoming JSON-RPC request body size (bytes). */\nexport const MAX_REQUEST_BODY_BYTES = 10_240;\n\n/** Timeout for outbound HTTPS fetches (SSL, MTA-STS policy, etc.). */\nexport const HTTPS_TIMEOUT_MS = 4_000;\n\n/** Default timeout for DNS-over-HTTPS queries. CF DoH p99 is <500ms. */\nexport const DNS_TIMEOUT_MS = 3_000;\n\n/** Default number of retry attempts for DNS-over-HTTPS queries. */\nexport const DNS_RETRIES = 1;\n\n/** Edge cache TTL (seconds) for outbound DoH fetch requests via Cloudflare's cf API. */\nexport const DOH_EDGE_CACHE_TTL = 300;\n\n/** Timeout (ms) after which a stuck INFLIGHT promise is evicted from the dedup map. */\nexport const INFLIGHT_CLEANUP_MS = 30_000;\n\n/** Base delay (ms) between DNS retry attempts. Actual delay = base * (attempt+1) + jitter. */\nexport const DNS_RETRY_BASE_DELAY_MS = 75;\n\n/**\n * When true, empty DoH answers from the primary resolver are optionally\n * confirmed with a secondary resolver to reduce false negatives.\n */\nexport const DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY = true;\n\n/** Default cache TTL in seconds. Override via CACHE_TTL_SECONDS env var. */\nexport const DEFAULT_CACHE_TTL_SECONDS = 300;\n\n/**\n * Parse CACHE_TTL_SECONDS env var, clamping to [60, 3600].\n * Returns DEFAULT_CACHE_TTL_SECONDS when absent or invalid.\n */\nexport function parseCacheTtl(envValue?: string): number {\n\tif (!envValue) return DEFAULT_CACHE_TTL_SECONDS;\n\tconst parsed = Number(envValue);\n\tif (!Number.isFinite(parsed) || parsed < 60) return DEFAULT_CACHE_TTL_SECONDS;\n\treturn Math.min(parsed, 3600);\n}\n\n/**\n * Global daily free-tier request ceiling across all unauthenticated IPs.\n * Protects from abuse by capping free usage at a service-wide level.\n * Authenticated requests are exempt.\n */\nexport const GLOBAL_DAILY_TOOL_LIMIT = 500_000;\n\n/**\n * Free-tier daily tool quotas for unauthenticated callers.\n * Tools omitted from this map are governed only by baseline per-IP rate limits.\n */\n/** MCP API key tiers with daily scan quotas. Derived from the Zod TierSchema in schemas/primitives. */\nexport type McpApiKeyTier = Tier;\n\n/** Daily scan limits per API key tier (applies per tool unless overridden by TIER_TOOL_DAILY_LIMITS). */\nexport const TIER_DAILY_LIMITS: Record<McpApiKeyTier, number> = {\n\tfree: 50,\n\tagent: 200,\n\tdeveloper: 500,\n\tenterprise: 10_000,\n\tpartner: 100_000,\n\towner: Infinity,\n};\n\n/**\n * Per-tool daily limit overrides for specific tiers.\n * When a tier+tool combo exists here, it takes precedence over the flat TIER_DAILY_LIMITS value.\n */\nexport const TIER_TOOL_DAILY_LIMITS: Partial<Record<McpApiKeyTier, Record<string, number>>> = {\n\tpartner: {\n\t\tscan_domain: 100_000,\n\t\tscan: 100_000,\n\t\tcompare_baseline: 100_000,\n\t\tcheck_spf: 500_000,\n\t\tcheck_dmarc: 500_000,\n\t\tcheck_dkim: 500_000,\n\t\tcheck_mx: 500_000,\n\t\tcheck_ns: 500_000,\n\t\tcheck_ssl: 500_000,\n\t\tcheck_dnssec: 500_000,\n\t\tcheck_mta_sts: 500_000,\n\t\tcheck_caa: 500_000,\n\t\tcheck_bimi: 500_000,\n\t\tcheck_tlsrpt: 500_000,\n\t\tcheck_lookalikes: 50_000,\n\t\tcheck_shadow_domains: 50_000,\n\t\tcheck_txt_hygiene: 500_000,\n\t\tcheck_http_security: 500_000,\n\t\tcheck_dane: 500_000,\n\t\tcheck_mx_reputation: 50_000,\n\t\tcheck_srv: 500_000,\n\t\tcheck_zone_hygiene: 500_000,\n\t\tcheck_subdomailing: 500_000,\n\t\texplain_finding: 500_000,\n\t},\n};\n\nexport const FREE_TOOL_DAILY_LIMITS: Record<string, number> = {\n\tscan_domain: 75,\n\tscan: 75,\n\tbatch_scan: 20,\n\tcompare_domains: 15,\n\tcheck_spf: 200,\n\tcheck_dmarc: 200,\n\tcheck_dkim: 200,\n\tcheck_mx: 200,\n\tcheck_ns: 200,\n\tcheck_ssl: 200,\n\tcheck_dnssec: 200,\n\tcheck_mta_sts: 200,\n\tcheck_caa: 200,\n\tcheck_bimi: 200,\n\tcheck_tlsrpt: 200,\n\tcheck_lookalikes: 20,\n\texplain_finding: 200,\n\tcompare_baseline: 150,\n\tcheck_shadow_domains: 20,\n\tcheck_txt_hygiene: 200,\n\tcheck_http_security: 200,\n\tcheck_dane: 200,\n\tcheck_mx_reputation: 20,\n\tcheck_srv: 200,\n\tcheck_zone_hygiene: 200,\n\tcheck_subdomailing: 200,\n\tgenerate_fix_plan: 75,\n\tgenerate_spf_record: 200,\n\tgenerate_dmarc_record: 200,\n\tgenerate_dkim_config: 200,\n\tgenerate_mta_sts_policy: 200,\n\tget_benchmark: 100,\n\tget_provider_insights: 50,\n\tassess_spoofability: 150,\n\tcheck_resolver_consistency: 50,\n\tmap_supply_chain: 75,\n\tanalyze_drift: 75,\n\tvalidate_fix: 200,\n\tgenerate_rollout_plan: 150,\n\tresolve_spf_chain: 100,\n\tdiscover_subdomains: 50,\n\tmap_compliance: 75,\n\tsimulate_attack_paths: 75,\n};\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\n\n/** DNS answer record from DoH response. */\nexport const DnsAnswerSchema = z.object({\n\tname: z.string(),\n\ttype: z.number(),\n\tTTL: z.number().optional(),\n\tdata: z.string(),\n});\n\n/** DNS authority record from DoH response. */\nexport const DnsAuthoritySchema = z.object({\n\tname: z.string(),\n\ttype: z.number(),\n\tTTL: z.number().optional(),\n\tdata: z.string(),\n});\n\n/** Complete DoH JSON response. Validates shape before casting. */\nexport const DohResponseSchema = z\n\t.object({\n\t\tStatus: z.number().finite(),\n\t\tTC: z.boolean().optional(),\n\t\tRD: z.boolean().optional(),\n\t\tRA: z.boolean().optional(),\n\t\tAD: z.boolean().optional(),\n\t\tCD: z.boolean().optional(),\n\t\tQuestion: z.array(z.object({ name: z.string(), type: z.unknown() })).optional(),\n\t\tAnswer: z.array(DnsAnswerSchema).optional(),\n\t\tAuthority: z.array(DnsAuthoritySchema).optional(),\n\t})\n\t.passthrough();\n\n/** Parsed CAA record. */\nexport const CaaRecordSchema = z.object({\n\tflags: z.number(),\n\ttag: z.string(),\n\tvalue: z.string(),\n});\n\n/** Parsed TLSA record. */\nexport const TlsaRecordSchema = z.object({\n\tusage: z.number(),\n\tselector: z.number(),\n\tmatchingType: z.number(),\n\tcertData: z.string(),\n});\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { DNS_TIMEOUT_MS, DNS_RETRIES, DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY, DOH_EDGE_CACHE_TTL, DNS_RETRY_BASE_DELAY_MS } from './config';\nimport { type DohResponse, type QueryDnsOptions, RecordType, type RecordTypeName } from './dns-types';\nimport { DohResponseSchema } from '../schemas/dns';\n\nconst DOH_ENDPOINT = 'https://cloudflare-dns.com/dns-query';\nconst GOOGLE_DOH_ENDPOINT = 'https://dns.google/resolve';\n\nfunction buildDohUrl(endpoint: string, domain: string, type: RecordTypeName, dnssecCheck: boolean): string {\n\tconst params = new URLSearchParams({\n\t\tname: domain,\n\t\ttype,\n\t\t...(dnssecCheck ? { cd: '0' } : {}),\n\t});\n\n\treturn `${endpoint}?${params.toString()}`;\n}\n\nfunction hasTypedAnswers(response: DohResponse, type: RecordTypeName): boolean {\n\treturn (response.Answer ?? []).some((answer) => answer.type === RecordType[type]);\n}\n\nfunction retryDelay(attempt: number): Promise<void> {\n\treturn new Promise((r) => setTimeout(r, DNS_RETRY_BASE_DELAY_MS * (attempt + 1) + Math.random() * 50));\n}\n\n/**\n * Fetch a DoH response from a URL.\n *\n * @param token - Optional auth token sent as `X-BV-Token` (for custom secondary resolvers).\n * @param useEdgeCache - If true, attaches Cloudflare `cf` cache directive. Omit for external origins.\n */\nasync function fetchDohResponse(\n\turl: string,\n\ttimeoutMs: number,\n\topts?: { token?: string; useEdgeCache?: boolean },\n): Promise<DohResponse | null> {\n\ttry {\n\t\tconst headers: Record<string, string> = { Accept: 'application/dns-json' };\n\t\tif (opts?.token) headers['X-BV-Token'] = opts.token;\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: 'GET',\n\t\t\theaders,\n\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t...(opts?.useEdgeCache ? { cf: { cacheTtl: DOH_EDGE_CACHE_TTL, cacheEverything: true } } : {}),\n\t\t});\n\t\tif (!response.ok) return null;\n\t\tconst data = await response.json();\n\t\tconst parsed = DohResponseSchema.safeParse(data);\n\t\tif (!parsed.success) return null;\n\t\treturn parsed.data as DohResponse;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Error thrown when a DNS query fails */\nexport class DnsQueryError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly domain: string,\n\t\tpublic readonly recordType: string,\n\t\tpublic readonly status?: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'DnsQueryError';\n\t}\n}\n\n/**\n * Query Cloudflare DoH for DNS records.\n *\n * When `opts.queryCache` is provided, deduplicates concurrent and sequential\n * identical queries within a single scan by caching the Promise keyed by\n * `domain:type:dnssecCheck`. Failed queries are evicted so retries can re-attempt.\n *\n * @param domain - The domain name to query\n * @param type - DNS record type name (e.g. \"TXT\", \"MX\", \"A\")\n * @param dnssecCheck - If true, sets the CD=0 flag to request DNSSEC validation\n * @returns The full DoH JSON response\n */\nexport async function queryDns(domain: string, type: RecordTypeName, dnssecCheck = false, opts?: QueryDnsOptions): Promise<DohResponse> {\n\tconst cache = opts?.queryCache;\n\tif (!cache) {\n\t\treturn queryDnsUncached(domain, type, dnssecCheck, opts);\n\t}\n\n\tconst cacheKey = `${domain}:${type}:${dnssecCheck}`;\n\tconst existing = cache.get(cacheKey);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\n\tconst promise = queryDnsUncached(domain, type, dnssecCheck, opts);\n\tcache.set(cacheKey, promise);\n\tpromise.catch(() => cache.delete(cacheKey));\n\treturn promise;\n}\n\nasync function queryDnsUncached(domain: string, type: RecordTypeName, dnssecCheck = false, opts?: QueryDnsOptions): Promise<DohResponse> {\n\tconst timeoutMs = opts?.timeoutMs ?? DNS_TIMEOUT_MS;\n\tconst retries = opts?.retries ?? DNS_RETRIES;\n\tconst confirmWithSecondaryOnEmpty = opts?.confirmWithSecondaryOnEmpty ?? DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY;\n\tconst url = buildDohUrl(DOH_ENDPOINT, domain, type, dnssecCheck);\n\n\tfor (let attempt = 0; attempt <= retries; attempt++) {\n\t\tlet response: Response;\n\n\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { Accept: 'application/dns-json' },\n\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t\tcf: { cacheTtl: DOH_EDGE_CACHE_TTL, cacheEverything: true },\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof DOMException && err.name === 'AbortError') {\n\t\t\t\tif (attempt < retries) {\n\t\t\t\t\tawait retryDelay(attempt);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new DnsQueryError(`DNS query timed out after ${timeoutMs}ms`, domain, type);\n\t\t\t}\n\t\t\tif (attempt < retries) {\n\t\t\t\tawait retryDelay(attempt);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DnsQueryError(`DNS query failed: ${err instanceof Error ? err.message : String(err)}`, domain, type);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tif (attempt < retries && response.status >= 500) {\n\t\t\t\tawait retryDelay(attempt);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DnsQueryError(`DoH returned HTTP ${response.status}`, domain, type, response.status);\n\t\t}\n\n\t\tconst raw = await response.json();\n\t\tconst validated = DohResponseSchema.safeParse(raw);\n\t\tif (!validated.success) {\n\t\t\tthrow new DnsQueryError('Invalid DoH response format', domain, type);\n\t\t}\n\t\tconst data = validated.data as DohResponse;\n\n\t\tif (confirmWithSecondaryOnEmpty && !opts?.skipSecondaryConfirmation && !hasTypedAnswers(data, type)) {\n\t\t\t// Try custom secondary (bv-dns) first if configured\n\t\t\tif (opts?.secondaryDoh?.endpoint) {\n\t\t\t\tconst bvDns = await fetchDohResponse(\n\t\t\t\t\tbuildDohUrl(opts.secondaryDoh.endpoint, domain, type, dnssecCheck),\n\t\t\t\t\ttimeoutMs,\n\t\t\t\t\t{ token: opts.secondaryDoh.token },\n\t\t\t\t);\n\t\t\t\tif (bvDns && hasTypedAnswers(bvDns, type)) {\n\t\t\t\t\treturn bvDns;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Google DoH as final fallback\n\t\t\tconst google = await fetchDohResponse(\n\t\t\t\tbuildDohUrl(GOOGLE_DOH_ENDPOINT, domain, type, dnssecCheck),\n\t\t\t\ttimeoutMs,\n\t\t\t\t{ useEdgeCache: true },\n\t\t\t);\n\t\t\tif (google && hasTypedAnswers(google, type)) {\n\t\t\t\treturn google;\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tthrow new DnsQueryError('DNS query failed after retries', domain, type);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { queryDns } from './dns-transport';\nimport { RecordType, type QueryDnsOptions, type RecordTypeName } from './dns-types';\nimport { CaaRecordSchema, TlsaRecordSchema } from '../schemas/dns';\n\n/** Parsed CAA record with flags, tag, and value */\nexport interface CaaRecord {\n\tflags: number;\n\ttag: string;\n\tvalue: string;\n}\n\n/** Parsed PTR record hostname */\nexport interface PtrRecord {\n\thostname: string;\n}\n\n/** Parsed SRV record with priority, weight, port, and target */\nexport interface SrvRecord {\n\tpriority: number;\n\tweight: number;\n\tport: number;\n\ttarget: string;\n}\n\n/** Parsed TLSA record with usage, selector, matching type, and certificate data */\nexport interface TlsaRecord {\n\tusage: number;\n\tselector: number;\n\tmatchingType: number;\n\tcertData: string;\n}\n\n/**\n * Query DNS and return just the answer data strings.\n * Returns an empty array if no answers are found.\n */\nexport async function queryDnsRecords(domain: string, type: RecordTypeName, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst resp = await queryDns(domain, type, false, opts);\n\treturn (resp.Answer ?? []).filter((answer) => answer.type === RecordType[type]).map((answer) => answer.data);\n}\n\n/**\n * Query TXT records, concatenate multi-string values, and unescape DNS\n * presentation-format backslash sequences.\n *\n * Cloudflare DoH returns TXT data with surrounding quotes and multiple\n * strings separated by `\" \"`. Per RFC 7208 §3.3, multi-string TXT records\n * MUST be concatenated without adding spaces. Some nameservers also emit\n * RFC 1035 §5.1 backslash escapes (e.g. `\\;` for a literal semicolon);\n * we unescape both `\\X` (single-char) and `\\DDD` (decimal octet) forms.\n */\nexport async function queryTxtRecords(domain: string, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst records = await queryDnsRecords(domain, 'TXT', opts);\n\treturn records.map((record) =>\n\t\tunescapeDnsTxt(\n\t\t\trecord\n\t\t\t\t.replace(/\" \"/g, '')\n\t\t\t\t.replace(/^\"|\"$/g, ''),\n\t\t),\n\t);\n}\n\n/**\n * Unescape DNS presentation-format backslash sequences in TXT record data.\n * Handles `\\DDD` (decimal octet 000–255) and `\\X` (literal character).\n *\n * Some DoH providers double-escape (e.g. `\\\\;` in the JS string for what\n * should be a plain `;`), so we loop until the string stabilises.\n */\nexport function unescapeDnsTxt(text: string): string {\n\tconst unescape = (s: string) =>\n\t\ts.replace(/\\\\(\\d{3})|\\\\(.)/g, (_, decimal, ch) => {\n\t\t\tif (decimal !== undefined) {\n\t\t\t\tconst code = parseInt(decimal, 10);\n\t\t\t\treturn code <= 255 ? String.fromCharCode(code) : `\\\\${decimal}`;\n\t\t\t}\n\t\t\treturn ch;\n\t\t});\n\n\tlet result = text;\n\tfor (let i = 0; i < 2; i++) {\n\t\tconst next = unescape(result);\n\t\tif (next === result) break;\n\t\tresult = next;\n\t}\n\treturn result;\n}\n\n/**\n * Check if a domain has valid DNSSEC by examining the AD (Authenticated Data) flag.\n * Returns true if the response was DNSSEC-validated.\n */\nexport async function checkDnssec(domain: string, opts?: QueryDnsOptions): Promise<boolean> {\n\tconst resp = await queryDns(domain, 'A', true, opts);\n\treturn resp.AD === true;\n}\n\n/**\n * Parse a single CAA record data string.\n * Handles both human-readable format (e.g. `0 issue \"letsencrypt.org\"`)\n * and Cloudflare DoH hex wire format (e.g. `\\# 19 00 05 69 73 73 75 65...`).\n *\n * Wire format bytes: flags(1) + tag_length(1) + tag(tag_length) + value(rest)\n */\nexport function parseCaaRecord(data: string): CaaRecord | null {\n\tif (data.startsWith('\\\\#') || data.startsWith('#')) {\n\t\tconst parts = data.trim().split(/\\s+/);\n\t\tconst hexStart = parts[0] === '\\\\#' || parts[0] === '#' ? 2 : 1;\n\t\tconst hexBytes = parts.slice(hexStart);\n\t\tif (hexBytes.length < 3) return null;\n\n\t\tconst flags = parseInt(hexBytes[0], 16);\n\t\tconst tagLen = parseInt(hexBytes[1], 16);\n\t\tif (isNaN(flags) || isNaN(tagLen) || hexBytes.length < 2 + tagLen) return null;\n\n\t\tconst tag = hexBytes\n\t\t\t.slice(2, 2 + tagLen)\n\t\t\t.map((hexByte) => String.fromCharCode(parseInt(hexByte, 16)))\n\t\t\t.join('');\n\t\tconst value = hexBytes\n\t\t\t.slice(2 + tagLen)\n\t\t\t.map((hexByte) => String.fromCharCode(parseInt(hexByte, 16)))\n\t\t\t.join('');\n\n\t\tconst record = { flags, tag: tag.toLowerCase(), value };\n\t\treturn CaaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\tconst match = data.match(/^(\\d+)\\s+(\\S+)\\s+\"?([^\"]*)\"?\\s*$/);\n\tif (match) {\n\t\tconst record = {\n\t\t\tflags: parseInt(match[1], 10),\n\t\t\ttag: match[2].toLowerCase(),\n\t\t\tvalue: match[3],\n\t\t};\n\t\treturn CaaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\treturn null;\n}\n\n/**\n * Query CAA records and parse them into structured objects.\n * Handles both human-readable and hex wire format from DoH.\n */\nexport async function queryCaaRecords(domain: string, opts?: QueryDnsOptions): Promise<CaaRecord[]> {\n\tconst records = await queryDnsRecords(domain, 'CAA', opts);\n\treturn records.map(parseCaaRecord).filter((record): record is CaaRecord => record !== null);\n}\n\n/**\n * Query MX records and parse them into priority + exchange pairs.\n */\nexport async function queryMxRecords(domain: string, opts?: QueryDnsOptions): Promise<Array<{ priority: number; exchange: string }>> {\n\tconst records = await queryDnsRecords(domain, 'MX', opts);\n\treturn records.map((record) => {\n\t\tconst parts = record.split(' ');\n\t\treturn {\n\t\t\tpriority: parseInt(parts[0], 10),\n\t\t\texchange: parts.slice(1).join(' ').replace(/\\.$/, ''),\n\t\t};\n\t});\n}\n\n/**\n * Query PTR records for an IP address by constructing the reverse DNS name.\n * For IPv4 address `192.0.2.1`, queries `1.2.0.192.in-addr.arpa`.\n * Returns an array of PTR hostnames with trailing dots stripped.\n */\nexport async function queryPtrRecords(ip: string, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst reverseName = ip.split('.').reverse().join('.') + '.in-addr.arpa';\n\tconst records = await queryDnsRecords(reverseName, 'PTR', opts);\n\treturn records.map((record) => record.replace(/\\.$/, ''));\n}\n\n/**\n * Query SRV records and parse them into structured objects.\n * SRV data format: `priority weight port target`\n */\nexport async function querySrvRecords(\n\tname: string,\n\topts?: QueryDnsOptions,\n): Promise<Array<{ priority: number; weight: number; port: number; target: string }>> {\n\tconst records = await queryDnsRecords(name, 'SRV', opts);\n\treturn records.map((record) => {\n\t\tconst parts = record.split(' ');\n\t\treturn {\n\t\t\tpriority: parseInt(parts[0], 10),\n\t\t\tweight: parseInt(parts[1], 10),\n\t\t\tport: parseInt(parts[2], 10),\n\t\t\ttarget: parts.slice(3).join(' ').replace(/\\.$/, ''),\n\t\t};\n\t});\n}\n\n/**\n * Parse a TLSA record data string into structured fields.\n * Handles both human-readable format (`usage selector matchingType certData`)\n * and hex wire format (data starting with `\\#`).\n *\n * Returns null if the data cannot be parsed.\n */\nexport function parseTlsaRecord(data: string): TlsaRecord | null {\n\tif (data.startsWith('\\\\#') || data.startsWith('#')) {\n\t\tconst parts = data.trim().split(/\\s+/);\n\t\tconst hexStart = parts[0] === '\\\\#' || parts[0] === '#' ? 2 : 1;\n\t\tconst hexBytes = parts.slice(hexStart);\n\t\tif (hexBytes.length < 4) return null;\n\n\t\tconst usage = parseInt(hexBytes[0], 16);\n\t\tconst selector = parseInt(hexBytes[1], 16);\n\t\tconst matchingType = parseInt(hexBytes[2], 16);\n\t\tif (isNaN(usage) || isNaN(selector) || isNaN(matchingType)) return null;\n\n\t\tconst certData = hexBytes.slice(3).join('');\n\t\tconst record = { usage, selector, matchingType, certData };\n\t\treturn TlsaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\tconst parts = data.trim().split(/\\s+/);\n\tif (parts.length < 4) return null;\n\n\tconst usage = parseInt(parts[0], 10);\n\tconst selector = parseInt(parts[1], 10);\n\tconst matchingType = parseInt(parts[2], 10);\n\tif (isNaN(usage) || isNaN(selector) || isNaN(matchingType)) return null;\n\n\tconst certData = parts.slice(3).join('');\n\tconst record = { usage, selector, matchingType, certData };\n\treturn TlsaRecordSchema.safeParse(record).success ? record : null;\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Adaptive weight computation for context-aware scoring.\n *\n * Uses exponential moving averages (EMA) of per-category failure rates,\n * collected by the ProfileAccumulator Durable Object, to adjust static\n * importance weights at scoring time. A maturity-gated blend ensures\n * weights stay close to static until enough telemetry has accumulated.\n */\n\nimport type { CheckCategory } from './scoring-model';\nimport type { DomainProfile } from './context-profiles';\nimport { PROFILE_WEIGHTS } from './context-profiles';\n\n// ─── Telemetry interfaces ──────────────────────────────────────────────\n\n/** A single scan's telemetry payload sent to the ProfileAccumulator DO. */\nexport interface ScanTelemetry {\n\tprofile: string;\n\tprovider: string | null;\n\tcategoryFindings: Array<{ category: string; score: number; passed: boolean }>;\n\ttimestamp: number;\n\t/** Overall scan score (0–100). Used for intelligence layer aggregation (histogram, cohort, trends). */\n\toverallScore?: number;\n}\n\n/** Response from the adaptive weights endpoint. */\nexport interface AdaptiveWeightsResponse {\n\tprofile: string;\n\tprovider: string | null;\n\tsampleCount: number;\n\tblendFactor: number;\n\tweights: Record<string, number>;\n\tboundHits: string[];\n}\n\n/** Min/max bounds for an adaptive weight value. */\nexport interface WeightBound {\n\tmin: number;\n\tmax: number;\n}\n\n// ─── Constants ─────────────────────────────────────────────────────────\n\n/** How aggressively deviation from baseline adjusts the weight (0–1). */\nexport const SENSITIVITY = 0.5;\n\n/** Sample count at which blending reaches 100% adaptive. */\nexport const MATURITY_THRESHOLD = 200;\n\n/** EMA span (number of recent observations the average reflects). */\nexport const EMA_SPAN = 200;\n\n/** EMA smoothing factor derived from span. */\nexport const EMA_ALPHA = 2 / (EMA_SPAN + 1);\n\n/** Minimum |scoreDelta| before a scoring note is generated. */\nexport const SCORING_NOTE_DELTA_THRESHOLD = 3;\n\n/** Expected failure rate per category across all domains (prior). */\nexport const BASELINE_FAILURE_RATES: Record<string, number> = {\n\tdmarc: 0.40,\n\tspf: 0.25,\n\tdkim: 0.35,\n\tssl: 0.08,\n\tmta_sts: 0.85,\n\tdnssec: 0.80,\n\tmx: 0.05,\n\tcaa: 0.70,\n\tns: 0.03,\n\tbimi: 0.95,\n\ttlsrpt: 0.90,\n\tsubdomain_takeover: 0.10,\n\tlookalikes: 0.00,\n};\n\n// ─── Weight bounds ─────────────────────────────────────────────────────\n\n/** Categories treated as \"critical mail\" for bound computation in mail-centric profiles. */\nconst CRITICAL_MAIL_CATEGORIES = new Set<string>(['dmarc', 'spf', 'dkim', 'ssl']);\n\n/** Profiles where critical-mail floor applies. */\nconst CRITICAL_MAIL_PROFILES = new Set<string>(['mail_enabled', 'enterprise_mail']);\n\n/**\n * Compute default min/max bounds for an adaptive weight.\n *\n * Critical-mail categories get a higher floor (min 5) to prevent\n * important email-auth checks from being zeroed out.\n */\nexport function defaultBounds(staticWeight: number, isCriticalMail: boolean): WeightBound {\n\tconst minFloor = isCriticalMail ? 5 : 0;\n\treturn {\n\t\tmin: Math.max(minFloor, Math.floor(staticWeight * 0.5)),\n\t\tmax: Math.ceil(staticWeight * 2) + 3,\n\t};\n}\n\n/** Pre-computed bounds for every profile × category combination. */\nexport const WEIGHT_BOUNDS: Record<DomainProfile, Record<CheckCategory, WeightBound>> = (() => {\n\tconst profiles = Object.keys(PROFILE_WEIGHTS) as DomainProfile[];\n\tconst result = {} as Record<DomainProfile, Record<CheckCategory, WeightBound>>;\n\n\tfor (const profile of profiles) {\n\t\tconst weights = PROFILE_WEIGHTS[profile];\n\t\tconst categories = Object.keys(weights) as CheckCategory[];\n\t\tconst profileBounds = {} as Record<CheckCategory, WeightBound>;\n\n\t\tfor (const cat of categories) {\n\t\t\tconst isCritical = CRITICAL_MAIL_PROFILES.has(profile) && CRITICAL_MAIL_CATEGORIES.has(cat);\n\t\t\tprofileBounds[cat] = defaultBounds(weights[cat].importance, isCritical);\n\t\t}\n\n\t\tresult[profile] = profileBounds;\n\t}\n\n\treturn result;\n})();\n\n// ─── Computation functions ─────────────────────────────────────────────\n\n/**\n * Compute a single adaptive weight from EMA failure rate and baseline.\n *\n * @returns The clamped weight and whether a bound was hit ('min' | 'max' | null).\n */\nexport function computeAdaptiveWeight(params: {\n\tstaticWeight: number;\n\temaFailureRate: number;\n\tbaselineFailureRate: number;\n\tbounds: WeightBound;\n}): { weight: number; boundHit: 'min' | 'max' | null } {\n\tconst { staticWeight, emaFailureRate, baselineFailureRate, bounds } = params;\n\n\tconst deviation = emaFailureRate - baselineFailureRate;\n\tconst rawAdjustment = deviation * SENSITIVITY * staticWeight;\n\tconst adaptive = staticWeight + rawAdjustment;\n\tconst clamped = Math.max(bounds.min, Math.min(bounds.max, adaptive));\n\n\tlet boundHit: 'min' | 'max' | null = null;\n\tif (clamped <= bounds.min && adaptive < bounds.min) {\n\t\tboundHit = 'min';\n\t} else if (clamped >= bounds.max && adaptive > bounds.max) {\n\t\tboundHit = 'max';\n\t}\n\n\treturn { weight: clamped, boundHit };\n}\n\n/**\n * Blend static and adaptive weights based on sample maturity.\n *\n * Returns `(1 - blendFactor) * staticWeight + blendFactor * adaptiveWeight`\n * where `blendFactor = min(1.0, sampleCount / MATURITY_THRESHOLD)`.\n */\nexport function blendWeights(staticWeight: number, adaptiveWeight: number, sampleCount: number): number {\n\tconst blendFactor = Math.min(1.0, sampleCount / MATURITY_THRESHOLD);\n\treturn (1 - blendFactor) * staticWeight + blendFactor * adaptiveWeight;\n}\n\n// ─── Type adapter ──────────────────────────────────────────────────────\n\n/**\n * Convert a DO-returned weight map to a CheckCategory-keyed importance record.\n *\n * Falls back to the static profile weight for any category not present in the\n * DO response. Returns `null` if any value is non-finite or negative.\n */\nexport function adaptiveWeightsToContext(\n\tdoWeights: Record<string, number>,\n\tprofile: DomainProfile,\n): Record<CheckCategory, { importance: number }> | null {\n\tconst staticWeights = PROFILE_WEIGHTS[profile];\n\tconst categories = Object.keys(staticWeights) as CheckCategory[];\n\tconst result = {} as Record<CheckCategory, { importance: number }>;\n\n\tfor (const cat of categories) {\n\t\tconst value = cat in doWeights ? doWeights[cat] : staticWeights[cat].importance;\n\t\tif (!isFinite(value) || value < 0) {\n\t\t\treturn null;\n\t\t}\n\t\tresult[cat] = { importance: value };\n\t}\n\n\treturn result;\n}\n\n// ─── Scoring note generation ───────────────────────────────────────────\n\n/**\n * Generate a human-readable note explaining adaptive weight shifts.\n *\n * Returns `null` if the absolute score delta is below the threshold.\n */\nexport function generateScoringNote(\n\tweightDeltas: Record<string, number>,\n\tscoreDelta: number,\n\tprovider: string | null,\n): string | null {\n\tif (Math.abs(scoreDelta) < SCORING_NOTE_DELTA_THRESHOLD) {\n\t\treturn null;\n\t}\n\n\t// Collect significant deltas (|delta| >= 2) sorted by magnitude descending\n\tconst significant = Object.entries(weightDeltas)\n\t\t.filter(([, d]) => Math.abs(d) >= 2)\n\t\t.sort((a, b) => Math.abs(b[1]) - Math.abs(a[1]));\n\n\tif (significant.length === 0) {\n\t\t// No individually significant deltas but overall threshold met — use the largest anyway\n\t\tconst all = Object.entries(weightDeltas).sort((a, b) => Math.abs(b[1]) - Math.abs(a[1]));\n\t\tif (all.length === 0) return null;\n\t\tconst [topCat, topDelta] = all[0];\n\t\treturn formatNote(topCat, topDelta, provider);\n\t}\n\n\tif (significant.length >= 3) {\n\t\tconst [topCat] = significant[0];\n\t\treturn `Several checks were weighted differently based on patterns seen across similar domains. The biggest shift was in ${topCat.toUpperCase()}.`;\n\t}\n\n\tconst [topCat, topDelta] = significant[0];\n\treturn formatNote(topCat, topDelta, provider);\n}\n\n/** Format a single-category scoring note. */\nfunction formatNote(category: string, delta: number, provider: string | null): string {\n\tconst cat = category.toUpperCase();\n\n\tif (delta > 0 && provider) {\n\t\tconst providerDisplay = capitalizeWords(provider);\n\t\treturn `${cat} carried more weight because domains using ${providerDisplay} frequently have issues in this area.`;\n\t}\n\n\tif (delta > 0) {\n\t\treturn `${cat} carried more weight in this scan because it is a common issue across similar domains.`;\n\t}\n\n\treturn `${cat} carried less weight because similar domains rarely have issues there.`;\n}\n\n/** Capitalize the first letter of each word. */\nfunction capitalizeWords(s: string): string {\n\treturn s.replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n// For IDN/Unicode normalization\nimport * as punycode from 'punycode/';\n// Centralized normalization config\nimport {\n\tBLOCKED_SUFFIXES,\n\tBLOCKED_HOSTS,\n\tBLOCKED_IP_PATTERNS,\n\tBLOCKED_DNS_REBINDING,\n\tMAX_DOMAIN_LENGTH,\n\tMAX_LABEL_LENGTH,\n\tLABEL_REGEX,\n} from './config';\n/**\n * Input sanitization and validation utilities for the DNS Security MCP Server.\n * Handles domain validation, input cleaning, and MCP error response helpers.\n * Compatible with Cloudflare Workers runtime (no Node.js APIs).\n */\n\nexport interface ValidationResult {\n\tvalid: boolean;\n\terror?: string;\n}\n\n/**\n * Parse a numeric IPv4 segment using decimal, octal, or hex notation.\n * Returns null when the token is not a numeric IP segment.\n */\nfunction parseIpv4NumberToken(token: string): number | null {\n\tif (!token) return null;\n\n\tlet radix = 10;\n\tlet digits = token;\n\tif (/^0x[0-9a-f]+$/i.test(token)) {\n\t\tradix = 16;\n\t\tdigits = token.slice(2);\n\t} else if (/^0[0-7]+$/.test(token) && token.length > 1) {\n\t\tradix = 8;\n\t}\n\n\tif (digits.length === 0) return null;\n\tconst value = Number.parseInt(digits, radix);\n\tif (!Number.isFinite(value) || value < 0) return null;\n\treturn value;\n}\n\n/**\n * Canonicalize IPv4 literals that may use short/octal/hex forms.\n * Returns null when input is not an IPv4 host literal candidate.\n */\nfunction canonicalizeIpv4Literal(input: string): string | null {\n\tif (!/^[0-9a-fx.]+$/i.test(input)) return null;\n\n\tconst parts = input.split('.');\n\tif (parts.length < 1 || parts.length > 4) return null;\n\tif (parts.some((part) => part.length === 0)) return null;\n\n\tconst values: number[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseIpv4NumberToken(part);\n\t\tif (parsed === null) return null;\n\t\tvalues.push(parsed);\n\t}\n\n\tlet ipAsUint32 = 0;\n\tif (values.length === 1) {\n\t\tif (values[0] > 0xffffffff) return null;\n\t\tipAsUint32 = values[0] >>> 0;\n\t} else if (values.length === 2) {\n\t\tif (values[0] > 0xff || values[1] > 0xffffff) return null;\n\t\tipAsUint32 = ((values[0] << 24) | values[1]) >>> 0;\n\t} else if (values.length === 3) {\n\t\tif (values[0] > 0xff || values[1] > 0xff || values[2] > 0xffff) return null;\n\t\tipAsUint32 = ((values[0] << 24) | (values[1] << 16) | values[2]) >>> 0;\n\t} else {\n\t\tif (values.some((value) => value > 0xff)) return null;\n\t\tipAsUint32 = ((values[0] << 24) | (values[1] << 16) | (values[2] << 8) | values[3]) >>> 0;\n\t}\n\n\tconst oct1 = (ipAsUint32 >>> 24) & 0xff;\n\tconst oct2 = (ipAsUint32 >>> 16) & 0xff;\n\tconst oct3 = (ipAsUint32 >>> 8) & 0xff;\n\tconst oct4 = ipAsUint32 & 0xff;\n\treturn `${oct1}.${oct2}.${oct3}.${oct4}`;\n}\n\n/**\n * Validate and sanitize a domain name for DNS queries.\n * Rejects localhost, private/reserved TLDs, IP addresses, and malformed domains.\n */\n\nexport function validateDomain(input: string): ValidationResult {\n\tif (!input || typeof input !== 'string') {\n\t\treturn { valid: false, error: 'Domain name is required' };\n\t}\n\n\t// Check for invisible/non-printable Unicode (except space, dot, hyphen)\n\tconst invisiblePattern = /[\\p{C}\\p{Zl}\\p{Zp}\\u200B-\\u200D\\uFEFF]/gu;\n\tif (invisiblePattern.test(input)) {\n\t\treturn { valid: false, error: 'Domain contains invalid Unicode or cannot be converted to ASCII' };\n\t}\n\tconst cleaned = input.replace(invisiblePattern, '').trim();\n\tif (cleaned.length === 0) {\n\t\treturn { valid: false, error: 'Domain name is required' };\n\t}\n\n\t// Normalize Unicode to NFC, lowercase, remove trailing dot\n\tlet domain = cleaned.normalize('NFC').toLowerCase();\n\tif (domain.endsWith('.')) domain = domain.slice(0, -1);\n\n\t// Convert Unicode/emoji/IDN to punycode for validation\n\tlet asciiDomain: string;\n\ttry {\n\t\tasciiDomain = punycode.toASCII(domain);\n\t} catch {\n\t\treturn { valid: false, error: 'Domain contains invalid Unicode or cannot be converted to ASCII' };\n\t}\n\n\tif (asciiDomain.length > MAX_DOMAIN_LENGTH) {\n\t\treturn { valid: false, error: `Domain exceeds maximum length of ${MAX_DOMAIN_LENGTH} characters` };\n\t}\n\n\t// Check blocked exact hostnames\n\tif (BLOCKED_HOSTS.includes(asciiDomain)) {\n\t\treturn { valid: false, error: `Domain \"${asciiDomain}\" is not allowed: reserved hostname` };\n\t}\n\n\t// Check blocked suffixes\n\tfor (const suffix of BLOCKED_SUFFIXES) {\n\t\tif (asciiDomain === suffix.slice(1) || asciiDomain.endsWith(suffix)) {\n\t\t\treturn { valid: false, error: `Domain \"${asciiDomain}\" is not allowed: reserved TLD \"${suffix}\"` };\n\t\t}\n\t}\n\n\t// Canonicalize non-standard IPv4 literals (e.g. 127.1, 0177.0.0.1)\n\t// and reject all IP literal forms (public, private, and special).\n\tconst canonicalIpv4 = canonicalizeIpv4Literal(asciiDomain);\n\tif (canonicalIpv4) {\n\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t}\n\n\t// Reject dotted numeric host literals that are IPv4-like but malformed/out-of-range.\n\tif (/^\\d+(?:\\.\\d+){1,3}$/.test(asciiDomain)) {\n\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t}\n\n\t// Check if it looks like an IP address (blocked)\n\tfor (const pattern of BLOCKED_IP_PATTERNS) {\n\t\tif (pattern.test(asciiDomain)) {\n\t\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t\t}\n\t}\n\n\t// Check for DNS rebinding services\n\tfor (const suffix of BLOCKED_DNS_REBINDING) {\n\t\tif (asciiDomain === suffix.slice(1) || asciiDomain.endsWith(suffix)) {\n\t\t\treturn { valid: false, error: 'Domain uses a DNS rebinding service and is not allowed' };\n\t\t}\n\t}\n\n\t// Validate domain label structure (punycode labels)\n\tconst labels = asciiDomain.split('.');\n\tif (labels.length < 2) {\n\t\treturn { valid: false, error: 'Domain must have at least two labels (e.g., example.com)' };\n\t}\n\tfor (const label of labels) {\n\t\tif (label.length === 0) {\n\t\t\treturn { valid: false, error: 'Domain contains empty label (consecutive dots)' };\n\t\t}\n\t\t// Strip HTML/script tags from label before including in error messages\n\t\tconst safeLabel = label.replace(/[<>]/g, '').slice(0, 63);\n\t\tif (label.length > MAX_LABEL_LENGTH) {\n\t\t\treturn { valid: false, error: `Label \"${safeLabel}\" exceeds maximum length of ${MAX_LABEL_LENGTH} characters` };\n\t\t}\n\t\tif (!LABEL_REGEX.test(label)) {\n\t\t\treturn { valid: false, error: `Label \"${safeLabel}\" contains invalid characters` };\n\t\t}\n\t}\n\n\treturn { valid: true };\n}\n\n/**\n * Sanitize a domain string: trim, lowercase, remove trailing dot.\n * Call validateDomain first to ensure the domain is valid.\n */\nexport function sanitizeDomain(input: string): string {\n\t// Remove invisible/non-printable Unicode (except space, dot, hyphen)\n\tconst cleaned = input.replace(/[\\p{C}\\p{Zl}\\p{Zp}\\u200B-\\u200D\\uFEFF]/gu, '').trim();\n\tif (cleaned.length === 0) return '';\n\tlet domain = cleaned.normalize('NFC').toLowerCase();\n\tif (domain.endsWith('.')) domain = domain.slice(0, -1);\n\t// Convert Unicode/emoji/IDN to punycode for DNS queries\n\ttry {\n\t\treturn punycode.toASCII(domain);\n\t} catch {\n\t\treturn '';\n\t}\n}\n\n/**\n * Sanitize arbitrary text input for safe logging/display.\n * Removes control characters except newlines and tabs, and truncates length.\n */\nexport function sanitizeInput(input: string, maxLength = 500): string {\n\tif (typeof input !== 'string') return '';\n\tconst sanitized = input.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\treturn sanitized.slice(0, maxLength);\n}\n\n\n","// SPDX-License-Identifier: BUSL-1.1\n\n/** Server version — keep in sync with package.json */\nexport const SERVER_VERSION = '2.2.1';\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\n\n/**\n * Domain name — shape validation only (length 1-253).\n *\n * Intentional two-layer design: this schema validates the string shape so Zod can\n * reject obviously invalid input early (empty strings, oversized payloads). The\n * second layer — `validateDomain()` + `sanitizeDomain()` from `lib/sanitize.ts` —\n * handles structural validation (label rules, TLD checks), SSRF protection\n * (blocked IPs/TLDs), and punycode normalization. That second layer runs after Zod\n * in `extractAndValidateDomain()` (handlers/tool-args.ts).\n */\nexport const DomainSchema = z.string().min(1).max(253);\n\n/** Session ID — exactly 64 lowercase hex characters. */\nexport const SessionIdSchema = z.string().regex(/^[0-9a-f]{64}$/);\n\n/** DKIM selector — valid DNS label, max 63 chars. Trims and lowercases input before validation. */\nexport const DkimSelectorSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.string().max(63).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/));\n\n/** Internal route tool name — lowercase + underscores, max 30 chars. */\nexport const ToolNameSchema = z.string().min(1).max(30).regex(/^[a-z_]+$/);\n\n/** Safe label for array elements (provider names, MX hosts). */\nexport const SafeLabelSchema = z.string().min(1).max(253);\n\n/** Scoring profile (with auto). Used by scan_domain. Trims and lowercases input. */\nexport const ProfileSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['auto', 'mail_enabled', 'enterprise_mail', 'non_mail', 'web_only', 'minimal']));\n\n/** Scoring profile (without auto). Used by get_benchmark, get_provider_insights. Trims and lowercases input. */\nexport const BenchmarkProfileSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['mail_enabled', 'enterprise_mail', 'non_mail', 'web_only', 'minimal']));\n\n/** Output format. Trims and lowercases input before validation. */\nexport const FormatSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['full', 'compact']));\n\n/** DNS record type for resolver consistency. Trims and uppercases input before validation. */\nexport const RecordTypeSchema = z.string().transform(s => s.trim().toUpperCase()).pipe(z.enum(['A', 'AAAA', 'MX', 'TXT', 'NS', 'CNAME', 'SOA', 'CAA']));\n\n/** Security grade. */\nexport const GradeSchema = z.enum(['A+', 'A', 'B+', 'B', 'C+', 'C', 'D+', 'D', 'F']);\n\n/** API key tier. */\nexport const TierSchema = z.enum(['free', 'agent', 'developer', 'enterprise', 'partner', 'owner']);\n\n/** DMARC policy for generate_dmarc_record. Trims and lowercases input. */\nexport const DmarcPolicySchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['none', 'quarantine', 'reject']));\n\n/** Explain finding status values. Trims and lowercases input. */\nexport const ExplainStatusSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['pass', 'fail', 'warning', 'critical', 'high', 'medium', 'low', 'info']));\n\n/** Inferred types for external use. */\nexport type Profile = z.infer<typeof ProfileSchema>;\nexport type BenchmarkProfile = z.infer<typeof BenchmarkProfileSchema>;\nexport type OutputFormat = z.infer<typeof FormatSchema>;\nexport type Grade = z.infer<typeof GradeSchema>;\nexport type Tier = z.infer<typeof TierSchema>;\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\nimport {\n\tDomainSchema,\n\tFormatSchema,\n\tProfileSchema,\n\tBenchmarkProfileSchema,\n\tDkimSelectorSchema,\n\tRecordTypeSchema,\n\tGradeSchema,\n\tSafeLabelSchema,\n\tDmarcPolicySchema,\n\tExplainStatusSchema,\n} from './primitives';\n\n/** Domain + optional format — shared by most check tools. */\nexport const BaseDomainArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** scan_domain */\nexport const ScanDomainArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tprofile: ProfileSchema.optional().describe('Scoring profile. Default \"auto\" detects.'),\n\tforce_refresh: z.boolean().optional().describe('Bypass cache and run a fresh scan. Useful after DNS changes.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** batch_scan */\nexport const BatchScanArgs = z.object({\n\tdomains: z.array(z.string().min(1).max(253)).min(1).max(10).describe('Domains to scan (max 10 per request)'),\n\tforce_refresh: z.boolean().optional().describe('Bypass cache and run fresh scans.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** compare_domains */\nexport const CompareDomainsArgs = z.object({\n\tdomains: z.array(z.string().min(1).max(253)).min(2).max(5).describe('Domains to compare (2–5 domains)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** check_dkim */\nexport const CheckDkimArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tselector: DkimSelectorSchema.optional().describe('DKIM selector. Omit to probe common ones.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** check_resolver_consistency */\nexport const CheckResolverConsistencyArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\trecord_type: RecordTypeSchema.optional().describe('Record type. Omit for A/AAAA/MX/TXT/NS.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_spf_record */\nexport const GenerateSpfArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\t// SafeLabelSchema provides min(1)/max(253); .regex() adds a stacking refinement in Zod v4 (does not override).\n\tinclude_providers: z.array(SafeLabelSchema.regex(/^[a-z0-9._-]+$/i)).max(15).optional().describe('Providers to include (e.g., [\"google\"]).'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_dmarc_record */\nexport const GenerateDmarcArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\tpolicy: DmarcPolicySchema.optional().describe('Policy (default \"reject\").'),\n\trua_email: z.string().max(254).optional().describe('Report email. Default: dmarc-reports@{domain}.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_dkim_config */\nexport const GenerateDkimConfigArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\tprovider: z.string().max(100).optional().describe('Provider (e.g., \"google\"). Omit for generic.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_mta_sts_policy */\nexport const GenerateMtaStsArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\t// SafeLabelSchema provides min(1)/max(253); .regex() adds a stacking refinement in Zod v4 (does not override).\n\tmx_hosts: z.array(SafeLabelSchema.regex(/^[^\\s\\x00-\\x1f\\x7f]*$/)).max(20).optional().describe('MX hosts. Omit to detect from DNS.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** explain_finding */\nexport const ExplainFindingArgs = z.object({\n\tcheckType: z.string().min(1).max(100).describe(\"Check type (e.g., 'SPF', 'DMARC').\"),\n\tstatus: ExplainStatusSchema.describe('Finding severity or status.'),\n\tdetails: z.string().max(2000).optional().describe('Additional detail from check result.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** compare_baseline */\nexport const CompareBaselineArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to scan and compare.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n\tbaseline: z.object({\n\t\tgrade: GradeSchema.optional().describe('Min grade (e.g., \"B+\").'),\n\t\tscore: z.number().min(0).max(100).optional().describe('Min score (0-100).'),\n\t\trequire_dmarc_enforce: z.boolean().optional().describe('Require DMARC enforce.'),\n\t\trequire_spf: z.boolean().optional().describe('Require SPF.'),\n\t\trequire_dkim: z.boolean().optional().describe('Require DKIM.'),\n\t\trequire_dnssec: z.boolean().optional().describe('Require DNSSEC.'),\n\t\trequire_mta_sts: z.boolean().optional().describe('Require MTA-STS.'),\n\t\trequire_caa: z.boolean().optional().describe('Require CAA.'),\n\t\tmax_critical_findings: z.number().int().min(0).optional().describe('Max critical findings (default 0).'),\n\t\tmax_high_findings: z.number().int().min(0).optional().describe('Max high findings allowed.'),\n\t}).passthrough().describe('Policy baseline requirements.'),\n}).passthrough();\n\n/** get_benchmark */\nexport const GetBenchmarkArgs = z.object({\n\tprofile: BenchmarkProfileSchema.optional().describe('Profile to benchmark (default \"mail_enabled\").'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** get_provider_insights */\nexport const GetProviderInsightsArgs = z.object({\n\tprovider: z.string().min(1).describe('Provider (e.g., \"google workspace\").'),\n\tprofile: BenchmarkProfileSchema.optional().describe('Profile (default \"mail_enabled\").'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** assess_spoofability — same as BaseDomainArgs */\nexport const AssessSpoofabilityArgs = BaseDomainArgs;\n\n/** generate_fix_plan — same as BaseDomainArgs */\nexport const GenerateFixPlanArgs = BaseDomainArgs;\n\nconst CheckNameSchema = z.string().transform((v) => v.toLowerCase().trim()).pipe(\n\tz.enum(['spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta_sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'http_security', 'dane']),\n);\n\nconst TimelineSchema = z.string().transform((v) => v.toLowerCase()).pipe(\n\tz.enum(['aggressive', 'standard', 'conservative']),\n);\n\nconst TargetPolicySchema = z.string().transform((v) => v.toLowerCase()).pipe(\n\tz.enum(['quarantine', 'reject']),\n);\n\n/** validate_fix */\nexport const ValidateFixArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to validate the fix for'),\n\tcheck: CheckNameSchema.describe('Check name to re-run (e.g., \"dmarc\", \"spf\")'),\n\texpected: z.string().max(1000).optional().describe('Expected DNS record value to verify against'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** map_supply_chain — same as BaseDomainArgs */\nexport const MapSupplyChainArgs = BaseDomainArgs;\n\n/** analyze_drift */\nexport const AnalyzeDriftArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to analyze drift for'),\n\tbaseline: z.string().min(1).max(50_000).describe('Previous ScanScore JSON or \"cached\" to use last cached scan'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_rollout_plan */\nexport const GenerateRolloutPlanArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to generate rollout plan for'),\n\ttarget_policy: TargetPolicySchema.optional().describe('Target DMARC policy (default: reject)'),\n\ttimeline: TimelineSchema.optional().describe('Rollout speed: aggressive, standard, conservative (default: standard)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/**\n * Map of every tool name to its Zod argument schema.\n * Used for runtime validation in tools.ts and for inputSchema generation.\n */\nexport const TOOL_SCHEMA_MAP: Record<string, z.ZodTypeAny> = {\n\tcheck_mx: BaseDomainArgs,\n\tcheck_spf: BaseDomainArgs,\n\tcheck_dmarc: BaseDomainArgs,\n\tcheck_dkim: CheckDkimArgs,\n\tcheck_dnssec: BaseDomainArgs,\n\tcheck_ssl: BaseDomainArgs,\n\tcheck_mta_sts: BaseDomainArgs,\n\tcheck_ns: BaseDomainArgs,\n\tcheck_caa: BaseDomainArgs,\n\tcheck_bimi: BaseDomainArgs,\n\tcheck_tlsrpt: BaseDomainArgs,\n\tcheck_lookalikes: BaseDomainArgs,\n\tcheck_shadow_domains: BaseDomainArgs,\n\tcheck_txt_hygiene: BaseDomainArgs,\n\tcheck_http_security: BaseDomainArgs,\n\tcheck_dane: BaseDomainArgs,\n\tcheck_dane_https: BaseDomainArgs,\n\tcheck_svcb_https: BaseDomainArgs,\n\tcheck_mx_reputation: BaseDomainArgs,\n\tcheck_srv: BaseDomainArgs,\n\tcheck_zone_hygiene: BaseDomainArgs,\n\tcheck_subdomailing: BaseDomainArgs,\n\tscan_domain: ScanDomainArgs,\n\tbatch_scan: BatchScanArgs,\n\tcompare_domains: CompareDomainsArgs,\n\tcompare_baseline: CompareBaselineArgs,\n\tgenerate_fix_plan: GenerateFixPlanArgs,\n\tgenerate_spf_record: GenerateSpfArgs,\n\tgenerate_dmarc_record: GenerateDmarcArgs,\n\tgenerate_dkim_config: GenerateDkimConfigArgs,\n\tgenerate_mta_sts_policy: GenerateMtaStsArgs,\n\tget_benchmark: GetBenchmarkArgs,\n\tget_provider_insights: GetProviderInsightsArgs,\n\tassess_spoofability: AssessSpoofabilityArgs,\n\tcheck_resolver_consistency: CheckResolverConsistencyArgs,\n\texplain_finding: ExplainFindingArgs,\n\tvalidate_fix: ValidateFixArgs,\n\tmap_supply_chain: MapSupplyChainArgs,\n\tanalyze_drift: AnalyzeDriftArgs,\n\tgenerate_rollout_plan: GenerateRolloutPlanArgs,\n\tresolve_spf_chain: BaseDomainArgs,\n\tdiscover_subdomains: BaseDomainArgs,\n\tmap_compliance: BaseDomainArgs,\n\tsimulate_attack_paths: BaseDomainArgs,\n};\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\nimport {\n\tBaseDomainArgs,\n\tScanDomainArgs,\n\tBatchScanArgs,\n\tCompareDomainsArgs,\n\tCheckDkimArgs,\n\tCheckResolverConsistencyArgs,\n\tGenerateSpfArgs,\n\tGenerateDmarcArgs,\n\tGenerateDkimConfigArgs,\n\tGenerateMtaStsArgs,\n\tExplainFindingArgs,\n\tCompareBaselineArgs,\n\tGetBenchmarkArgs,\n\tGetProviderInsightsArgs,\n\tValidateFixArgs,\n\tMapSupplyChainArgs,\n\tAnalyzeDriftArgs,\n\tGenerateRolloutPlanArgs,\n\tTOOL_SCHEMA_MAP,\n} from './tool-args';\n\nexport type ToolGroup = 'email_auth' | 'infrastructure' | 'brand_threats' | 'dns_hygiene' | 'intelligence' | 'remediation' | 'meta';\nexport type ToolTier = 'core' | 'protective' | 'hardening';\n\nexport interface McpTool {\n\tname: string;\n\tdescription: string;\n\tinputSchema: {\n\t\ttype: string;\n\t\tproperties: Record<string, unknown>;\n\t\trequired?: string[];\n\t\t[key: string]: unknown;\n\t};\n\tannotations?: {\n\t\ttitle?: string;\n\t\treadOnlyHint?: boolean;\n\t\tdestructiveHint?: boolean;\n\t\tidempotentHint?: boolean;\n\t\topenWorldHint?: boolean;\n\t};\n\t/** Functional group for client-side tool discoverability. Not used in dispatch. */\n\tgroup: ToolGroup;\n\t/** Scoring tier from the three-tier model. Absent for non-scoring tools (meta/intelligence/remediation). */\n\ttier?: ToolTier;\n\t/** True when this tool is included in the scan_domain parallel orchestration. */\n\tscanIncluded: boolean;\n}\n\ninterface ToolDef {\n\tdescription: string;\n\tschema: z.ZodTypeAny;\n\tgroup: ToolGroup;\n\ttier?: ToolTier;\n\tscanIncluded: boolean;\n}\n\n/** DNS/security acronyms that should be uppercased in human-readable tool titles. */\nconst KNOWN_ACRONYMS = new Set(['mx', 'spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta', 'sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'http', 'https', 'dane', 'svcb', 'srv', 'txt', 'doh', 'rpm']);\n\n/** Convert a snake_case tool name to a human-readable title. e.g. \"check_mta_sts\" → \"Check MTA STS\" */\nfunction toolNameToTitle(name: string): string {\n\treturn name\n\t\t.split('_')\n\t\t.map((word) => (KNOWN_ACRONYMS.has(word) ? word.toUpperCase() : word.charAt(0).toUpperCase() + word.slice(1)))\n\t\t.join(' ');\n}\n\n/** Convert a Zod schema to a JSON Schema object suitable for MCP inputSchema. */\nfunction toInputSchema(schema: z.ZodTypeAny): McpTool['inputSchema'] {\n\tconst jsonSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n\tdelete jsonSchema.$schema;\n\t// Clean up additionalProperties: {} (equivalent to not having it, but cleaner)\n\tif (\n\t\tjsonSchema.additionalProperties !== undefined &&\n\t\ttypeof jsonSchema.additionalProperties === 'object' &&\n\t\tjsonSchema.additionalProperties !== null &&\n\t\tObject.keys(jsonSchema.additionalProperties).length === 0\n\t) {\n\t\tdelete jsonSchema.additionalProperties;\n\t}\n\treturn jsonSchema as McpTool['inputSchema'];\n}\n\n/** All 43 MCP tool definitions. */\nconst TOOL_DEFS: Record<string, ToolDef> = {\n\tcheck_mx: {\n\t\tdescription: 'Validate MX records and email provider detection.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_spf: {\n\t\tdescription: 'Validate SPF syntax, policy, and trust surface.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dmarc: {\n\t\tdescription: 'Validate DMARC policy, alignment, and reporting.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dkim: {\n\t\tdescription: 'Probe DKIM selectors and validate key strength.',\n\t\tschema: CheckDkimArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dnssec: {\n\t\tdescription: 'Verify DNSSEC validation and DNSKEY/DS records.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_ssl: {\n\t\tdescription: 'Verify SSL/TLS certificate and HTTPS config.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_mta_sts: {\n\t\tdescription: 'Validate MTA-STS SMTP encryption policy.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_ns: {\n\t\tdescription: 'Analyze NS delegation and provider diversity.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_caa: {\n\t\tdescription: 'Check authorized Certificate Authorities via CAA.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_bimi: {\n\t\tdescription: 'Validate BIMI record and VMC evidence.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_tlsrpt: {\n\t\tdescription: 'Validate TLS-RPT SMTP failure reporting.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_http_security: {\n\t\tdescription: 'Audit HTTP security headers (CSP, COOP, etc.).',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dane: {\n\t\tdescription: 'Verify DANE/TLSA certificate pinning.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dane_https: {\n\t\tdescription: 'Verify DANE certificate pinning for HTTPS via TLSA records at _443._tcp.{domain}.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_svcb_https: {\n\t\tdescription: 'Validate HTTPS/SVCB records (RFC 9460) for modern transport capability advertisement.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_lookalikes: {\n\t\tdescription: 'Detect active typosquat/lookalike domains. Standalone.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'protective',\n\t\tscanIncluded: false,\n\t},\n\tcheck_subdomailing: {\n\t\tdescription: 'Detect SubdoMailing risk by analyzing SPF include chain for takeover-vulnerable domains.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tscan_domain: {\n\t\tdescription: 'Full DNS and email security audit. Score, grade, maturity, findings. Start here.',\n\t\tschema: ScanDomainArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tbatch_scan: {\n\t\tdescription: 'Scan up to 10 domains at once. Returns score, grade, and finding counts per domain.',\n\t\tschema: BatchScanArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcompare_domains: {\n\t\tdescription: 'Side-by-side security comparison of 2–5 domains. Shows scores, category gaps, and unique weaknesses.',\n\t\tschema: CompareDomainsArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcompare_baseline: {\n\t\tdescription: 'Compare domain security against a policy baseline.',\n\t\tschema: CompareBaselineArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcheck_shadow_domains: {\n\t\tdescription: 'Find TLD variants with email auth gaps. Standalone.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'protective',\n\t\tscanIncluded: false,\n\t},\n\tcheck_txt_hygiene: {\n\t\tdescription: 'Audit TXT records for stale entries and SaaS exposure.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'dns_hygiene',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_mx_reputation: {\n\t\tdescription: 'Check MX blocklist status and reverse DNS.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_srv: {\n\t\tdescription: 'Probe SRV records for service footprint.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_zone_hygiene: {\n\t\tdescription: 'Audit SOA propagation and sensitive subdomains.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_fix_plan: {\n\t\tdescription: 'Generate prioritized remediation plan with effort estimates.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_spf_record: {\n\t\tdescription: 'Generate corrected SPF record from detected providers.',\n\t\tschema: GenerateSpfArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_dmarc_record: {\n\t\tdescription: 'Generate DMARC record with configurable policy.',\n\t\tschema: GenerateDmarcArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_dkim_config: {\n\t\tdescription: 'Generate DKIM setup instructions and DNS record.',\n\t\tschema: GenerateDkimConfigArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_mta_sts_policy: {\n\t\tdescription: 'Generate MTA-STS record and policy file.',\n\t\tschema: GenerateMtaStsArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tget_benchmark: {\n\t\tdescription: 'Get score benchmarks: percentiles, mean, top failures.',\n\t\tschema: GetBenchmarkArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tget_provider_insights: {\n\t\tdescription: 'Get provider cohort benchmarks and common issues.',\n\t\tschema: GetProviderInsightsArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tassess_spoofability: {\n\t\tdescription: 'Composite email spoofability score (0-100).',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tcheck_resolver_consistency: {\n\t\tdescription: 'Check DNS consistency across 4 public resolvers.',\n\t\tschema: CheckResolverConsistencyArgs,\n\t\tgroup: 'infrastructure',\n\t\tscanIncluded: false,\n\t},\n\texplain_finding: {\n\t\tdescription: 'Explain a finding with impact and remediation.',\n\t\tschema: ExplainFindingArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tmap_supply_chain: {\n\t\tdescription: 'Map third-party service dependencies from DNS records. Correlates SPF, NS, TXT verifications, SRV services, and CAA to show who can send as you, control your DNS, and what services are integrated.',\n\t\tschema: MapSupplyChainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tanalyze_drift: {\n\t\tdescription: 'Compare current security posture against a previous baseline. Shows what improved, regressed, or changed.',\n\t\tschema: AnalyzeDriftArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tvalidate_fix: {\n\t\tdescription: 'Re-check a specific control after applying a fix. Confirms whether the finding is resolved.',\n\t\tschema: ValidateFixArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_rollout_plan: {\n\t\tdescription: 'Generate a phased DMARC enforcement timeline with exact DNS records per phase.',\n\t\tschema: GenerateRolloutPlanArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tresolve_spf_chain: {\n\t\tdescription: 'Recursively resolve the full SPF include chain. Shows lookup count, tree depth, and flags issues like circular includes or exceeding the 10-lookup limit.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tdiscover_subdomains: {\n\t\tdescription: 'Discover subdomains via Certificate Transparency logs. Reveals shadow IT, forgotten services, and unauthorized certificate issuance.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tmap_compliance: {\n\t\tdescription: 'Map scan findings to compliance frameworks: NIST 800-177, PCI DSS 4.0, SOC 2, CIS Controls. Shows pass/fail/partial status per control.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tsimulate_attack_paths: {\n\t\tdescription: 'Analyze current DNS posture and enumerate specific attack paths an adversary could exploit, with severity, feasibility, steps, and mitigations.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n};\n\nexport const TOOLS: McpTool[] = Object.entries(TOOL_DEFS).map(([name, def]) => ({\n\tname,\n\tdescription: def.description,\n\tinputSchema: toInputSchema(def.schema),\n\tannotations: {\n\t\ttitle: toolNameToTitle(name),\n\t\treadOnlyHint: true,\n\t\tdestructiveHint: false,\n\t\tidempotentHint: true,\n\t\topenWorldHint: true,\n\t},\n\tgroup: def.group,\n\t...(def.tier !== undefined && { tier: def.tier }),\n\tscanIncluded: def.scanIncluded,\n}));\n\nexport { TOOL_SCHEMA_MAP };\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * BIMI (Brand Indicators for Message Identification) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkBIMI } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check BIMI records for a domain.\n * Validates the presence and configuration of BIMI TXT records,\n * including logo URL format and VMC authority evidence.\n */\nexport async function checkBimi(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkBIMI(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * CAA (Certificate Authority Authorization) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkCAA } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check CAA records for a domain.\n * Validates that CAA records exist and are properly configured.\n */\nexport async function checkCaa(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkCAA(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DKIM (DomainKeys Identified Mail) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n * Retains applyProviderDkimContext for scan_domain post-processing.\n */\n\nimport { checkDKIM, createFinding, buildCheckResult } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\n/**\n * Email providers with high confidence of default DKIM signing.\n */\nconst HIGH_CONFIDENCE_DKIM_PROVIDERS = new Set([\n\t'amazon ses',\n\t'sendgrid',\n\t'mailgun',\n\t'postmark',\n\t'google workspace',\n\t'microsoft 365',\n]);\n\n/**\n * Email providers that typically sign with DKIM but vary by configuration.\n */\nconst MEDIUM_CONFIDENCE_DKIM_PROVIDERS = new Set(['proofpoint', 'mimecast']);\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DKIM records for a domain.\n * Probes common selectors at <selector>._domainkey.<domain>.\n * Optionally accepts a specific selector to check.\n */\nexport async function checkDkim(domain: string, selector?: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDKIM(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000, selector },\n\t) as Promise<CheckResult>;\n}\n\n/**\n * Apply provider-informed context to DKIM results.\n * Called as a post-processing step in scan_domain after MX-based provider detection completes.\n * When a known DKIM-signing provider is detected, downgrades the \"No DKIM records found\"\n * finding from HIGH to MEDIUM since the provider likely signs outbound mail by default.\n */\nexport function applyProviderDkimContext(dkimResult: CheckResult, provider: string): CheckResult {\n\tconst normalizedProvider = provider.toLowerCase();\n\tconst notFoundIdx = dkimResult.findings.findIndex(\n\t\t(f) => /No DKIM records found/i.test(f.title) && f.severity === 'high',\n\t);\n\tif (notFoundIdx === -1) return dkimResult;\n\n\tconst selectorsChecked = (dkimResult.findings[notFoundIdx].metadata?.selectorsChecked as string[]) ?? [];\n\tconst newFindings = [...dkimResult.findings];\n\n\tif (HIGH_CONFIDENCE_DKIM_PROVIDERS.has(normalizedProvider)) {\n\t\tnewFindings[notFoundIdx] = createFinding(\n\t\t\t'dkim',\n\t\t\t'DKIM selector not discovered',\n\t\t\t'medium',\n\t\t\t`No DKIM selectors were found among the tested set, but ${provider} is detected as the email provider and signs outbound mail by default. DKIM is likely present with a custom selector.`,\n\t\t\t{\n\t\t\t\tconfidence: 'heuristic',\n\t\t\t\tdetectionMethod: 'provider-implied',\n\t\t\t\tprovider: normalizedProvider,\n\t\t\t\tselectorsChecked,\n\t\t\t},\n\t\t);\n\t} else if (MEDIUM_CONFIDENCE_DKIM_PROVIDERS.has(normalizedProvider)) {\n\t\tnewFindings[notFoundIdx] = createFinding(\n\t\t\t'dkim',\n\t\t\t'DKIM selector not discovered',\n\t\t\t'medium',\n\t\t\t`No DKIM selectors were found among the tested set. ${provider} is detected as the email provider and typically signs outbound mail.`,\n\t\t\t{\n\t\t\t\tconfidence: 'heuristic',\n\t\t\t\tdetectionMethod: 'provider-implied',\n\t\t\t\tprovider: normalizedProvider,\n\t\t\t\tselectorsChecked,\n\t\t\t},\n\t\t);\n\t\tnewFindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'dkim',\n\t\t\t\t'DKIM provider signing unverified',\n\t\t\t\t'low',\n\t\t\t\t`${provider} signing policy varies by configuration — DKIM presence cannot be confirmed without selector discovery.`,\n\t\t\t\t{ confidence: 'heuristic' },\n\t\t\t),\n\t\t);\n\t}\n\n\treturn buildCheckResult('dkim', newFindings) as CheckResult;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DMARC (Domain-based Message Authentication, Reporting & Conformance) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDMARC } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nexport { parseDmarcTags } from '@blackveil/dns-checks';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DMARC records for a domain.\n * Queries _dmarc.<domain> TXT records and validates policy configuration.\n */\nexport async function checkDmarc(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDMARC(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DNSSEC (DNS Security Extensions) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDNSSEC } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { buildCheckResult, createFinding } from '../lib/scoring';\nimport type { CheckResult } from '../lib/scoring';\n\nexport { parseDnskeyAlgorithm, parseDsRecord } from '@blackveil/dns-checks';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DNSSEC configuration for a domain.\n * Verifies the AD (Authenticated Data) flag, checks for DNSKEY/DS records,\n * and audits algorithm and digest type security.\n * Augments results with dnssecSource metadata: 'domain_configured' or 'tld_inherited'.\n */\nexport async function checkDnssec(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\tconst baseResult = await checkDNSSEC(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as CheckResult;\n\n\t// Skip augmentation when DNSSEC is definitively absent, failed, or misconfigured at the domain level.\n\t// 'DNSSEC chain of trust incomplete' means the domain has DNSKEY but no DS — it is domain-operator-configured\n\t// (just broken), not TLD-inherited. 'DNSSEC validation failing' means records exist but fail verification.\n\tconst dnssecAbsent =\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC not enabled') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC check failed') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC chain of trust incomplete') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC validation failing');\n\tif (dnssecAbsent) {\n\t\treturn baseResult;\n\t}\n\n\t// Detect whether the domain has its own DNSKEY/DS (domain_configured) or inherits from TLD\n\tconst [dnskeyResult, dsResult] = await Promise.allSettled([\n\t\tqueryDnsRecords(domain, 'DNSKEY', dnsOptions),\n\t\tqueryDnsRecords(domain, 'DS', dnsOptions),\n\t]);\n\n\tconst hasDnskey = dnskeyResult.status === 'fulfilled' && dnskeyResult.value.length > 0;\n\tconst hasDs = dsResult.status === 'fulfilled' && dsResult.value.length > 0;\n\tconst dnssecSource = hasDnskey && hasDs ? 'domain_configured' : 'tld_inherited';\n\n\tif (dnssecSource === 'tld_inherited') {\n\t\tconst inheritedFinding = createFinding(\n\t\t\t'dnssec',\n\t\t\t'DNSSEC inherited from TLD',\n\t\t\t'info',\n\t\t\t`DNSSEC validation passes but ${domain} does not have its own DNSKEY or DS records. DNSSEC protection is inherited from the TLD registry, not configured by the domain owner.`,\n\t\t\t{ dnssecSource: 'tld_inherited' },\n\t\t);\n\t\treturn buildCheckResult('dnssec', [...baseResult.findings, inheritedFinding]);\n\t}\n\n\t// domain_configured — tag the first non-info finding with the source, or add a carrier finding\n\tif (baseResult.findings.length > 0) {\n\t\tconst [first, ...rest] = baseResult.findings;\n\t\tconst tagged = { ...first, metadata: { ...(first.metadata ?? {}), dnssecSource: 'domain_configured' } };\n\t\treturn buildCheckResult('dnssec', [tagged, ...rest]);\n\t}\n\n\tconst configuredFinding = createFinding(\n\t\t'dnssec',\n\t\t'DNSSEC configured by domain owner',\n\t\t'info',\n\t\t`${domain} has DNSKEY and DS records — DNSSEC is explicitly configured by the domain owner.`,\n\t\t{ dnssecSource: 'domain_configured' },\n\t);\n\treturn buildCheckResult('dnssec', [configuredFinding]);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Lookalike domain generation utilities.\n * Generates typosquat/lookalike domain permutations using multiple strategies:\n * adjacent key swaps, character omission, character duplication, dot insertion,\n * common TLD swaps, and homoglyph substitution.\n */\n\nimport { LABEL_REGEX, MAX_DOMAIN_LENGTH, MAX_LABEL_LENGTH } from '../lib/config';\n\n/** QWERTY keyboard adjacency map for typosquat detection */\nconst QWERTY_ADJACENT: Record<string, string[]> = {\n\tq: ['w', 'a'],\n\tw: ['q', 'e', 's', 'a'],\n\te: ['w', 'r', 'd', 's'],\n\tr: ['e', 't', 'f', 'd'],\n\tt: ['r', 'y', 'g', 'f'],\n\ty: ['t', 'u', 'h', 'g'],\n\tu: ['y', 'i', 'j', 'h'],\n\ti: ['u', 'o', 'k', 'j'],\n\to: ['i', 'p', 'l', 'k'],\n\tp: ['o', 'l'],\n\ta: ['q', 'w', 's', 'z'],\n\ts: ['a', 'w', 'e', 'd', 'z', 'x'],\n\td: ['s', 'e', 'r', 'f', 'x', 'c'],\n\tf: ['d', 'r', 't', 'g', 'c', 'v'],\n\tg: ['f', 't', 'y', 'h', 'v', 'b'],\n\th: ['g', 'y', 'u', 'j', 'b', 'n'],\n\tj: ['h', 'u', 'i', 'k', 'n', 'm'],\n\tk: ['j', 'i', 'o', 'l', 'm'],\n\tl: ['k', 'o', 'p'],\n\tz: ['a', 's', 'x'],\n\tx: ['z', 's', 'd', 'c'],\n\tc: ['x', 'd', 'f', 'v'],\n\tv: ['c', 'f', 'g', 'b'],\n\tb: ['v', 'g', 'h', 'n'],\n\tn: ['b', 'h', 'j', 'm'],\n\tm: ['n', 'j', 'k'],\n};\n\n/** Homoglyph substitution pairs (one substitution at a time) */\nconst HOMOGLYPHS: Array<[string, string]> = [\n\t['o', '0'],\n\t['0', 'o'],\n\t['l', '1'],\n\t['1', 'l'],\n\t['i', '1'],\n\t['1', 'i'],\n\t['l', 'i'],\n\t['i', 'l'],\n\t['rn', 'm'],\n\t['m', 'rn'],\n\t['vv', 'w'],\n\t['w', 'vv'],\n];\n\n/** Common TLD swap pairs */\nconst TLD_SWAPS: Array<[string, string]> = [\n\t['.com', '.co'],\n\t['.com', '.net'],\n\t['.com', '.org'],\n\t['.com', '.io'],\n\t['.co.nz', '.com'],\n\t['.com.au', '.com'],\n];\n\n/** Maximum number of permutations to return */\nconst MAX_PERMUTATIONS = 50;\n\n/**\n * Split a domain into base (before TLD) and TLD parts.\n * Handles multi-part TLDs like .co.nz and .com.au.\n */\nfunction splitDomainTld(domain: string): { base: string; tld: string } {\n\tconst multiPartTlds = ['.co.nz', '.com.au', '.co.uk', '.org.uk', '.net.au', '.org.au'];\n\tfor (const multiTld of multiPartTlds) {\n\t\tif (domain.endsWith(multiTld)) {\n\t\t\treturn { base: domain.slice(0, -multiTld.length), tld: multiTld };\n\t\t}\n\t}\n\tconst lastDot = domain.lastIndexOf('.');\n\tif (lastDot === -1) return { base: domain, tld: '' };\n\treturn { base: domain.slice(0, lastDot), tld: domain.slice(lastDot) };\n}\n\n/**\n * Check whether a domain string is structurally valid.\n * Labels must be 1-63 chars, alphanumeric + hyphens, total <= 253 chars.\n */\nfunction isDomainValid(domain: string): boolean {\n\tif (domain.length > MAX_DOMAIN_LENGTH) return false;\n\tconst labels = domain.split('.');\n\tif (labels.length < 2) return false;\n\tfor (const label of labels) {\n\t\tif (label.length === 0 || label.length > MAX_LABEL_LENGTH) return false;\n\t\tif (!LABEL_REGEX.test(label)) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Generate lookalike/typosquat domain permutations for a given domain.\n * Applies six strategies: adjacent key swaps, character omission, character duplication,\n * dot insertion, common TLD swaps, and homoglyph substitution.\n *\n * Returns up to 50 unique, valid, alphabetically sorted permutations.\n */\nexport function generateLookalikes(domain: string): string[] {\n\tconst normalizedDomain = domain.toLowerCase();\n\tconst { base, tld } = splitDomainTld(normalizedDomain);\n\tconst candidates = new Set<string>();\n\n\t// 1. Adjacent key swaps — swap each char in base with QWERTY adjacent keys\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst ch = base[i];\n\t\tconst adjacent = QWERTY_ADJACENT[ch];\n\t\tif (adjacent) {\n\t\t\tfor (const adj of adjacent) {\n\t\t\t\tconst permuted = base.slice(0, i) + adj + base.slice(i + 1);\n\t\t\t\tcandidates.add(permuted + tld);\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Character omission — remove one char at a time from base\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst permuted = base.slice(0, i) + base.slice(i + 1);\n\t\tif (permuted.length > 0) {\n\t\t\tcandidates.add(permuted + tld);\n\t\t}\n\t}\n\n\t// 3. Character duplication — double one char at a time in base\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst permuted = base.slice(0, i) + base[i] + base[i] + base.slice(i + 1);\n\t\tcandidates.add(permuted + tld);\n\t}\n\n\t// 4. Dot insertion — insert dots between chars in base (both parts must be >= 2 chars)\n\tfor (let i = 1; i < base.length; i++) {\n\t\tconst left = base.slice(0, i);\n\t\tconst right = base.slice(i);\n\t\tif (left.length >= 2 && right.length >= 2) {\n\t\t\tcandidates.add(left + '.' + right + tld);\n\t\t}\n\t}\n\n\t// 5. Common TLD swaps — swap to different TLD if original matches\n\tfor (const [fromTld, toTld] of TLD_SWAPS) {\n\t\tif (tld === fromTld) {\n\t\t\tcandidates.add(base + toTld);\n\t\t} else if (tld === toTld) {\n\t\t\tcandidates.add(base + fromTld);\n\t\t}\n\t}\n\n\t// 6. Homoglyph substitution — one substitution at a time in base\n\tfor (const [from, to] of HOMOGLYPHS) {\n\t\tlet searchIdx = 0;\n\t\twhile (searchIdx <= base.length - from.length) {\n\t\t\tconst idx = base.indexOf(from, searchIdx);\n\t\t\tif (idx === -1) break;\n\t\t\tconst permuted = base.slice(0, idx) + to + base.slice(idx + from.length);\n\t\t\tcandidates.add(permuted + tld);\n\t\t\tsearchIdx = idx + 1;\n\t\t}\n\t}\n\n\t// Filter, dedup, and cap\n\tconst results = Array.from(candidates)\n\t\t.filter((candidate) => candidate !== normalizedDomain && isDomainValid(candidate))\n\t\t.sort();\n\n\treturn results.slice(0, MAX_PERMUTATIONS);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Lookalike domain detection tool.\n * Generates typosquat/lookalike domain permutations and checks for\n * active DNS registrations and mail infrastructure.\n * Standalone check — not included in scan_domain due to query volume.\n */\n\nimport { queryDnsRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult, Finding } from '../lib/scoring';\nimport { buildCheckResult, createFinding } from '../lib/scoring';\nimport { generateLookalikes } from './lookalike-analysis';\n\n/** Default and minimum batch sizes for adaptive batching */\nexport const INITIAL_BATCH_SIZE = 10;\nexport const MIN_BATCH_SIZE = 3;\nexport const BACKOFF_DELAY_MS = 500;\nexport const FAILURE_THRESHOLD = 2;\n\n/** Maximum wall-clock time for the entire lookalike check (ms). */\nconst LOOKALIKE_TIMEOUT_MS = 20_000;\n\n/** Canary label used for wildcard detection on parent domains */\nexport const WILDCARD_CANARY_LABEL = '_bv-wc-probe';\n\n/** Lean DNS options for Phase 1 existence checks — fast, no retries, no secondary confirmation. */\nexport const PHASE1_DNS_OPTS: QueryDnsOptions = {\n\ttimeoutMs: 2000,\n\tretries: 0,\n\tskipSecondaryConfirmation: true,\n};\n\ninterface LookalikeResult {\n\tdomain: string;\n\thasA: boolean;\n\thasMX: boolean;\n}\n\n/** Minimum number of NS records that must overlap to consider domains as sharing nameservers. */\nconst SHARED_NS_THRESHOLD = 1;\n\n/**\n * Check whether an MX record represents real mail infrastructure.\n * RFC 7505 null MX (\"0 .\") explicitly means \"no mail accepted\" and must be excluded.\n */\nfunction isRealMxRecord(data: string): boolean {\n\t// Null MX: priority 0, exchange \".\" — RFC 7505\n\tconst trimmed = data.trim();\n\treturn trimmed !== '0 .' && trimmed !== '0\\t.';\n}\n\n/**\n * Check a single lookalike domain for DNS and MX records.\n * Filters out null MX records (RFC 7505) to avoid false positives.\n */\nasync function probeLookalike(domain: string): Promise<LookalikeResult> {\n\tconst [aRecords, mxRecords] = await Promise.allSettled([\n\t\tqueryDnsRecords(domain, 'A'),\n\t\tqueryDnsRecords(domain, 'MX'),\n\t]);\n\n\tconst realMxRecords =\n\t\tmxRecords.status === 'fulfilled' ? mxRecords.value.filter(isRealMxRecord) : [];\n\n\treturn {\n\t\tdomain,\n\t\thasA: aRecords.status === 'fulfilled' && aRecords.value.length > 0,\n\t\thasMX: realMxRecords.length > 0,\n\t};\n}\n\n/**\n * Count the number of labels (dot-separated segments) in a domain.\n */\nfunction labelCount(domain: string): number {\n\treturn domain.split('.').length;\n}\n\n/**\n * Extract the parent domain from a dot-insertion permutation.\n * E.g., \"blackve.ilsecurity.com\" → \"ilsecurity.com\"\n */\nfunction getParentDomain(domain: string): string {\n\tconst parts = domain.split('.');\n\treturn parts.slice(1).join('.');\n}\n\n/**\n * Detect wildcard DNS on a set of parent domains by probing a canary subdomain.\n * Returns a Set of parent domains that have wildcard A records.\n */\nasync function detectWildcardParents(parentDomains: string[]): Promise<Set<string>> {\n\tconst wildcardParents = new Set<string>();\n\tconst probes = parentDomains.map(async (parent) => {\n\t\ttry {\n\t\t\tconst canary = `${WILDCARD_CANARY_LABEL}.${parent}`;\n\t\t\tconst records = await queryDnsRecords(canary, 'A');\n\t\t\tif (records.length > 0) {\n\t\t\t\twildcardParents.add(parent);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Query failed — not a wildcard\n\t\t}\n\t});\n\tawait Promise.allSettled(probes);\n\treturn wildcardParents;\n}\n\n/**\n * Phase 1: Fast NS existence check for all domains in parallel.\n * Returns only domains that have NS records (i.e., are registered),\n * along with their normalized NS record data for ownership comparison.\n */\nasync function filterByNsExistence(domains: string[]): Promise<{ registered: string[]; nsMap: Map<string, Set<string>> }> {\n\tconst nsMap = new Map<string, Set<string>>();\n\tconst results = await Promise.allSettled(\n\t\tdomains.map(async (domain) => {\n\t\t\tconst ns = await queryDnsRecords(domain, 'NS', PHASE1_DNS_OPTS);\n\t\t\tif (ns.length > 0) {\n\t\t\t\tnsMap.set(domain, normalizeNsSet(ns));\n\t\t\t}\n\t\t\treturn { domain, hasNs: ns.length > 0 };\n\t\t}),\n\t);\n\tconst registered = results\n\t\t.filter(\n\t\t\t(r): r is PromiseFulfilledResult<{ domain: string; hasNs: boolean }> =>\n\t\t\t\tr.status === 'fulfilled' && r.value.hasNs,\n\t\t)\n\t\t.map((r) => r.value.domain);\n\treturn { registered, nsMap };\n}\n\n/**\n * Normalize a set of NS record values for comparison.\n * Strips trailing dots, lowercases, and returns a Set.\n */\nfunction normalizeNsSet(nsRecords: string[]): Set<string> {\n\treturn new Set(nsRecords.map((ns) => ns.replace(/\\.$/, '').toLowerCase()));\n}\n\n/**\n * Check whether two NS sets share at least SHARED_NS_THRESHOLD nameservers.\n * Shared nameservers are a strong signal that both domains are controlled by the same entity.\n */\nfunction sharesNameservers(primaryNs: Set<string>, lookalikeNs: Set<string>): boolean {\n\tlet overlap = 0;\n\tfor (const ns of lookalikeNs) {\n\t\tif (primaryNs.has(ns)) {\n\t\t\toverlap++;\n\t\t\tif (overlap >= SHARED_NS_THRESHOLD) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Query NS records for the primary domain to use for ownership comparison.\n * Returns an empty set if the query fails.\n */\nasync function queryPrimaryNs(domain: string): Promise<Set<string>> {\n\ttry {\n\t\tconst ns = await queryDnsRecords(domain, 'NS', PHASE1_DNS_OPTS);\n\t\treturn normalizeNsSet(ns);\n\t} catch {\n\t\treturn new Set<string>();\n\t}\n}\n\n/**\n * Run permutation probes with adaptive batch sizing and backoff.\n * Starts at INITIAL_BATCH_SIZE, halves on repeated failures (floor at MIN_BATCH_SIZE),\n * recovers on clean batches.\n */\nasync function probeWithAdaptiveBatching(\n\tpermutations: string[],\n): Promise<PromiseSettledResult<LookalikeResult>[]> {\n\tconst allResults: PromiseSettledResult<LookalikeResult>[] = [];\n\tlet batchSize = INITIAL_BATCH_SIZE;\n\tlet delayMs = 0;\n\n\tfor (let i = 0; i < permutations.length; i += batchSize) {\n\t\tif (delayMs > 0) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, delayMs));\n\t\t}\n\n\t\tconst batch = permutations.slice(i, i + batchSize);\n\t\tconst batchResults = await Promise.allSettled(batch.map((d) => probeLookalike(d)));\n\t\tallResults.push(...batchResults);\n\n\t\t// Count failures in this batch\n\t\tconst failures = batchResults.filter((r) => r.status === 'rejected').length;\n\t\tif (failures > FAILURE_THRESHOLD) {\n\t\t\t// Back off: halve batch size (floor to MIN_BATCH_SIZE) and add delay\n\t\t\tbatchSize = Math.max(MIN_BATCH_SIZE, Math.floor(batchSize / 2));\n\t\t\tdelayMs = BACKOFF_DELAY_MS;\n\t\t} else if (delayMs > 0 && failures === 0) {\n\t\t\t// Recover: if a clean batch after backoff, try increasing again\n\t\t\tbatchSize = Math.min(INITIAL_BATCH_SIZE, batchSize + 2);\n\t\t\tdelayMs = 0;\n\t\t}\n\t}\n\n\treturn allResults;\n}\n\n/**\n * Detect registered lookalike/typosquat domains with DNS or mail infrastructure.\n * Generates domain permutations and checks for active registrations using adaptive batching.\n * Filters out false positives from wildcard DNS on parent domains and null MX records.\n */\nexport async function checkLookalikes(domain: string): Promise<CheckResult> {\n\treturn Promise.race([\n\t\tcheckLookalikesCore(domain),\n\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('Lookalike check timed out')), LOOKALIKE_TIMEOUT_MS)),\n\t]).catch(() => {\n\t\treturn buildCheckResult('lookalikes', [\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'Lookalike check incomplete',\n\t\t\t\t'info',\n\t\t\t\t'Lookalike check did not complete. This check generates many DNS queries — try again shortly, as partial results are cached.',\n\t\t\t),\n\t\t]);\n\t});\n}\n\nasync function checkLookalikesCore(domain: string): Promise<CheckResult> {\n\tconst findings: Finding[] = [];\n\tconst permutations = generateLookalikes(domain);\n\n\tif (permutations.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`No lookalike domain permutations could be generated for ${domain}.`,\n\t\t\t),\n\t\t);\n\t\treturn buildCheckResult('lookalikes', findings);\n\t}\n\n\t// Identify dot-insertion permutations (they have more labels than the original domain)\n\tconst originalLabelCount = labelCount(domain);\n\tconst dotInsertionParents = new Map<string, string[]>(); // parent → [permutations]\n\tconst nonDotInsertionPerms: string[] = [];\n\n\tfor (const perm of permutations) {\n\t\tif (labelCount(perm) > originalLabelCount) {\n\t\t\tconst parent = getParentDomain(perm);\n\t\t\tconst existing = dotInsertionParents.get(parent);\n\t\t\tif (existing) {\n\t\t\t\texisting.push(perm);\n\t\t\t} else {\n\t\t\t\tdotInsertionParents.set(parent, [perm]);\n\t\t\t}\n\t\t} else {\n\t\t\tnonDotInsertionPerms.push(perm);\n\t\t}\n\t}\n\n\t// Detect wildcard DNS on parent domains of dot-insertion permutations\n\tconst wildcardParents = dotInsertionParents.size > 0\n\t\t? await detectWildcardParents([...dotInsertionParents.keys()])\n\t\t: new Set<string>();\n\n\t// Filter out permutations whose parent has wildcard DNS\n\tconst filteredDotInsertionPerms: string[] = [];\n\tfor (const [parent, perms] of dotInsertionParents) {\n\t\tif (!wildcardParents.has(parent)) {\n\t\t\tfilteredDotInsertionPerms.push(...perms);\n\t\t}\n\t}\n\n\tconst permsToProbe = [...nonDotInsertionPerms, ...filteredDotInsertionPerms];\n\n\t// Phase 1: Fast NS existence check — filter out unregistered domains\n\t// Also query the primary domain's NS for ownership comparison\n\tconst [nsResult, primaryNs] = await Promise.all([\n\t\tfilterByNsExistence(permsToProbe),\n\t\tqueryPrimaryNs(domain),\n\t]);\n\tconst { registered: registeredPerms, nsMap: lookalikeNsMap } = nsResult;\n\n\tif (registeredPerms.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`Checked ${permutations.length} domain permutations of ${domain}. No active registrations detected.`,\n\t\t\t),\n\t\t);\n\t\treturn buildCheckResult('lookalikes', findings);\n\t}\n\n\t// Phase 2: Detail probe only registered domains\n\tconst probeResults = await probeWithAdaptiveBatching(registeredPerms);\n\tconst results: LookalikeResult[] = [];\n\tfor (const result of probeResults) {\n\t\tif (result.status === 'fulfilled') {\n\t\t\tresults.push(result.value);\n\t\t}\n\t}\n\n\t// Classify results — check for shared nameservers with primary domain to detect defensive registrations\n\tlet highCount = 0;\n\tfor (const result of results) {\n\t\tconst lookalikeNs = lookalikeNsMap.get(result.domain);\n\t\tconst sameOwner = primaryNs.size > 0 && lookalikeNs !== undefined && sharesNameservers(primaryNs, lookalikeNs);\n\n\t\tif (sameOwner) {\n\t\t\t// Shared nameservers — likely a defensive registration by the same entity\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain likely owned by same entity: ${result.domain}`,\n\t\t\t\t\t'info',\n\t\t\t\t\t`The domain ${result.domain} shares nameservers with ${domain}, indicating it is likely a defensive registration by the same owner.${result.hasMX ? ' Has active mail infrastructure.' : ''}${result.hasA ? ' Has web presence.' : ''}`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX, sharedNs: true },\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (result.hasMX) {\n\t\t\thighCount++;\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain with mail infrastructure: ${result.domain}`,\n\t\t\t\t\t'high',\n\t\t\t\t\t`The domain ${result.domain} is registered with active mail servers (MX records), which could be used for phishing or email spoofing targeting ${domain}.`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX },\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (result.hasA) {\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain registered: ${result.domain}`,\n\t\t\t\t\t'medium',\n\t\t\t\t\t`The domain ${result.domain} is registered (has web presence) but no mail infrastructure detected. It could still be used for phishing websites targeting ${domain}.`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX },\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Summary finding for high-severity lookalikes\n\tif (highCount > 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t`${highCount} lookalike domain${highCount > 1 ? 's' : ''} with mail capability detected`,\n\t\t\t\t'high',\n\t\t\t\t`${highCount} lookalike domain${highCount > 1 ? 's' : ''} of ${domain} ${highCount > 1 ? 'have' : 'has'} active mail infrastructure, presenting a phishing risk. Consider monitoring these domains and implementing DMARC with p=reject to protect your brand.`,\n\t\t\t\t{ lookalikeDomainCount: highCount },\n\t\t\t),\n\t\t);\n\t}\n\n\t// If no active lookalikes found\n\tif (findings.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`Checked ${permutations.length} domain permutations of ${domain}. No active registrations with DNS or mail infrastructure detected.`,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn buildCheckResult('lookalikes', findings);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * MTA-STS (Mail Transfer Agent Strict Transport Security) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkMTASTS } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check MTA-STS configuration for a domain.\n * Queries _mta-sts.<domain> TXT records and optionally fetches the policy file.\n */\nexport async function checkMtaSts(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkMTASTS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? HTTPS_TIMEOUT_MS, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nexport interface ProviderSignature {\n\tname: string;\n\tdomains: string[];\n\tselectorHints?: string[];\n}\n\nexport interface ProviderSignaturePayload {\n\tversion?: string;\n\tinbound?: ProviderSignature[];\n\toutbound?: ProviderSignature[];\n}\n\nexport interface ProviderSourceResult {\n\tversion: string;\n\tsource: 'runtime' | 'stale' | 'built-in';\n\tfetchedAt: string;\n\tdegraded: boolean;\n\tinbound: ProviderSignature[];\n\toutbound: ProviderSignature[];\n}\n\nexport interface LoadProviderSignaturesOptions {\n\tsourceUrl?: string;\n\tallowedHosts?: string[];\n\texpectedSha256?: string;\n\ttimeoutMs?: number;\n\tretries?: number;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 2500;\nexport const DEFAULT_RETRIES = 1;\nexport const RUNTIME_SIGNATURE_CACHE_TTL_MS = 5 * 60 * 1000;\n\nexport const BUILT_IN_SIGNATURES: ProviderSignaturePayload = {\n\tversion: 'built-in-2026-03-04',\n\tinbound: [\n\t\t{ name: 'Google Workspace', domains: ['google.com', 'googlemail.com'], selectorHints: ['google'] },\n\t\t{ name: 'Microsoft 365', domains: ['outlook.com', 'protection.outlook.com'], selectorHints: ['selector1', 'selector2'] },\n\t\t{ name: 'Proofpoint', domains: ['pphosted.com'] },\n\t\t{ name: 'Mimecast', domains: ['mimecast.com'], selectorHints: ['mimecast'] },\n\t\t{ name: 'Mailgun', domains: ['mailgun.org'] },\n\t\t{ name: 'SendGrid', domains: ['sendgrid.net'] },\n\t\t{ name: 'Amazon SES', domains: ['amazonses.com'] },\n\t],\n\toutbound: [],\n};\n\nexport function normalizeSha256(value: string): string {\n\treturn value.trim().toLowerCase().replace(/^sha256:/, '');\n}\n\nexport function normalizeAllowedHosts(input: string[] | undefined): string[] {\n\tif (!Array.isArray(input)) return [];\n\treturn input.map((host) => host.trim().toLowerCase()).filter((host) => host.length > 0);\n}\n\nexport function validateRuntimeSourceUrl(sourceUrl: string, allowedHosts: string[]): URL {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(sourceUrl);\n\t} catch {\n\t\tthrow new Error('Invalid provider signature source URL');\n\t}\n\n\tif (url.protocol !== 'https:') {\n\t\tthrow new Error('Invalid provider signature source URL: HTTPS is required');\n\t}\n\n\tif (allowedHosts.length > 0 && !allowedHosts.includes(url.hostname.toLowerCase())) {\n\t\tthrow new Error('Invalid provider signature source URL: host is not allowlisted');\n\t}\n\n\treturn url;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n\tconst digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));\n\treturn Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction normalizeDomain(value: string): string {\n\treturn value.trim().toLowerCase().replace(/\\.$/, '');\n}\n\nfunction normalizeProviderSignatures(input: ProviderSignature[] | undefined): ProviderSignature[] {\n\tif (!Array.isArray(input)) return [];\n\n\treturn input\n\t\t.map((provider) => {\n\t\t\tconst name = typeof provider?.name === 'string' ? provider.name.trim() : '';\n\t\t\tconst domains = Array.isArray(provider?.domains)\n\t\t\t\t? provider.domains.map((domain) => normalizeDomain(String(domain))).filter((domain) => domain.length > 0)\n\t\t\t\t: [];\n\t\t\tconst selectorHints = Array.isArray(provider?.selectorHints)\n\t\t\t\t? provider.selectorHints.map((selector) => String(selector).trim().toLowerCase()).filter((selector) => selector.length > 0)\n\t\t\t\t: [];\n\t\t\treturn { name, domains, ...(selectorHints.length > 0 ? { selectorHints } : {}) };\n\t\t})\n\t\t.filter((provider) => provider.name.length > 0 && provider.domains.length > 0);\n}\n\nexport function buildResult(\n\tpayload: ProviderSignaturePayload,\n\tsource: ProviderSourceResult['source'],\n\tdegraded: boolean,\n): ProviderSourceResult {\n\tconst inbound = normalizeProviderSignatures(payload.inbound);\n\tconst outbound = normalizeProviderSignatures(payload.outbound);\n\n\treturn {\n\t\tversion: payload.version?.trim() || BUILT_IN_SIGNATURES.version || 'unknown',\n\t\tsource,\n\t\tfetchedAt: new Date().toISOString(),\n\t\tdegraded,\n\t\tinbound,\n\t\toutbound,\n\t};\n}\n\nexport function isValidSignaturePayload(payload: unknown): payload is ProviderSignaturePayload {\n\tif (!payload || typeof payload !== 'object') return false;\n\tconst record = payload as Record<string, unknown>; // typeof payload === 'object' is checked above\n\tif (record.version !== undefined && typeof record.version !== 'string') return false;\n\tif (record.inbound !== undefined && !Array.isArray(record.inbound)) return false;\n\tif (record.outbound !== undefined && !Array.isArray(record.outbound)) return false;\n\treturn true;\n}\n\nexport async function fetchProviderPayload(\n\turl: string,\n\ttimeoutMs: number,\n\tretries: number,\n\texpectedSha256?: string,\n): Promise<ProviderSignaturePayload | null> {\n\tfor (let attempt = 0; attempt <= retries; attempt++) {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { Accept: 'application/json' },\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tredirect: 'manual',\n\t\t\t});\n\t\t\tif (response.status >= 300 && response.status < 400) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tif (attempt < retries && response.status >= 500) continue;\n\t\t\t\tthrow new Error(`Provider signature source returned HTTP ${response.status}`);\n\t\t\t}\n\n\t\t\tconst MAX_BODY_BYTES = 1_048_576; // 1 MB — provider signature JSON from pinned source\n\t\t\tconst contentLength = parseInt(response.headers?.get('content-length') ?? '0', 10);\n\t\t\tif (contentLength > MAX_BODY_BYTES) {\n\t\t\t\tthrow new Error(`Provider signature source exceeds ${MAX_BODY_BYTES} bytes (Content-Length: ${contentLength})`);\n\t\t\t}\n\t\t\tconst rawPayload = await response.text();\n\t\t\tif (rawPayload.length > MAX_BODY_BYTES) {\n\t\t\t\tthrow new Error(`Provider signature source exceeds ${MAX_BODY_BYTES} bytes`);\n\t\t\t}\n\t\t\tif (!expectedSha256) {\n\t\t\t\tthrow new Error('Provider signature source requires a pinned SHA-256 digest');\n\t\t\t}\n\n\t\t\tconst digest = await sha256Hex(rawPayload);\n\t\t\tif (digest !== normalizeSha256(expectedSha256)) {\n\t\t\t\tthrow new Error('Provider signature source failed SHA-256 verification');\n\t\t\t}\n\n\t\t\tconst payload = JSON.parse(rawPayload) as unknown;\n\t\t\tif (!isValidSignaturePayload(payload)) {\n\t\t\t\tthrow new Error('Provider signature source returned an invalid payload shape');\n\t\t\t}\n\n\t\t\treturn payload;\n\t\t} catch (error) {\n\t\t\tif (attempt < retries) continue;\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new Error(`Provider signature source timed out after ${timeoutMs}ms`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\tthrow new Error('Failed to load provider signatures');\n}","// SPDX-License-Identifier: BUSL-1.1\n\nimport {\n\tBUILT_IN_SIGNATURES,\n\tbuildResult,\n\tDEFAULT_RETRIES,\n\tDEFAULT_TIMEOUT_MS,\n\tfetchProviderPayload,\n\ttype LoadProviderSignaturesOptions,\n\tnormalizeAllowedHosts,\n\ttype ProviderSignature,\n\ttype ProviderSourceResult,\n\tRUNTIME_SIGNATURE_CACHE_TTL_MS,\n\tvalidateRuntimeSourceUrl,\n} from './provider-signature-source';\n\ninterface ProviderMatchEvidence {\n\tprovider: string;\n\tmatches: string[];\n}\n\nlet lastKnownGood: ProviderSourceResult | null = null;\nlet runtimeSignatureCache: {\n\tsourceUrl: string;\n\tresult: ProviderSourceResult;\n\texpiresAt: number;\n} | null = null;\n\nfunction normalizeDomain(value: string): string {\n\treturn value.trim().toLowerCase().replace(/\\.$/, '');\n}\n\nfunction boundarySuffixMatch(hostname: string, suffix: string): boolean {\n\tconst host = normalizeDomain(hostname);\n\tconst normalizedSuffix = normalizeDomain(suffix);\n\tif (!host || !normalizedSuffix) return false;\n\treturn host === normalizedSuffix || host.endsWith(`.${normalizedSuffix}`);\n}\n\n\nexport async function loadProviderSignatures(options?: LoadProviderSignaturesOptions): Promise<ProviderSourceResult> {\n\tconst timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\tconst retries = options?.retries ?? DEFAULT_RETRIES;\n\tconst sourceUrl = options?.sourceUrl?.trim();\n\tconst allowedHosts = normalizeAllowedHosts(options?.allowedHosts);\n\tconst expectedSha256 = options?.expectedSha256?.trim();\n\n\tif (!sourceUrl) {\n\t\treturn buildResult(BUILT_IN_SIGNATURES, 'built-in', false);\n\t}\n\n\tconst now = Date.now();\n\tif (runtimeSignatureCache && runtimeSignatureCache.sourceUrl === sourceUrl && runtimeSignatureCache.expiresAt > now) {\n\t\treturn runtimeSignatureCache.result;\n\t}\n\n\ttry {\n\t\tconst validatedUrl = validateRuntimeSourceUrl(sourceUrl, allowedHosts);\n\t\tconst payload = await fetchProviderPayload(validatedUrl.toString(), timeoutMs, retries, expectedSha256);\n\t\tif (!payload) {\n\t\t\tthrow new Error('Provider signature source returned a redirect');\n\t\t}\n\t\tconst result = buildResult(payload, 'runtime', false);\n\t\tlastKnownGood = result;\n\t\truntimeSignatureCache = {\n\t\t\tsourceUrl,\n\t\t\tresult,\n\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t};\n\t\treturn result;\n\t} catch {\n\t\tif (lastKnownGood) {\n\t\t\tconst staleResult = { ...lastKnownGood, source: 'stale' as const, degraded: true, fetchedAt: new Date().toISOString() };\n\t\t\truntimeSignatureCache = {\n\t\t\t\tsourceUrl,\n\t\t\t\tresult: staleResult,\n\t\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t\t};\n\t\t\treturn staleResult;\n\t\t}\n\t\tconst fallbackResult = buildResult(BUILT_IN_SIGNATURES, 'built-in', true);\n\t\truntimeSignatureCache = {\n\t\t\tsourceUrl,\n\t\t\tresult: fallbackResult,\n\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t};\n\t\treturn fallbackResult;\n\t}\n}\n\n/**\n * Test helper to reset provider signature loader state between cases.\n * @internal Exported for test use only.\n */\nexport function resetProviderSignatureState(): void {\n\tlastKnownGood = null;\n\truntimeSignatureCache = null;\n}\n\nexport function detectProviderMatches(hosts: string[], signatures: ProviderSignature[]): ProviderMatchEvidence[] {\n\tconst normalizedHosts = hosts.map((host) => normalizeDomain(host)).filter((host) => host.length > 0);\n\tconst matches: ProviderMatchEvidence[] = [];\n\n\tfor (const provider of signatures) {\n\t\tconst providerMatches = new Set<string>();\n\t\tfor (const host of normalizedHosts) {\n\t\t\tif (provider.domains.some((domain) => boundarySuffixMatch(host, domain))) {\n\t\t\t\tproviderMatches.add(host);\n\t\t\t}\n\t\t}\n\t\tif (providerMatches.size > 0) {\n\t\t\tmatches.push({ provider: provider.name, matches: Array.from(providerMatches) });\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nexport function detectProviderMatchesBySelectors(selectors: string[], signatures: ProviderSignature[]): ProviderMatchEvidence[] {\n\tconst normalizedSelectors = selectors.map((selector) => selector.trim().toLowerCase()).filter((selector) => selector.length > 0);\n\tconst matches: ProviderMatchEvidence[] = [];\n\n\tfor (const provider of signatures) {\n\t\tconst hints = provider.selectorHints ?? [];\n\t\tif (hints.length === 0) continue;\n\n\t\tconst providerMatches = normalizedSelectors.filter((selector) => hints.includes(selector));\n\t\tif (providerMatches.length > 0) {\n\t\t\tmatches.push({ provider: provider.name, matches: Array.from(new Set(providerMatches)) });\n\t\t}\n\t}\n\n\treturn matches;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * MX record check tool for MCP server.\n * Thin wrapper around @blackveil/dns-checks — delegates core logic to the shared package.\n * Adds provider detection post-processing on top of the package result.\n */\n\nimport { checkMX, createFinding } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { detectProviderMatches, loadProviderSignatures } from '../lib/provider-signatures';\n\nexport interface CheckMxOptions {\n\tproviderSignaturesUrl?: string;\n\tproviderSignaturesAllowedHosts?: string[];\n\tproviderSignaturesSha256?: string;\n}\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/** Check MX record configuration for a domain */\nexport async function checkMx(domain: string, options?: CheckMxOptions, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\tconst timeout = dnsOptions?.timeoutMs ?? 5000;\n\n\t// Run core MX check from shared package\n\tconst baseResult = await checkMX(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout },\n\t) as CheckResult;\n\n\t// Early return if MX check already returned critical/error findings (no MX records, etc.)\n\t// Only add provider detection when we have meaningful MX records\n\tconst hasCritical = baseResult.findings.some((f) => f.severity === 'critical');\n\tconst hasMediumQueryFailed = baseResult.findings.some((f) => f.title === 'DNS query failed');\n\tif (hasCritical || hasMediumQueryFailed) {\n\t\treturn baseResult;\n\t}\n\n\t// Provider detection post-processing\n\tconst findings = [...baseResult.findings];\n\n\ttry {\n\t\t// Re-query MX records to get raw strings for provider matching\n\t\tconst mxAnswers = await queryDnsRecords(domain, 'MX', dnsOptions);\n\t\tconst mxTargets = mxAnswers.map((answer) => {\n\t\t\tconst parts = answer.split(' ');\n\t\t\treturn (parts.slice(1).join(' ') || '').replace(/\\.$/, '').toLowerCase();\n\t\t}).filter(Boolean);\n\n\t\tif (mxTargets.length > 0) {\n\t\t\tconst providerSignatures = await loadProviderSignatures({\n\t\t\t\tsourceUrl: options?.providerSignaturesUrl,\n\t\t\t\tallowedHosts: options?.providerSignaturesAllowedHosts,\n\t\t\t\texpectedSha256: options?.providerSignaturesSha256,\n\t\t\t});\n\t\t\tconst inboundMatches = detectProviderMatches(mxTargets, providerSignatures.inbound);\n\n\t\t\tif (inboundMatches.length > 0) {\n\t\t\t\tconst providerNames = inboundMatches.map((m) => m.provider).join(', ');\n\t\t\t\tconst evidence = inboundMatches.map((m) => `${m.provider}: ${m.matches.join(', ')}`).join('; ');\n\t\t\t\tconst providerConfidence = providerSignatures.source === 'runtime' ? 0.95 : providerSignatures.source === 'stale' ? 0.75 : 0.7;\n\n\t\t\t\tfindings.push(\n\t\t\t\t\tcreateFinding('mx', 'Managed email provider detected', 'info', `Inbound provider(s): ${providerNames}. Evidence: ${evidence}.`, {\n\t\t\t\t\t\tdetectionType: 'inbound',\n\t\t\t\t\t\tproviders: inboundMatches.map((m) => ({ name: m.provider, matches: m.matches })),\n\t\t\t\t\t\tproviderConfidence,\n\t\t\t\t\t\tsignatureSource: providerSignatures.source,\n\t\t\t\t\t\tsignatureVersion: providerSignatures.version,\n\t\t\t\t\t\tsignatureFetchedAt: providerSignatures.fetchedAt,\n\t\t\t\t\t}) as (typeof findings)[0],\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (providerSignatures.degraded) {\n\t\t\t\tfindings.push(\n\t\t\t\t\tcreateFinding(\n\t\t\t\t\t\t'mx',\n\t\t\t\t\t\t'Provider signature source unavailable',\n\t\t\t\t\t\t'info',\n\t\t\t\t\t\t`Provider detection used ${providerSignatures.source === 'stale' ? 'stale cached' : 'built-in fallback'} signatures.`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdetectionType: 'inbound',\n\t\t\t\t\t\t\tproviderConfidence: providerSignatures.source === 'stale' ? 0.55 : 0.45,\n\t\t\t\t\t\t\tsignatureSource: providerSignatures.source,\n\t\t\t\t\t\t\tsignatureVersion: providerSignatures.version,\n\t\t\t\t\t\t\tsignatureFetchedAt: providerSignatures.fetchedAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t) as (typeof findings)[0],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Provider detection failure is non-critical — return base result\n\t}\n\n\treturn { ...baseResult, findings };\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * NS (Name Server) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkNS } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check nameserver configuration for a domain.\n * Validates NS records exist, checks for diversity, and verifies responsiveness.\n */\nexport async function checkNs(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkNS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SPF (Sender Policy Framework) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSPF } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\n/**\n * Build a DNSQueryFunction adapter that routes TXT queries through queryTxtRecords\n * (which strips surrounding quotes from DoH TXT data) and all other record types\n * through queryDnsRecords.\n */\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check SPF records for a domain.\n * Looks for v=spf1 TXT records and validates their configuration.\n * Recursively expands include chains to compute true DNS lookup count.\n */\nexport async function checkSpf(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSPF(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SSL/TLS certificate check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSSL } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\n/**\n * Check SSL/TLS configuration for a domain.\n * Validates HTTPS connectivity, HSTS headers, and HTTP→HTTPS redirect.\n */\nexport async function checkSsl(domain: string): Promise<CheckResult> {\n\treturn checkSSL(domain, fetch, { timeout: HTTPS_TIMEOUT_MS }) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Subdomain Takeover / Dangling CNAME Detection Tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSubdomainTakeover as checkSubdomainTakeoverPkg } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check for dangling CNAME records on known/active subdomains.\n * Flags orphaned records and potential takeover vectors.\n */\nexport async function checkSubdomainTakeover(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSubdomainTakeoverPkg(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? HTTPS_TIMEOUT_MS, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * TLS-RPT (SMTP TLS Reporting) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkTLSRPT } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check TLS-RPT records for a domain.\n * Validates the presence and configuration of SMTP TLS Reporting records.\n */\nexport async function checkTlsrpt(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkTLSRPT(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { sanitizeInput } from './sanitize';\n\nconst MARKDOWN_SYNTAX = /[`*_#[\\]()>|<]/g;\n\n/**\n * Characters that can inject HTML or dangerous markdown constructs.\n * Excludes `_` (common in DNS names like `_dmarc`, `_mta-sts`) and\n * `()` (used in natural-language detail text) which are safe in finding details.\n */\nconst DNS_DATA_UNSAFE = /[`*#[\\]>|<]/g;\n\n/**\n * Sanitize DNS-sourced data before it enters finding detail strings.\n * Strips C0 control characters (preserving tab/newline), replaces HTML/markdown\n * injection characters, but does NOT truncate — DNS data in findings can be\n * longer than display output.\n */\nexport function sanitizeDnsData(input: string): string {\n\treturn input\n\t\t.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '')\n\t\t.replace(DNS_DATA_UNSAFE, ' ')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim();\n}\n\nexport function sanitizeOutputText(input: string, maxLength = 240): string {\n\tconst trimmed = sanitizeInput(input, maxLength * 2)\n\t\t.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, '')\n\t\t.replace(MARKDOWN_SYNTAX, ' ')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim();\n\n\tif (trimmed.length <= maxLength) {\n\t\treturn trimmed;\n\t}\n\n\treturn `${trimmed.slice(0, maxLength - 3).trimEnd()}...`;\n}","export interface ExplanationTemplate {\n\ttitle: string;\n\tseverity: string;\n\texplanation: string;\n\timpact?: string;\n\tadverseConsequences?: string;\n\trecommendation: string;\n\treferences: string[];\n}\n\nexport interface ImpactNarrative {\n\timpact?: string;\n\tadverseConsequences?: string;\n}\n\nexport interface SpecificImpactRule extends ImpactNarrative {\n\tcheckType?: string;\n\ttitleIncludes?: string[];\n\tdetailIncludes?: string[];\n}\n\nexport const EXPLANATIONS: Record<string, ExplanationTemplate> = {\n\tSUBDOMAIN_TAKEOVER_CRITICAL: {\n\t\ttitle: 'Dangling CNAME — Subdomain Takeover Risk',\n\t\tseverity: 'critical',\n\t\texplanation:\n\t\t\t'A subdomain points to a third-party service (e.g., CloudFront, Heroku) that does not resolve. This is a potential subdomain takeover vector, allowing attackers to claim the orphaned resource and control the subdomain.',\n\t\timpact: 'Attackers may host malicious content or capture traffic on a trusted subdomain, enabling phishing and session abuse.',\n\t\tadverseConsequences:\n\t\t\t'Brand trust can be damaged, users can be redirected to attacker infrastructure, and incident response costs can increase.',\n\t\trecommendation: 'Remove or update the CNAME record to point to a valid, owned resource. Regularly audit DNS for orphaned records.',\n\t\treferences: [\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t\t'https://www.hackerone.com/blog/Guide-Subdomain-Takeover',\n\t\t\t'https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html',\n\t\t],\n\t},\n\tSUBDOMAIN_TAKEOVER_HIGH: {\n\t\ttitle: 'CNAME Resolution Failed — Manual Review Needed',\n\t\tseverity: 'high',\n\t\texplanation:\n\t\t\t'A subdomain CNAME points to a third-party service but the target could not be resolved. This may indicate a takeover risk or DNS misconfiguration.',\n\t\timpact: 'If the target is orphaned, an attacker may be able to claim it and gain control of the affected subdomain.',\n\t\tadverseConsequences: 'Users may be exposed to fraudulent pages and the organization may face reputation damage until DNS is remediated.',\n\t\trecommendation: 'Manually review the CNAME target and remove or update if orphaned. Use DNS monitoring tools for ongoing checks.',\n\t\treferences: [\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t\t'https://www.hackerone.com/blog/Guide-Subdomain-Takeover',\n\t\t],\n\t},\n\tSUBDOMAIN_TAKEOVER_INFO: {\n\t\ttitle: 'No Dangling CNAME Records Found',\n\t\tseverity: 'info',\n\t\texplanation: 'No subdomain takeover vectors detected among known/active subdomains. DNS configuration is secure for this check.',\n\t\trecommendation: 'Continue regular DNS audits and monitoring for new subdomains or changes.',\n\t\treferences: ['https://github.com/EdOverflow/can-i-take-over-xyz'],\n\t},\n\tSUBDOMAILING_CRITICAL: {\n\t\ttitle: 'Dangling CNAME in SPF Include Chain — SubdoMailing Risk',\n\t\tseverity: 'critical',\n\t\texplanation:\n\t\t\t'An SPF include domain has a dangling CNAME record pointing to a third-party service that does not resolve. An attacker could register the orphaned resource, gain control of the SPF include, and send authenticated email as the target domain.',\n\t\timpact: 'Full email authentication bypass — attacker-sent messages pass SPF checks and may pass DMARC alignment.',\n\t\tadverseConsequences:\n\t\t\t'Targeted phishing campaigns sent from a trusted domain identity, bypassing email security filters at scale.',\n\t\trecommendation: 'Remove the include mechanism from the SPF record or update it to point to a valid, owned resource. Audit all SPF includes periodically.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t],\n\t},\n\tSUBDOMAILING_HIGH: {\n\t\ttitle: 'Dangling NS Delegation in SPF Include Chain',\n\t\tseverity: 'high',\n\t\texplanation:\n\t\t\t'An SPF include domain has nameservers that do not resolve. An attacker could register the NS target domains and take control of DNS for the include domain, enabling SPF authorization hijacking.',\n\t\timpact: 'Potential email authentication bypass if the attacker registers the unresolvable nameserver domains.',\n\t\tadverseConsequences:\n\t\t\t'Spoofed emails could pass SPF validation, eroding trust and enabling impersonation attacks.',\n\t\trecommendation: 'Remove the include mechanism or ensure its nameservers resolve correctly. Consider consolidating SPF includes to domains under your direct control.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSUBDOMAILING_LOW: {\n\t\ttitle: 'Void SPF Include',\n\t\tseverity: 'low',\n\t\texplanation:\n\t\t\t'An SPF include domain has no SPF record. While not immediately exploitable, this wastes a DNS lookup and could become a risk if the domain is abandoned or expires.',\n\t\trecommendation: 'Remove unused include mechanisms from the SPF record to reduce lookup waste and attack surface.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSUBDOMAILING_INFO: {\n\t\ttitle: 'No SubdoMailing Risk Detected',\n\t\tseverity: 'info',\n\t\texplanation: 'All SPF include and redirect domains resolve correctly with no takeover indicators. The SPF include chain is secure for this check.',\n\t\trecommendation: 'Continue periodic audits of SPF include domains, especially after vendor changes.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSPF_PASS: {\n\t\ttitle: 'SPF Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'SPF (Sender Policy Framework) is properly configured. The domain specifies which mail servers are authorized to send email on its behalf.',\n\t\trecommendation: 'Maintain your current SPF configuration. Ensure you update it when adding new email sending sources.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208'],\n\t},\n\tSPF_FAIL: {\n\t\ttitle: 'SPF Validation Failed',\n\t\tseverity: 'fail',\n\t\texplanation: 'SPF validation failed - emails from this domain are being rejected because the sending server is not authorized.',\n\t\timpact: 'Email authentication becomes unreliable, and spoofed or misrouted messages may evade expected controls.',\n\t\tadverseConsequences:\n\t\t\t'Legitimate email delivery can degrade, while impersonation attempts can increase helpdesk and abuse handling load.',\n\t\trecommendation:\n\t\t\t'Review your SPF record and ensure all legitimate email sources are included. Common issue: using -all but missing include statements.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208', 'https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/'],\n\t},\n\tSPF_WARNING: {\n\t\ttitle: 'SPF Soft Fail',\n\t\tseverity: 'warning',\n\t\texplanation: 'SPF uses a soft fail (~all) policy. Emails that fail SPF will be accepted but may be flagged as suspicious.',\n\t\timpact: 'Failing SPF messages are often still accepted, so spoofed mail may continue reaching recipients.',\n\t\tadverseConsequences: 'Phishing risk remains elevated and security teams may need to manually triage suspicious mail.',\n\t\trecommendation: 'Upgrade to hard fail (-all) after verifying all legitimate sources are in your SPF record.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208#section-8.1'],\n\t},\n\tSPF_MISSING: {\n\t\ttitle: 'No SPF Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'SPF (Sender Policy Framework) is a DNS TXT record that specifies which mail servers are authorized to send email on behalf of your domain. Without SPF, any server can send email pretending to be from your domain.',\n\t\timpact: 'Any internet host can attempt to send email as your domain, making sender impersonation significantly easier.',\n\t\tadverseConsequences: 'Spoofing and phishing campaigns can harm brand trust, increase abuse complaints, and impair deliverability.',\n\t\trecommendation: \"Add a TXT record to your domain's DNS with a valid SPF policy. Start with: v=spf1 include:<your-email-provider> -all\",\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208', 'https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/'],\n\t},\n\tDMARC_PASS: {\n\t\ttitle: 'DMARC Policy Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DMARC (Domain-based Message Authentication, Reporting & Conformance) is properly configured with a policy that provides protection against email spoofing.',\n\t\trecommendation:\n\t\t\t'Monitor your DMARC reports to ensure legitimate email is not being blocked. Consider enabling reject policy for stronger protection.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489'],\n\t},\n\tDMARC_FAIL: {\n\t\ttitle: 'No DMARC Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'DMARC builds on SPF and DKIM to provide email authentication policy. Without DMARC, receivers have no policy guidance for handling authentication failures.',\n\t\timpact: 'Receiving systems cannot consistently quarantine or reject forged messages that fail authentication.',\n\t\tadverseConsequences: 'Domain spoofing can reach inboxes more often, increasing phishing exposure and reputational damage.',\n\t\trecommendation: 'Add a TXT record at _dmarc.<domain> with at minimum: v=DMARC1; p=quarantine; rua=mailto:dmarc@<domain>',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489', 'https://www.cloudflare.com/learning/dns/dns-records/dns-dmarc-record/'],\n\t},\n\tDMARC_WARNING: {\n\t\ttitle: 'DMARC Policy Not Enforcing',\n\t\tseverity: 'warning',\n\t\texplanation: \"DMARC policy is set to 'none' (monitoring only) or 'quarantine'. This provides limited protection against spoofing.\",\n\t\timpact: 'Authentication failures may not be fully blocked, allowing some malicious mail to be delivered.',\n\t\tadverseConsequences: 'Attackers can still impersonate the domain in recipient inboxes, leading to fraud and support overhead.',\n\t\trecommendation: \"After reviewing DMARC reports, upgrade the policy to 'reject' to actively protect against email spoofing.\",\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489#section-6.3'],\n\t},\n\tDKIM_PASS: {\n\t\ttitle: 'DKIM Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DKIM (DomainKeys Identified Mail) is properly configured. Outgoing emails are digitally signed and can be verified by receivers.',\n\t\trecommendation: 'Maintain your DKIM configuration. Rotate keys periodically as per your security policy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6376'],\n\t},\n\tDKIM_FAIL: {\n\t\ttitle: 'No DKIM Records Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t\"DKIM adds a digital signature to outgoing emails, allowing receivers to verify the email was sent by an authorized server and wasn't modified in transit.\",\n\t\timpact: 'Receivers lose a key authenticity signal, which weakens anti-spoofing and anti-tampering protections.',\n\t\tadverseConsequences:\n\t\t\t'Legitimate email may be distrusted while fraudulent messages are harder to distinguish, hurting deliverability and trust.',\n\t\trecommendation: 'Configure DKIM signing with your email provider. They will provide the DKIM DNS records to publish.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6376', 'https://www.cloudflare.com/learning/dns/dns-records/dns-dkim-record/'],\n\t},\n\tDNSSEC_PASS: {\n\t\ttitle: 'DNSSEC Enabled',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DNSSEC is properly configured with valid cryptographic signatures. This protects against DNS spoofing and cache poisoning attacks.',\n\t\trecommendation: 'Maintain your DNSSEC configuration. Monitor for any validation failures in your logs.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc4033'],\n\t},\n\tDNSSEC_FAIL: {\n\t\ttitle: 'DNSSEC Not Validated',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t\"DNSSEC adds cryptographic signatures to DNS records, preventing DNS spoofing and cache poisoning attacks. Without DNSSEC, attackers can redirect your domain's traffic.\",\n\t\timpact: 'DNS responses can be forged in transit, enabling redirection to attacker-controlled infrastructure.',\n\t\tadverseConsequences: 'Users may be sent to malicious destinations, causing credential theft, service disruption, and incident response costs.',\n\t\trecommendation: 'Enable DNSSEC through your domain registrar and DNS provider. Most providers offer one-click DNSSEC activation.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc4033', 'https://www.cloudflare.com/dns/dnssec/how-dnssec-works/'],\n\t},\n\tSSL_PASS: {\n\t\ttitle: 'SSL/TLS Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'The domain properly serves content over HTTPS with a valid certificate.',\n\t\trecommendation: 'Maintain your SSL certificate. Consider implementing HSTS for additional security.',\n\t\treferences: ['https://https.cio.gov/hsts/'],\n\t},\n\tSSL_FAIL: {\n\t\ttitle: 'HTTPS Not Available',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'The domain does not have a valid SSL/TLS certificate or the HTTPS server is not responding. This means traffic to the domain is not encrypted.',\n\t\timpact: 'Network attackers can intercept or tamper with data exchanged between users and the site.',\n\t\tadverseConsequences: 'Credentials and sensitive data may be exposed, and browser trust warnings can reduce conversion and user confidence.',\n\t\trecommendation: \"Install a valid SSL/TLS certificate. Free certificates are available from Let's Encrypt or Cloudflare.\",\n\t\treferences: ['https://letsencrypt.org/', 'https://www.cloudflare.com/ssl/'],\n\t},\n\tSSL_WARNING: {\n\t\ttitle: 'Mixed Content or Redirect Issues',\n\t\tseverity: 'warning',\n\t\texplanation: 'HTTPS is available but there may be issues with redirects or mixed content.',\n\t\timpact: 'Some resources may still load insecurely, creating opportunities for content manipulation or privacy leakage.',\n\t\tadverseConsequences: 'User sessions and page integrity can be weakened, and security posture may fail audit expectations.',\n\t\trecommendation: 'Ensure all resources load over HTTPS and implement proper redirects from HTTP to HTTPS.',\n\t\treferences: ['https://www.cloudflare.com/ssl/'],\n\t},\n\tSSL_MEDIUM: {\n\t\ttitle: 'HSTS or Redirect Issues',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'HTTPS is available but the domain is missing HSTS (Strict-Transport-Security) headers or does not redirect HTTP to HTTPS. Without HSTS, browsers may still attempt insecure connections.',\n\t\timpact: 'Clients may be downgraded to insecure HTTP connections, especially on first visit or hostile networks.',\n\t\tadverseConsequences: 'Session data can be exposed in transit and users remain vulnerable to downgrade or interception attacks.',\n\t\trecommendation:\n\t\t\t'Add a Strict-Transport-Security header with max-age of at least 1 year (31536000). Configure your web server to redirect all HTTP requests to HTTPS.',\n\t\treferences: ['https://https.cio.gov/hsts/', 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security'],\n\t},\n\tSSL_LOW: {\n\t\ttitle: 'HSTS Configuration Suboptimal',\n\t\tseverity: 'low',\n\t\texplanation:\n\t\t\t'HSTS is configured but could be improved. Common issues include a short max-age value or missing includeSubDomains directive.',\n\t\timpact: 'Partial HSTS coverage leaves windows where transport security guarantees are weaker than expected.',\n\t\tadverseConsequences: 'Subdomains or returning sessions may still face avoidable downgrade exposure and policy non-compliance findings.',\n\t\trecommendation:\n\t\t\t'Set max-age to at least 31536000 (1 year) and include the includeSubDomains directive. Consider adding your domain to the HSTS preload list.',\n\t\treferences: [\n\t\t\t'https://hstspreload.org/',\n\t\t\t'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security',\n\t\t],\n\t},\n\tMTA_STS_PASS: {\n\t\ttitle: 'MTA-STS Enabled',\n\t\tseverity: 'pass',\n\t\texplanation: 'MTA-STS (Mail Transfer Agent Strict Transport Security) is properly configured and enforces TLS for incoming email.',\n\t\trecommendation: 'Monitor your MTA-STS reports to ensure legitimate mail servers can deliver successfully.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tMTA_STS_FAIL: {\n\t\ttitle: 'No MTA-STS Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'MTA-STS enforces TLS encryption for incoming email, preventing downgrade attacks where an attacker forces email to be sent unencrypted.',\n\t\timpact: 'Inbound SMTP sessions are more susceptible to TLS downgrade and interception attempts.',\n\t\tadverseConsequences: 'Sensitive email content can be exposed in transit, raising confidentiality and compliance risks.',\n\t\trecommendation:\n\t\t\t'Publish an MTA-STS TXT record at _mta-sts.<domain> and host a policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tMTA_STS_WARNING: {\n\t\ttitle: 'MTA-STS in Testing Mode',\n\t\tseverity: 'warning',\n\t\texplanation: 'MTA-STS is configured but in testing mode (mode=testing) rather than enforcement mode.',\n\t\timpact: 'Delivery behavior is monitored but not enforced, so some insecure transport paths may still be accepted.',\n\t\tadverseConsequences: 'Security gaps can persist longer and confidentiality controls for inbound mail remain partially effective.',\n\t\trecommendation: 'After verifying all mail servers can successfully deliver over TLS, upgrade to mode=enforce.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tNS_PASS: {\n\t\ttitle: 'Nameservers Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'The domain has properly configured nameservers that are responding to queries.',\n\t\trecommendation: 'Maintain your current nameserver configuration. Use at least two geographically distributed nameservers for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035'],\n\t},\n\tNS_FAIL: {\n\t\ttitle: 'Nameserver Issues Detected',\n\t\tseverity: 'fail',\n\t\texplanation: 'One or more nameservers for this domain are not responding or are misconfigured, which can cause DNS resolution failures.',\n\t\timpact: 'Resolvers may fail to resolve the domain, degrading access to web, API, and mail services.',\n\t\tadverseConsequences: 'Users can experience outages, failed transactions, and business continuity disruptions.',\n\t\trecommendation: 'Verify all listed nameservers are operational and properly configured. Ensure NS records match those at the registrar.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035', 'https://www.cloudflare.com/learning/dns/dns-records/dns-ns-record/'],\n\t},\n\tNS_WARNING: {\n\t\ttitle: 'Nameserver Configuration Suboptimal',\n\t\tseverity: 'warning',\n\t\texplanation: 'Nameservers are functional but the configuration could be improved for better reliability or security.',\n\t\timpact: 'Single points of failure or weak diversity can reduce DNS resilience during provider or network incidents.',\n\t\tadverseConsequences: 'Availability and latency can degrade under stress, increasing user-facing instability.',\n\t\trecommendation: 'Consider adding additional nameservers for redundancy and ensuring they are geographically distributed.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035'],\n\t},\n\tCAA_PASS: {\n\t\ttitle: 'CAA Records Configured',\n\t\tseverity: 'pass',\n\t\texplanation: 'CAA (Certificate Authority Authorization) records are properly configured, restricting which CAs can issue certificates for this domain.',\n\t\trecommendation: 'Maintain your CAA records. Review periodically to ensure they reflect your current certificate issuance needs.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659'],\n\t},\n\tCAA_FAIL: {\n\t\ttitle: 'No CAA Records Found',\n\t\tseverity: 'fail',\n\t\texplanation: 'No CAA records are present for this domain. Without CAA, any certificate authority can issue certificates for your domain.',\n\t\timpact: 'Certificate issuance controls are broad, increasing the chance of unauthorized or misissued certificates.',\n\t\tadverseConsequences: 'Attackers may abuse misissuance for impersonation and interception, with trust and compliance implications.',\n\t\trecommendation: 'Add CAA DNS records to restrict certificate issuance to your authorized CAs (e.g., \"0 issue letsencrypt.org\").',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659', 'https://www.cloudflare.com/learning/dns/dns-records/dns-caa-record/'],\n\t},\n\tCAA_WARNING: {\n\t\ttitle: 'CAA Configuration Incomplete',\n\t\tseverity: 'warning',\n\t\texplanation: 'CAA records exist but may not fully restrict certificate issuance. Consider adding iodef or wildcard policies.',\n\t\timpact: 'Incomplete CAA policy can leave gaps in issuance constraints for wildcard or incident-reporting scenarios.',\n\t\tadverseConsequences: 'Certificate governance may be weaker than intended, increasing operational and audit risk.',\n\t\trecommendation: 'Review your CAA records and add an iodef tag for incident reporting. Consider restricting wildcard certificate issuance separately.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659'],\n\t},\n\tMX_PASS: {\n\t\ttitle: 'MX Records Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'MX (Mail Exchange) records are properly configured, directing email to the correct mail servers.',\n\t\trecommendation: 'Maintain your MX records. Ensure backup MX entries exist for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_FAIL: {\n\t\ttitle: 'No MX Records Found',\n\t\tseverity: 'fail',\n\t\texplanation: 'No MX records are present for this domain. Without MX records, email delivery to this domain will fail or fall back to A record delivery.',\n\t\timpact: 'Mail routing is unreliable or unavailable for intended recipients on this domain.',\n\t\tadverseConsequences: 'Inbound communications may be lost, causing business disruption and missed security notifications.',\n\t\trecommendation: 'Add MX records pointing to your mail server. If this domain does not handle email, consider adding a null MX record (0 .).',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321', 'https://datatracker.ietf.org/doc/html/rfc7505'],\n\t},\n\tMX_WARNING: {\n\t\ttitle: 'MX Configuration Suboptimal',\n\t\tseverity: 'warning',\n\t\texplanation: 'MX records exist but the configuration could be improved, such as missing backup MX or unusual priority values.',\n\t\timpact: 'Mail delivery reliability is reduced during server failures or routing anomalies.',\n\t\tadverseConsequences: 'Message delays and intermittent delivery failures can affect operations and customer support.',\n\t\trecommendation: 'Review MX priorities and add at least one backup MX record for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_INFO: {\n\t\ttitle: 'MX Records Present',\n\t\tseverity: 'info',\n\t\texplanation: 'Mail exchange records are properly configured for this domain.',\n\t\trecommendation: 'No action required. Ensure backup MX records exist for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_LOW: {\n\t\ttitle: 'MX Configuration Could Be Improved',\n\t\tseverity: 'low',\n\t\texplanation: 'MX records are present but the configuration has minor issues such as missing backup MX records.',\n\t\timpact: 'Resilience to mail infrastructure outages is lower than recommended.',\n\t\tadverseConsequences: 'Short outages can become user-visible delivery delays and increase operational toil.',\n\t\trecommendation: 'Add at least one backup MX record with a different priority for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_HIGH: {\n\t\ttitle: 'MX Configuration Error',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'MX records have a configuration error such as pointing to an IP address instead of a hostname (violating RFC 5321) or referencing a hostname that does not resolve to any address record.',\n\t\timpact: 'Standards-incompatible or unresolvable MX targets can cause mail rejection or routing failures across sending systems.',\n\t\tadverseConsequences: 'Business-critical messages may bounce, delaying incident response and external communication.',\n\t\trecommendation:\n\t\t\t'Update MX records to point to valid hostnames, not IP addresses. Ensure all MX targets resolve to valid A/AAAA records.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_MEDIUM: {\n\t\ttitle: 'No MX Records Found',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'No MX records are present for this domain. Email delivery will fall back to A record delivery or fail entirely.',\n\t\timpact: 'Email reception may fail or behave inconsistently depending on sender fallback behavior.',\n\t\tadverseConsequences: 'Organizations may miss customer, partner, or security messages, creating operational and reputational risk.',\n\t\trecommendation:\n\t\t\t'If this domain should receive email, add MX records. If not, publish a null MX record per RFC 7505 to explicitly declare that.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321', 'https://datatracker.ietf.org/doc/html/rfc7505'],\n\t},\n\tDANE_HTTPS_PASS: {\n\t\ttitle: 'DANE TLSA Configured for HTTPS',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'TLSA records at _443._tcp.{domain} pin the web server certificate to DNS, providing an additional layer of TLS trust beyond the CA system. Combined with DNSSEC, this prevents unauthorized CAs from issuing fraudulent certificates for the domain.',\n\t\trecommendation: 'Maintain your DANE HTTPS configuration. Ensure TLSA records are updated whenever TLS certificates are renewed.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_FAIL: {\n\t\ttitle: 'No DANE TLSA for HTTPS',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'No TLSA records were found at _443._tcp.{domain}. DANE certificate pinning for HTTPS provides an additional trust anchor beyond the CA system, preventing unauthorized certificate issuance attacks.',\n\t\timpact: 'Certificate issuance for this domain relies solely on the CA trust hierarchy.',\n\t\tadverseConsequences:\n\t\t\t'A compromised or rogue CA can issue a valid certificate for the domain, enabling MITM attacks that bypass standard browser trust checks.',\n\t\trecommendation:\n\t\t\t'Implement DANE-EE (usage 3) TLSA records at _443._tcp.{domain} and ensure DNSSEC is enabled. Use SHA-256 (matching type 1) or SHA-512 (matching type 2) for the certificate data hash.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_WARNING: {\n\t\ttitle: 'DANE HTTPS Configuration Warning',\n\t\tseverity: 'warning',\n\t\texplanation:\n\t\t\t'DANE TLSA records exist for the HTTPS endpoint but the configuration has issues that reduce their security value, such as DANE without DNSSEC or weak matching types.',\n\t\timpact: 'DANE protection is partially effective but can be bypassed or subverted.',\n\t\tadverseConsequences:\n\t\t\t'Attackers may be able to spoof or modify TLSA records if DNSSEC is absent, negating the security benefit of DANE.',\n\t\trecommendation:\n\t\t\t'Enable DNSSEC on the domain and use DANE-EE (usage 3) with SHA-256 matching (type 1) for best security.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_INFO: {\n\t\ttitle: 'DANE HTTPS Record Present',\n\t\tseverity: 'info',\n\t\texplanation: 'A TLSA record is configured at _443._tcp.{domain}, enabling DANE certificate pinning for HTTPS.',\n\t\trecommendation: 'Keep TLSA records synchronized with your TLS certificate. Automate renewal if possible.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6698'],\n\t},\n\tSVCB_HTTPS_PASS: {\n\t\ttitle: 'HTTPS Record Configured',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'HTTPS/SVCB records (RFC 9460) are present and advertise modern transport capabilities. This enables clients to negotiate HTTP/2 or HTTP/3 without an initial redirect and optionally distributes ECH parameters for privacy.',\n\t\trecommendation: 'Maintain your HTTPS records. Consider enabling ECH for enhanced connection privacy.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc9460',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc8446',\n\t\t],\n\t},\n\tSVCB_HTTPS_FAIL: {\n\t\ttitle: 'No HTTPS Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'No HTTPS record (type 65, RFC 9460) was found for this domain. HTTPS records advertise modern transport capabilities (ALPN, ECH) and allow clients to connect securely and efficiently without an initial redirect round-trip.',\n\t\timpact: 'Clients cannot discover HTTP/2 or HTTP/3 support via DNS, requiring an additional round-trip.',\n\t\tadverseConsequences:\n\t\t\t'Connection setup is slower, privacy from ECH is unavailable, and the domain misses opportunities for TLS optimization.',\n\t\trecommendation:\n\t\t\t'Publish an HTTPS record with at minimum alpn=\"h2,h3\" to enable HTTP/2 and HTTP/3 advertisement. If using Cloudflare or similar CDN, this may be automatically managed.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc9460',\n\t\t\t'https://blog.cloudflare.com/speeding-up-https-and-http-3-negotiation-with-dns/',\n\t\t],\n\t},\n\tSVCB_HTTPS_WARNING: {\n\t\ttitle: 'HTTPS Record Configuration Warning',\n\t\tseverity: 'warning',\n\t\texplanation:\n\t\t\t'HTTPS records are present but the configuration is suboptimal — for example, no ALPN parameters or missing HTTP/2 support.',\n\t\timpact: 'Clients cannot fully leverage the capabilities advertised in the HTTPS record.',\n\t\tadverseConsequences:\n\t\t\t'Performance benefits from SVCB are partially lost and ECH privacy may be unavailable.',\n\t\trecommendation:\n\t\t\t'Update HTTPS records to include alpn=\"h2,h3\" and consider adding ECH parameters. Ensure alias mode targets also have valid HTTPS records.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc9460'],\n\t},\n\tSVCB_HTTPS_INFO: {\n\t\ttitle: 'HTTPS Record Present',\n\t\tseverity: 'info',\n\t\texplanation: 'An HTTPS/SVCB record is configured, advertising modern connection capabilities for this domain.',\n\t\trecommendation: 'No action required. Consider adding ECH for enhanced privacy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc9460'],\n\t},\n};\n\nexport const DEFAULT_EXPLANATION: ExplanationTemplate = {\n\ttitle: 'Security Check Complete',\n\tseverity: 'info',\n\texplanation: \"This check has been completed. Review the findings above for details on your domain's security posture.\",\n\trecommendation: 'Refer to the specific check documentation for detailed remediation steps.',\n\treferences: ['https://www.cloudflare.com/learning/dns/what-is-dns/'],\n};\n\nexport const CATEGORY_TO_CHECKTYPE: Record<string, string> = {\n\tspf: 'SPF',\n\tdmarc: 'DMARC',\n\tdkim: 'DKIM',\n\tdnssec: 'DNSSEC',\n\tssl: 'SSL',\n\tmta_sts: 'MTA_STS',\n\tns: 'NS',\n\tcaa: 'CAA',\n\tmx: 'MX',\n\tsubdomain_takeover: 'SUBDOMAIN_TAKEOVER',\n\tsubdomailing: 'SUBDOMAILING',\n\tdane_https: 'DANE_HTTPS',\n\tsvcb_https: 'SVCB_HTTPS',\n};\n\nexport const CATEGORY_FALLBACK_IMPACT: Record<string, ImpactNarrative> = {\n\tSPF: {\n\t\timpact: 'SPF coverage is weak, so unauthorized senders can spoof domain identity more easily.',\n\t\tadverseConsequences: 'Phishing attempts and deliverability disputes increase security and support workload.',\n\t},\n\tDMARC: {\n\t\timpact: 'DMARC enforcement is reduced or absent at receiving systems.',\n\t\tadverseConsequences: 'Forged messages are more likely to reach users and erode brand trust.',\n\t},\n\tDKIM: {\n\t\timpact: 'DKIM assurance is weak, reducing message integrity and sender-authenticity confidence.',\n\t\tadverseConsequences: 'Legitimate messages may be distrusted while impersonation attempts become harder to detect.',\n\t},\n\tDNSSEC: {\n\t\timpact: 'DNS answers are more exposed to spoofing and tampering in transit.',\n\t\tadverseConsequences: 'Users can be redirected to attacker infrastructure, causing security and availability incidents.',\n\t},\n\tSSL: {\n\t\timpact: 'Transport security guarantees are reduced, increasing interception and tampering risk.',\n\t\tadverseConsequences: 'Sensitive user data may be exposed and browser trust can decline.',\n\t},\n\tMTA_STS: {\n\t\timpact: 'Inbound SMTP delivery is not consistently protected from downgrade attacks.',\n\t\tadverseConsequences: 'Confidential email content may be exposed in transit, increasing compliance risk.',\n\t},\n\tNS: {\n\t\timpact: 'DNS resolution reliability is reduced, which weakens service reachability.',\n\t\tadverseConsequences: 'Users may experience outages and business transactions may fail.',\n\t},\n\tCAA: {\n\t\timpact: 'Certificate issuance controls are weak, raising unauthorized issuance risk.',\n\t\tadverseConsequences: 'Domain impersonation and TLS trust incidents become more likely.',\n\t},\n\tMX: {\n\t\timpact: 'Mail routing reliability is reduced by MX configuration gaps or errors.',\n\t\tadverseConsequences: 'Important communications can be delayed, bounced, or lost.',\n\t},\n\tSUBDOMAIN_TAKEOVER: {\n\t\timpact: 'An orphaned delegated subdomain may be claimable by an attacker.',\n\t\tadverseConsequences: 'Users can be redirected to malicious content hosted under a trusted hostname.',\n\t},\n\tSUBDOMAILING: {\n\t\timpact: 'SPF include chain references a takeover-vulnerable domain, potentially allowing unauthorized email sending.',\n\t\tadverseConsequences: 'Attackers could send authenticated phishing emails from the trusted domain, bypassing email security controls.',\n\t},\n\tDANE_HTTPS: {\n\t\timpact: 'HTTPS certificate pinning via DANE is absent or misconfigured, leaving TLS trust dependent solely on the CA system.',\n\t\tadverseConsequences: 'A rogue or compromised CA can issue a fraudulent certificate, enabling undetected MITM attacks.',\n\t},\n\tSVCB_HTTPS: {\n\t\timpact: 'Modern transport capabilities (ALPN, ECH) cannot be advertised via DNS, reducing connection efficiency and privacy.',\n\t\tadverseConsequences: 'Clients require additional round-trips to negotiate protocols, and ECH-based privacy is unavailable.',\n\t},\n};\n\nexport const SEVERITY_FALLBACK_IMPACT: Record<string, ImpactNarrative> = {\n\tcritical: {\n\t\timpact: 'This is a high-likelihood weakness with immediate exploitation potential.',\n\t\tadverseConsequences: 'Compromise, disruption, or abuse can occur without prompt remediation.',\n\t},\n\thigh: {\n\t\timpact: 'This weakness materially increases attack surface and failure risk.',\n\t\tadverseConsequences: 'Business operations, user trust, and response workload can be negatively affected.',\n\t},\n\tmedium: {\n\t\timpact: 'This issue weakens defenses and compounds risk when paired with other gaps.',\n\t\tadverseConsequences: 'Over time it can degrade reliability, security assurance, and compliance posture.',\n\t},\n\twarning: {\n\t\timpact: 'This configuration is partially protective but leaves avoidable exposure.',\n\t\tadverseConsequences: 'If unresolved, incidents become harder to prevent or contain.',\n\t},\n\tfail: {\n\t\timpact: 'A required control is missing or not functioning as intended.',\n\t\tadverseConsequences: 'Security and availability incidents become more likely until it is corrected.',\n\t},\n\tlow: {\n\t\timpact: 'This is a minor weakness that still reduces resilience.',\n\t\tadverseConsequences: 'Operational friction and audit findings can increase over time.',\n\t},\n};\n\nexport const SPECIFIC_IMPACT_RULES: SpecificImpactRule[] = [\n\t{\n\t\tcheckType: 'DKIM',\n\t\ttitleIncludes: ['weak rsa key'],\n\t\timpact: 'Weak DKIM keys are easier to forge, reducing message authenticity assurance.',\n\t\tadverseConsequences: 'Attackers can impersonate trusted senders more easily, increasing fraud and phishing risk.',\n\t},\n\t{\n\t\tcheckType: 'SSL',\n\t\ttitleIncludes: ['no hsts header', 'no http to https redirect', 'mixed content'],\n\t\timpact: 'Users are exposed to insecure transport paths that permit interception or downgrade attacks.',\n\t\tadverseConsequences: 'Sensitive sessions and data can leak on hostile networks, weakening trust and compliance posture.',\n\t},\n\t{\n\t\tcheckType: 'DMARC',\n\t\ttitleIncludes: ['no aggregate reporting'],\n\t\timpact: 'Authentication failures and spoofing activity become harder to observe at scale.',\n\t\tadverseConsequences: 'Threats can persist longer without detection, increasing response time and abuse volume.',\n\t},\n\t{\n\t\tcheckType: 'MX',\n\t\ttitleIncludes: ['no mx records found', 'mx configuration error'],\n\t\timpact: 'Inbound email delivery becomes unreliable or fails for recipients on this domain.',\n\t\tadverseConsequences: 'Critical business and security communications may be delayed, bounced, or silently lost.',\n\t},\n\t{\n\t\tcheckType: 'NS',\n\t\ttitleIncludes: ['no soa record', 'nameserver', 'low nameserver diversity'],\n\t\timpact: 'DNS resilience and consistency are reduced, increasing partial or full resolution outage risk.',\n\t\tadverseConsequences: 'Availability incidents can affect websites, APIs, and transactional workflows.',\n\t},\n\t{\n\t\tcheckType: 'CAA',\n\t\ttitleIncludes: ['no caa records', 'issuewild', 'iodef'],\n\t\timpact: 'Certificate governance controls are weakened, especially for unauthorized or wildcard issuance.',\n\t\tadverseConsequences: 'TLS trust incidents and audit findings become more likely if certificate misuse occurs.',\n\t},\n\t{\n\t\tcheckType: 'SPF',\n\t\ttitleIncludes: ['permissive spf: +all', 'multiple spf records'],\n\t\tdetailIncludes: ['+all', 'multiple records'],\n\t\timpact: 'SPF policy becomes ineffective or ambiguous, allowing unauthorized senders to appear legitimate.',\n\t\tadverseConsequences: 'Spoofing, phishing, and deliverability failures can increase simultaneously.',\n\t},\n\t{\n\t\tcheckType: 'MTA_STS',\n\t\ttitleIncludes: ['no mta-sts', 'testing mode', 'tls-rpt'],\n\t\timpact: 'SMTP transport protections are not consistently enforced for inbound mail delivery.',\n\t\tadverseConsequences: 'Confidential email may traverse weaker paths, increasing confidentiality and regulatory risk.',\n\t},\n];","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Explain Finding tool.\n * Provides static explanations for DNS security findings.\n * No AI binding required - uses a built-in knowledge base.\n */\n\nimport type { OutputFormat } from '../handlers/tool-args';\nimport { sanitizeOutputText } from '../lib/output-sanitize';\n\nimport {\n\tCATEGORY_FALLBACK_IMPACT,\n\tCATEGORY_TO_CHECKTYPE,\n\tDEFAULT_EXPLANATION,\n\tEXPLANATIONS,\n\ttype ExplanationTemplate,\n\ttype ImpactNarrative,\n\tSEVERITY_FALLBACK_IMPACT,\n\tSPECIFIC_IMPACT_RULES,\n} from './explain-finding-data';\n\nexport interface ExplanationResult {\n\tcheckType: string;\n\tstatus: string;\n\tdetails?: string;\n\ttitle: string;\n\tseverity: string;\n\texplanation: string;\n\timpact?: string;\n\tadverseConsequences?: string;\n\trecommendation: string;\n\treferences: string[];\n}\n\ntype ExplanationEntry = ExplanationTemplate;\n\nfunction matchesRule(ruleValues: string[] | undefined, source: string): boolean {\n\tif (!ruleValues || ruleValues.length === 0) return true;\n\treturn ruleValues.some((value) => source.includes(value));\n}\n\nfunction resolveSpecificNarrative(params: {\n\tcheckType?: string;\n\ttitle?: string;\n\tdetail?: string;\n}): ImpactNarrative | undefined {\n\tconst checkType = params.checkType?.toUpperCase();\n\tconst title = params.title?.toLowerCase() ?? '';\n\tconst detail = params.detail?.toLowerCase() ?? '';\n\n\tfor (const rule of SPECIFIC_IMPACT_RULES) {\n\t\tif (rule.checkType && checkType && rule.checkType !== checkType) continue;\n\t\tif (!matchesRule(rule.titleIncludes, title)) continue;\n\t\tif (!matchesRule(rule.detailIncludes, detail)) continue;\n\t\treturn {\n\t\t\timpact: rule.impact,\n\t\t\tadverseConsequences: rule.adverseConsequences,\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction getNarrativeFromEntry(entry: ExplanationEntry | undefined): ImpactNarrative | undefined {\n\tif (!entry) return undefined;\n\tif (!entry.impact && !entry.adverseConsequences) return undefined;\n\treturn {\n\t\timpact: entry.impact,\n\t\tadverseConsequences: entry.adverseConsequences,\n\t};\n}\n\n/**\n * Resolve impact/adverse-consequence narrative for a finding context.\n * Uses explicit explanation entries first, then category, then severity fallback.\n */\nexport function resolveImpactNarrative(params: {\n\tcheckType?: string;\n\tcategory?: string;\n\tstatus?: string;\n\tseverity?: string;\n\ttitle?: string;\n\tdetail?: string;\n}): ImpactNarrative {\n\tconst normalizedCheckType = params.checkType?.toUpperCase();\n\tconst normalizedStatus = params.status?.toUpperCase();\n\tconst normalizedSeverity = params.severity?.toLowerCase();\n\tconst derivedCheckType = params.category ? CATEGORY_TO_CHECKTYPE[params.category.toLowerCase()] : undefined;\n\n\tif (normalizedCheckType && normalizedStatus) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${normalizedCheckType}_${normalizedStatus}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (normalizedCheckType && normalizedSeverity) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${normalizedCheckType}_${normalizedSeverity.toUpperCase()}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (derivedCheckType && normalizedStatus) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${derivedCheckType}_${normalizedStatus}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (derivedCheckType && normalizedSeverity) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${derivedCheckType}_${normalizedSeverity.toUpperCase()}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tconst specificNarrative = resolveSpecificNarrative({\n\t\tcheckType: normalizedCheckType ?? derivedCheckType,\n\t\ttitle: params.title,\n\t\tdetail: params.detail,\n\t});\n\tif (specificNarrative) return specificNarrative;\n\n\tif (normalizedCheckType && CATEGORY_FALLBACK_IMPACT[normalizedCheckType]) {\n\t\treturn CATEGORY_FALLBACK_IMPACT[normalizedCheckType];\n\t}\n\n\tif (derivedCheckType && CATEGORY_FALLBACK_IMPACT[derivedCheckType]) {\n\t\treturn CATEGORY_FALLBACK_IMPACT[derivedCheckType];\n\t}\n\n\tif (normalizedSeverity && SEVERITY_FALLBACK_IMPACT[normalizedSeverity]) {\n\t\treturn SEVERITY_FALLBACK_IMPACT[normalizedSeverity];\n\t}\n\n\treturn {};\n}\n\nexport function explainFinding(checkType: string, status: string, details?: string): ExplanationResult {\n\tconst normalizedType = checkType.toUpperCase();\n\tconst key = `${normalizedType}_${status.toUpperCase()}`;\n\n\t// 1. Try checkType_STATUS key\n\tlet entry: ExplanationTemplate | undefined = EXPLANATIONS[key];\n\n\t// 2. Fall back to default\n\tif (!entry) {\n\t\tentry = DEFAULT_EXPLANATION;\n\t}\n\n\tconst narrative = resolveImpactNarrative({ checkType: normalizedType, status, detail: details });\n\n\treturn {\n\t\tcheckType: normalizedType,\n\t\tstatus,\n\t\tdetails,\n\t\t...entry,\n\t\timpact: entry.impact ?? narrative.impact,\n\t\tadverseConsequences: entry.adverseConsequences ?? narrative.adverseConsequences,\n\t};\n}\n\nexport function formatExplanation(result: ExplanationResult, format: OutputFormat = 'full'): string {\n\tif (format === 'compact') {\n\t\tconst lines = [\n\t\t\t`${result.title} (${result.checkType} | ${result.status})`,\n\t\t\tsanitizeOutputText(result.explanation, 200),\n\t\t\t`Recommendation: ${sanitizeOutputText(result.recommendation, 200)}`,\n\t\t];\n\t\treturn lines.join('\\n');\n\t}\n\n\tconst lines = [`## ${result.title}`, `**Check Type:** ${result.checkType} | **Status:** ${result.status}`, ''];\n\n\tlines.push(`### What this means`, result.explanation, '');\n\n\tif (result.impact) {\n\t\tlines.push(`### Potential Impact`, result.impact, '');\n\t}\n\n\tif (result.adverseConsequences) {\n\t\tlines.push(`### Adverse Consequences`, result.adverseConsequences, '');\n\t}\n\n\tlines.push(`### Recommendation`, result.recommendation, '', `### References`, ...result.references.map((reference) => `- ${reference}`));\n\treturn lines.join('\\n');\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Category interaction scoring — post-scoring adjustments for correlated weaknesses.\n *\n * Applied after computeScanScore() as a separate penalty layer.\n * Does NOT modify categoryScores — only adjusts the overall score.\n * Existing compare_baseline CI/CD workflows continue to work identically.\n */\n\nimport type { CheckCategory, ScanScore } from './scoring-model';\nimport { scoreToGrade } from './scoring-engine';\nimport type { ScoringConfig } from './scoring-config';\n\n/** A condition that must be met for an interaction rule to fire. */\ninterface InteractionCondition {\n\tcategory: CheckCategory;\n\t/** Maximum category score for the condition to be true (score <= maxScore). */\n\tmaxScore?: number;\n\t/** Minimum category score for the condition to be true (score >= minScore). */\n\tminScore?: number;\n}\n\n/** An interaction rule that applies a penalty when all conditions are met. */\nexport interface InteractionRule {\n\t/** Unique identifier for the interaction. */\n\tid: string;\n\t/** All conditions must be satisfied for the penalty to apply. */\n\tconditions: InteractionCondition[];\n\t/** Additional points deducted from the overall score. */\n\toverallPenalty: number;\n\t/** Human-readable explanation of the interaction effect. */\n\tnarrative: string;\n}\n\n/** Result of applying interaction rules to a scan score. */\nexport interface InteractionEffect {\n\truleId: string;\n\tpenalty: number;\n\tnarrative: string;\n}\n\n/** Interaction rules — correlated weaknesses that amplify risk. */\nexport const INTERACTION_RULES: InteractionRule[] = [\n\t{\n\t\tid: 'weak_dkim_permissive_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'dkim', maxScore: 40 },\n\t\t\t{ category: 'dmarc', maxScore: 60 },\n\t\t],\n\t\toverallPenalty: 5,\n\t\tnarrative: 'Weak DKIM combined with permissive DMARC creates multiplicative spoofing risk — attackers can forge messages that pass relaxed alignment checks.',\n\t},\n\t{\n\t\tid: 'no_spf_no_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'spf', maxScore: 0 },\n\t\t\t{ category: 'dmarc', maxScore: 0 },\n\t\t],\n\t\toverallPenalty: 10,\n\t\tnarrative: 'Complete absence of both SPF and DMARC means any server can send as this domain with no detection mechanism.',\n\t},\n\t{\n\t\tid: 'weak_dnssec_enforcing_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'dmarc', minScore: 80 },\n\t\t\t{ category: 'dnssec', maxScore: 40 },\n\t\t],\n\t\toverallPenalty: 3,\n\t\tnarrative: 'Strong email authentication is in place but DNSSEC is weak or absent — DNS tampering could undermine authentication records.',\n\t},\n\t{\n\t\tid: 'no_spf_no_dkim',\n\t\tconditions: [\n\t\t\t{ category: 'spf', maxScore: 0 },\n\t\t\t{ category: 'dkim', maxScore: 0 },\n\t\t],\n\t\toverallPenalty: 5,\n\t\tnarrative: 'Neither SPF nor DKIM is configured — DMARC alignment cannot be satisfied through either mechanism, making enforcement ineffective even if DMARC is published.',\n\t},\n\t{\n\t\tid: 'weak_ssl_no_http_security',\n\t\tconditions: [\n\t\t\t{ category: 'ssl', maxScore: 40 },\n\t\t\t{ category: 'http_security', maxScore: 30 },\n\t\t],\n\t\toverallPenalty: 3,\n\t\tnarrative: 'Weak SSL/TLS combined with missing HTTP security headers exposes the domain to man-in-the-middle attacks and content injection.',\n\t},\n];\n\n/** Check if a single condition is satisfied by the category scores. */\nfunction conditionMet(condition: InteractionCondition, categoryScores: Record<string, number>): boolean {\n\tconst score = categoryScores[condition.category];\n\tif (score === undefined) return false;\n\n\tif (condition.maxScore !== undefined && score > condition.maxScore) return false;\n\tif (condition.minScore !== undefined && score < condition.minScore) return false;\n\n\treturn true;\n}\n\n/**\n * Apply interaction penalties to a scan score.\n *\n * This is a post-scoring adjustment — categoryScores remain unchanged,\n * only the overall score and grade are updated.\n *\n * @param score - The computed scan score from computeScanScore()\n * @param config - Optional scoring config for grade computation\n * @returns Updated score with interaction penalties applied, plus the list of triggered effects\n */\nexport function applyInteractionPenalties(\n\tscore: ScanScore,\n\tconfig?: ScoringConfig,\n): { adjustedScore: ScanScore; effects: InteractionEffect[] } {\n\tconst effects: InteractionEffect[] = [];\n\tlet totalPenalty = 0;\n\n\tfor (const rule of INTERACTION_RULES) {\n\t\tconst allMet = rule.conditions.every((c) => conditionMet(c, score.categoryScores));\n\t\tif (allMet) {\n\t\t\teffects.push({\n\t\t\t\truleId: rule.id,\n\t\t\t\tpenalty: rule.overallPenalty,\n\t\t\t\tnarrative: rule.narrative,\n\t\t\t});\n\t\t\ttotalPenalty += rule.overallPenalty;\n\t\t}\n\t}\n\n\tif (totalPenalty === 0) {\n\t\treturn { adjustedScore: score, effects };\n\t}\n\n\tconst adjustedOverall = Math.max(0, score.overall - totalPenalty);\n\tconst adjustedGrade = scoreToGrade(adjustedOverall, config);\n\n\t// Update summary if grade changed\n\tlet summary = score.summary;\n\tif (adjustedGrade !== score.grade) {\n\t\tsummary = summary.replace(`Grade: ${score.grade}`, `Grade: ${adjustedGrade}`);\n\t}\n\n\treturn {\n\t\tadjustedScore: {\n\t\t\t...score,\n\t\t\toverall: adjustedOverall,\n\t\t\tgrade: adjustedGrade,\n\t\t\tsummary,\n\t\t},\n\t\teffects,\n\t};\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Structured logging utility for Cloudflare Worker (MCP server)\n * Logs JSON objects with request, tool, result, and error metadata\n * Usage: logEvent({ ... })\n */\n\nexport type LogEvent = {\n\ttimestamp: string;\n\trequestId?: string;\n\tip?: string;\n\ttool?: string;\n\tdomain?: string;\n\tseverity?: 'info' | 'warn' | 'error';\n\tcategory?: string;\n\tresult?: string;\n\tdetails?: unknown;\n\terror?: string;\n\tdurationMs?: number;\n\tuserAgent?: string;\n};\n\nconst REDACTED = '[redacted]';\nconst MAX_LOG_STRING_LENGTH = 256;\nconst SENSITIVE_KEY_PATTERN = /(^ip$|authorization|mcp-session-id|session|token|api[-_]?key|secret|password|cookie|rawbody)/i;\n\nfunction isSensitiveKey(key: string): boolean {\n\treturn !/^has[A-Z]/.test(key) && SENSITIVE_KEY_PATTERN.test(key);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction sanitizeString(value: string): string {\n\t// Strip control characters (except tab) to prevent log injection via newlines/ANSI sequences\n\tconst stripped = value.replace(/[\\x00-\\x08\\x0a-\\x1f\\x7f]/g, ' ');\n\treturn stripped.length > MAX_LOG_STRING_LENGTH ? `${stripped.slice(0, MAX_LOG_STRING_LENGTH)}...` : stripped;\n}\n\nexport function sanitizeLogValue(value: unknown, key?: string): unknown {\n\tif (key && isSensitiveKey(key)) {\n\t\treturn REDACTED;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn sanitizeString(value);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item) => sanitizeLogValue(item));\n\t}\n\n\tif (isPlainObject(value)) {\n\t\tconst sanitized: Record<string, unknown> = {};\n\t\tfor (const [entryKey, entryValue] of Object.entries(value)) {\n\t\t\tsanitized[entryKey] = sanitizeLogValue(entryValue, entryKey);\n\t\t}\n\t\treturn sanitized;\n\t}\n\n\treturn value;\n}\n\nexport function sanitizeHeadersForLog(headers: Headers | Record<string, string>): Record<string, string> {\n\tconst sanitized: Record<string, string> = {};\n\tif (headers instanceof Headers) {\n\t\theaders.forEach((value, rawKey) => {\n\t\t\tconst key = rawKey.toLowerCase();\n\t\t\tsanitized[key] = isSensitiveKey(key) ? REDACTED : sanitizeString(value);\n\t\t});\n\t\treturn sanitized;\n\t}\n\n\tfor (const [rawKey, value] of Object.entries(headers)) {\n\t\tconst key = rawKey.toLowerCase();\n\t\tsanitized[key] = isSensitiveKey(key) ? REDACTED : sanitizeString(value);\n\t}\n\treturn sanitized;\n}\n\n/**\n * Emit a structured log event (console.log as JSON)\n */\nexport function logEvent(event: LogEvent): void {\n\tconst log = {\n\t\t...event,\n\t\ttimestamp: event.timestamp || new Date().toISOString(),\n\t\tdetails: sanitizeLogValue(event.details),\n\t\terror: typeof event.error === 'string' ? sanitizeString(event.error) : event.error,\n\t};\n\tconsole.log(JSON.stringify(log));\n}\n\n/**\n * Helper for error logging\n */\nexport function logError(error: Error | string, context?: Partial<LogEvent>): void {\n\tlogEvent({\n\t\ttimestamp: new Date().toISOString(),\n\t\tseverity: 'error',\n\t\terror: typeof error === 'string' ? error : error.message,\n\t\t...context,\n\t});\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { INFLIGHT_CLEANUP_MS } from './config';\nimport { logError } from './log';\n\n/**\n * TTL cache for DNS scan results.\n *\n * Uses Cloudflare KV for persistent caching when available,\n * with in-memory fallback when KV is not configured.\n *\n * Cloudflare Workers compatible - no Node.js APIs.\n */\n\ninterface CacheEntry<T> {\n\tvalue: T;\n\texpiresAt: number;\n}\n\ninterface CacheOptions {\n\t/** Time-to-live in milliseconds. Default: 5 minutes (300_000ms) */\n\tttlMs?: number;\n\t/** Maximum number of entries. Default: 1000 */\n\tmaxEntries?: number;\n}\n\nconst DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_TTL_SECONDS = 300; // 5 minutes in seconds (for KV expirationTtl)\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport class TTLCache<T = unknown> {\n\tprivate readonly store = new Map<string, CacheEntry<T>>();\n\tprivate readonly ttlMs: number;\n\tprivate readonly maxEntries: number;\n\n\tconstructor(options: CacheOptions = {}) {\n\t\tthis.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;\n\t\tthis.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n\t}\n\n\t/**\n\t * Get a cached value by key. Returns undefined if not found or expired.\n\t */\n\tget(key: string): T | undefined {\n\t\tconst entry = this.store.get(key);\n\t\tif (!entry) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (Date.now() > entry.expiresAt) {\n\t\t\tthis.store.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn entry.value;\n\t}\n\n\t/**\n\t * Set a value in the cache with optional custom TTL.\n\t */\n\tset(key: string, value: T, ttlMs?: number): void {\n\t\t// Evict expired entries if at capacity\n\t\tif (this.store.size >= this.maxEntries && !this.store.has(key)) {\n\t\t\tthis.evictExpired();\n\t\t}\n\t\t// If still at capacity after eviction, remove oldest entry\n\t\tif (this.store.size >= this.maxEntries && !this.store.has(key)) {\n\t\t\tconst firstKey = this.store.keys().next().value;\n\t\t\tif (firstKey !== undefined) {\n\t\t\t\tthis.store.delete(firstKey);\n\t\t\t}\n\t\t}\n\t\tthis.store.set(key, {\n\t\t\tvalue,\n\t\t\texpiresAt: Date.now() + (ttlMs ?? this.ttlMs),\n\t\t});\n\t}\n\n\t/**\n\t * Check if a key exists and is not expired.\n\t */\n\thas(key: string): boolean {\n\t\treturn this.get(key) !== undefined;\n\t}\n\n\t/**\n\t * Delete a specific key from the cache.\n\t */\n\tdelete(key: string): boolean {\n\t\treturn this.store.delete(key);\n\t}\n\n\t/**\n\t * Remove all entries from the cache.\n\t */\n\tclear(): void {\n\t\tthis.store.clear();\n\t}\n\n\t/**\n\t * Get the number of entries (including potentially expired ones).\n\t */\n\tget size(): number {\n\t\treturn this.store.size;\n\t}\n\n\t/**\n\t * Remove all expired entries from the cache.\n\t */\n\tevictExpired(): number {\n\t\tconst now = Date.now();\n\t\tlet evicted = 0;\n\t\tfor (const [key, entry] of this.store) {\n\t\t\tif (now > entry.expiresAt) {\n\t\t\t\tthis.store.delete(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n}\n\n/** In-flight promise map for cache stampede (thundering herd) protection */\nconst INFLIGHT = new Map<string, Promise<unknown>>();\n\n/** In-memory cache instance used as fallback when KV is unavailable */\nexport const IN_MEMORY_CACHE = new TTLCache<unknown>({\n\tttlMs: DEFAULT_TTL_MS,\n\tmaxEntries: DEFAULT_MAX_ENTRIES,\n});\n\n// ---------------------------------------------------------------------------\n// KV-backed cache functions\n// ---------------------------------------------------------------------------\n\n/**\n * Get a cached value by key.\n * Uses KV when available, falls back to in-memory.\n *\n * @param key - Cache key\n * @param kv - Optional KV namespace for persistent caching\n */\nexport async function cacheGet<T>(key: string, kv?: KVNamespace): Promise<T | undefined> {\n if (kv) {\n\t try {\n\t\t const val = await kv.get(key, 'json');\n\t\t return (val ?? undefined) as T | undefined; // KV.get('json') returns unknown; generic T is caller-enforced\n\t } catch {\n\t\t // KV error — log warning and fall through to in-memory\n\t\t logError('[cache] KV get failed, falling back to in-memory');\n\t }\n }\n return IN_MEMORY_CACHE.get(key) as T | undefined;\n}\n\n/**\n * Set a cached value with configurable TTL.\n * Uses KV when available, falls back to in-memory.\n *\n * @param key - Cache key\n * @param value - Value to cache (must be JSON-serializable for KV)\n * @param kv - Optional KV namespace for persistent caching\n * @param ttlSeconds - Cache TTL in seconds (default: 300 = 5 minutes)\n */\n/**\n * Set a cached value, deferring the KV write via ctx.waitUntil() to avoid blocking the response.\n * Falls back to synchronous cacheSet when no ExecutionContext is provided.\n */\nexport function cacheSetDeferred(key: string, value: unknown, ctx: ExecutionContext, kv?: KVNamespace, ttlSeconds?: number): void {\n\tctx.waitUntil(cacheSet(key, value, kv, ttlSeconds));\n}\n\nexport async function cacheSet(key: string, value: unknown, kv?: KVNamespace, ttlSeconds?: number): Promise<void> {\n const ttl = ttlSeconds ?? DEFAULT_TTL_SECONDS;\n if (kv) {\n\t try {\n\t\t await kv.put(key, JSON.stringify(value), { expirationTtl: ttl });\n\t\t return;\n\t } catch {\n\t\t // KV error — log warning and fall through to in-memory\n\t\t logError('[cache] KV put failed, falling back to in-memory');\n\t }\n }\n IN_MEMORY_CACHE.set(key, value, ttl * 1000);\n}\n\n/**\n * Run a function with cache-aside logic: returns cached value if available,\n * otherwise executes the function and caches the result.\n * Includes in-flight deduplication to prevent cache stampedes.\n *\n * @param key - Cache key\n * @param run - Async function to execute on cache miss\n * @param kv - Optional KV namespace for persistent caching\n * @param ttlSeconds - Cache TTL in seconds (default: 300 = 5 minutes)\n * @param skipCache - When true, bypass cache lookup and always execute the function (result is still cached)\n * @returns The cached or freshly computed result\n */\nexport async function runWithCache<T>(key: string, run: () => Promise<T>, kv?: KVNamespace, ttlSeconds?: number, skipCache?: boolean): Promise<T> {\n\tif (!skipCache) {\n\t\tconst cached = await cacheGet<T>(key, kv);\n\t\tif (cached !== undefined) return cached;\n\t}\n\n\tconst existing = INFLIGHT.get(key);\n\tif (existing) return existing as Promise<T>; // INFLIGHT map stores Promise<unknown>; keyed by same cache key ensures type match\n\n\tconst cleanup = setTimeout(() => INFLIGHT.delete(key), INFLIGHT_CLEANUP_MS);\n\tconst promise = run()\n\t\t.then(async (result) => {\n\t\t\tawait cacheSet(key, result, kv, ttlSeconds);\n\t\t\treturn result;\n\t\t})\n\t\t.finally(() => {\n\t\t\tclearTimeout(cleanup);\n\t\t\tINFLIGHT.delete(key);\n\t\t});\n\n\tINFLIGHT.set(key, promise);\n\treturn promise;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * HTTP security headers check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n * Post-augments with CDN provider detection from response headers.\n */\n\nimport { checkHTTPSecurity } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { createFinding } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\n/** Detect CDN provider from HTTP response headers. Returns provider name or null. */\nfunction detectCdnProvider(headers: Headers): string | null {\n\tif (headers.get('cf-ray') || headers.get('server')?.toLowerCase().includes('cloudflare')) {\n\t\treturn 'Cloudflare';\n\t}\n\tif (headers.get('x-vercel-id') || headers.get('x-vercel-cache')) {\n\t\treturn 'Vercel';\n\t}\n\tif (headers.get('x-amz-cf-id') || headers.get('via')?.includes('CloudFront')) {\n\t\treturn 'CloudFront';\n\t}\n\tconst servedBy = headers.get('x-served-by') ?? '';\n\tif (servedBy.includes('cache') || headers.get('via')?.toLowerCase().includes('varnish')) {\n\t\treturn 'Fastly';\n\t}\n\tif (headers.get('x-akamai-transformed') || headers.get('x-check-cacheable')) {\n\t\treturn 'Akamai';\n\t}\n\treturn null;\n}\n\n/**\n * Check HTTP security headers for a domain.\n * Fetches the HTTPS endpoint and analyzes browser security headers.\n * Detects CDN provider and adds an info finding when CDN headers are present.\n */\nexport async function checkHttpSecurity(domain: string): Promise<CheckResult> {\n\tlet capturedHeaders: Headers | null = null;\n\tconst capturingFetch: typeof fetch = async (input, init) => {\n\t\tconst response = await fetch(input, init);\n\t\tcapturedHeaders = response.headers;\n\t\treturn response;\n\t};\n\n\tconst result = await checkHTTPSecurity(domain, capturingFetch, { timeout: HTTPS_TIMEOUT_MS }) as CheckResult;\n\n\tif (!capturedHeaders) return result;\n\n\tconst cdnProvider = detectCdnProvider(capturedHeaders);\n\tif (!cdnProvider) return result;\n\n\t// Only annotate CDN when headers were actually analyzed.\n\t// If the check was blocked (WAF, connection refused, etc.) or timed out,\n\t// capturedHeaders may reflect the error response, not the security response.\n\tconst isUnanalyzable =\n\t\tresult.checkStatus === 'error' ||\n\t\tresult.checkStatus === 'timeout' ||\n\t\tresult.findings.some((f) => f.metadata?.missingControl === true);\n\tif (isUnanalyzable) return result;\n\n\tconst cdnFinding = createFinding(\n\t\t'http_security',\n\t\t`HTTP headers via ${cdnProvider} CDN`,\n\t\t'info',\n\t\t`HTTP security headers may be provided by ${cdnProvider} CDN rather than the origin server. CDN-applied headers do not reflect the origin server's security configuration.`,\n\t\t{ cdnProvider },\n\t);\n\n\treturn { ...result, findings: [...result.findings, cdnFinding] };\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DANE (DNS-Based Authentication of Named Entities) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDANE } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DANE TLSA records for a domain's MX servers and HTTPS endpoint.\n */\nexport async function checkDane(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDANE(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DANE-HTTPS check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDANEHTTPS } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DANE TLSA records for a domain's HTTPS endpoint (_443._tcp.{domain}).\n */\nexport async function checkDaneHttps(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDANEHTTPS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SVCB/HTTPS DNS record check tool (RFC 9460).\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSVCBHTTPS } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check HTTPS/SVCB records (RFC 9460) for a domain.\n */\nexport async function checkSvcbHttps(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSVCBHTTPS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SubdoMailing check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSubdomailing as checkSubdomailingCore } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check for SubdoMailing risk by analyzing SPF include chain for takeover-vulnerable domains.\n */\nexport async function checkSubdomailing(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSubdomailingCore(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { type CheckCategory, type CheckResult, type Finding, buildCheckResult, createFinding } from '../../lib/scoring';\nimport { queryTxtRecords } from '../../lib/dns';\nimport { detectProviderMatches, detectProviderMatchesBySelectors, loadProviderSignatures } from '../../lib/provider-signatures';\nimport { parseDmarcTags } from '../check-dmarc';\n\nexport interface ScanRuntimeOptions {\n\tproviderSignaturesUrl?: string;\n\tproviderSignaturesAllowedHosts?: string[];\n\tproviderSignaturesSha256?: string;\n\tprofile?: 'mail_enabled' | 'enterprise_mail' | 'non_mail' | 'web_only' | 'minimal' | 'auto';\n\tprofileAccumulator?: DurableObjectNamespace;\n\twaitUntil?: (promise: Promise<unknown>) => void;\n\tscoringConfig?: import('../../lib/scoring-config').ScoringConfig;\n\t/** Override cache TTL in seconds (default: 300). Clamped to [60, 3600]. */\n\tcacheTtlSeconds?: number;\n\t/** Custom secondary DoH resolver config (bv-dns). Threaded to scanDns but only active when skipSecondaryConfirmation is false. */\n\tsecondaryDoh?: import('../../lib/dns-types').SecondaryDohConfig;\n\t/** Bypass cache and run a fresh scan. Useful for troubleshooting after DNS changes. */\n\tforceRefresh?: boolean;\n}\n\nexport async function applyScanPostProcessing(\n\tdomain: string,\n\tcheckResults: CheckResult[],\n\truntimeOptions?: ScanRuntimeOptions,\n): Promise<CheckResult[]> {\n\tlet results = checkResults;\n\tconst mxResult = results.find((result) => result.category === 'mx');\n\tconst hasNoMx = mxResult ? mxResult.findings.some((finding: Finding) => finding.title === 'No MX records found') : false;\n\n\tif (hasNoMx) {\n\t\tconst apexCovers = await checkApexDmarcPolicy(domain);\n\t\tresults = adjustForNonMailDomain(results, apexCovers);\n\t\tresults = adjustBimiForNonMailDomain(results);\n\t} else if (mxResult) {\n\t\tresults = clarifyMtaStsForMailDomain(domain, results);\n\t}\n\n\t// Detect no-send SPF policy (v=spf1 -all with no authorizing mechanisms)\n\tconst spfResult = results.find((result) => result.category === 'spf');\n\tconst hasNoSendPolicy = spfResult?.findings.some((f: Finding) => f.metadata?.noSendPolicy === true) ?? false;\n\tif (hasNoSendPolicy && !hasNoMx) {\n\t\tresults = adjustForNoSendDomain(results);\n\t}\n\n\treturn addOutboundProviderInference(results, runtimeOptions);\n}\n\nfunction extractSpfSignalDomains(result: CheckResult | undefined): string[] {\n\tif (!result) return [];\n\n\tconst domains = new Set<string>();\n\tfor (const finding of result.findings) {\n\t\tconst metadata = finding.metadata;\n\t\tif (!metadata || typeof metadata !== 'object') continue;\n\n\t\tconst includeDomains = metadata.includeDomains;\n\t\tif (Array.isArray(includeDomains)) {\n\t\t\tfor (const domain of includeDomains) {\n\t\t\t\tif (typeof domain === 'string' && domain.trim().length > 0) {\n\t\t\t\t\tdomains.add(domain.trim().toLowerCase());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst redirectDomain = metadata.redirectDomain;\n\t\tif (typeof redirectDomain === 'string' && redirectDomain.trim().length > 0) {\n\t\t\tdomains.add(redirectDomain.trim().toLowerCase());\n\t\t}\n\t}\n\n\treturn Array.from(domains);\n}\n\nfunction extractDkimSignalSelectors(result: CheckResult | undefined): string[] {\n\tif (!result) return [];\n\n\tconst selectors = new Set<string>();\n\tfor (const finding of result.findings) {\n\t\tconst metadata = finding.metadata;\n\t\tif (!metadata || typeof metadata !== 'object') continue;\n\n\t\tconst selectorsFound = metadata.selectorsFound;\n\t\tif (!Array.isArray(selectorsFound)) continue;\n\n\t\tfor (const selector of selectorsFound) {\n\t\t\tif (typeof selector === 'string' && selector.trim().length > 0) {\n\t\t\t\tselectors.add(selector.trim().toLowerCase());\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(selectors);\n}\n\nfunction upsertCheckResult(results: CheckResult[], updated: CheckResult): CheckResult[] {\n\treturn results.map((result) => (result.category === updated.category ? updated : result));\n}\n\nasync function addOutboundProviderInference(results: CheckResult[], runtimeOptions?: ScanRuntimeOptions): Promise<CheckResult[]> {\n\tconst spfResult = results.find((result) => result.category === 'spf');\n\tconst dkimResult = results.find((result) => result.category === 'dkim');\n\n\tconst signalDomains = extractSpfSignalDomains(spfResult);\n\tconst dkimSelectors = extractDkimSignalSelectors(dkimResult);\n\tif (signalDomains.length === 0 && dkimSelectors.length === 0) return results;\n\n\tconst signatures = await loadProviderSignatures({\n\t\tsourceUrl: runtimeOptions?.providerSignaturesUrl,\n\t\tallowedHosts: runtimeOptions?.providerSignaturesAllowedHosts,\n\t\texpectedSha256: runtimeOptions?.providerSignaturesSha256,\n\t});\n\tconst signatureSet = signatures.outbound.length > 0 ? signatures.outbound : signatures.inbound;\n\tconst hostMatches = detectProviderMatches(signalDomains, signatureSet);\n\tconst selectorMatches = detectProviderMatchesBySelectors(dkimSelectors, signatureSet);\n\n\tconst mergedMatches = new Map<string, Set<string>>();\n\tfor (const match of [...hostMatches, ...selectorMatches]) {\n\t\tif (!mergedMatches.has(match.provider)) {\n\t\t\tmergedMatches.set(match.provider, new Set<string>());\n\t\t}\n\t\tfor (const evidence of match.matches) {\n\t\t\tmergedMatches.get(match.provider)?.add(evidence);\n\t\t}\n\t}\n\n\tconst outboundMatches = Array.from(mergedMatches.entries()).map(([provider, matches]) => ({\n\t\tprovider,\n\t\tmatches: Array.from(matches),\n\t}));\n\tif (outboundMatches.length === 0) return results;\n\n\tconst providerNames = outboundMatches.map((match) => match.provider).join(', ');\n\tconst evidence = outboundMatches.map((match) => `${match.provider}: ${match.matches.join(', ')}`).join('; ');\n\tconst signalBoost = signalDomains.length > 0 && dkimSelectors.length > 0 ? 0.05 : 0;\n\tconst baseConfidence = signatures.source === 'runtime' ? 0.85 : signatures.source === 'stale' ? 0.7 : 0.65;\n\tconst providerConfidence = Math.min(0.95, baseConfidence + signalBoost);\n\n\tconst spfBaseline = spfResult ?? buildCheckResult('spf', []);\n\tconst updatedSpf = buildCheckResult('spf', [\n\t\t...spfBaseline.findings,\n\t\tcreateFinding('spf', 'Outbound email provider inferred', 'info', `Outbound provider(s): ${providerNames}. Evidence: ${evidence}.`, {\n\t\t\tdetectionType: 'outbound',\n\t\t\tproviders: outboundMatches.map((match) => ({ name: match.provider, matches: match.matches })),\n\t\t\tsignalsUsed: {\n\t\t\t\tspfDomains: signalDomains,\n\t\t\t\tdkimSelectors,\n\t\t\t},\n\t\t\tproviderConfidence,\n\t\t\tsignatureSource: signatures.source,\n\t\t\tsignatureVersion: signatures.version,\n\t\t\tsignatureFetchedAt: signatures.fetchedAt,\n\t\t}),\n\t]);\n\n\treturn upsertCheckResult(results, updatedSpf);\n}\n\nfunction getParentDomain(domain: string): string | null {\n\tconst parts = domain.split('.');\n\tif (parts.length <= 2) return null;\n\treturn parts.slice(1).join('.');\n}\n\nasync function checkApexDmarcPolicy(domain: string): Promise<boolean> {\n\tconst parent = getParentDomain(domain);\n\tif (!parent) return false;\n\n\ttry {\n\t\tconst records = await queryTxtRecords(`_dmarc.${parent}`);\n\t\tconst dmarcRecord = records.find((record) => record.toLowerCase().startsWith('v=dmarc1'));\n\t\tif (!dmarcRecord) return false;\n\n\t\tconst tags = parseDmarcTags(dmarcRecord);\n\t\tconst effectivePolicy = tags.get('sp') || tags.get('p') || '';\n\t\treturn effectivePolicy === 'quarantine' || effectivePolicy === 'reject';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isMissingRecordFinding(finding: { title: string; detail: string }): boolean {\n\t// Match against title only (controlled by check modules, not DNS data) to avoid ReDoS on attacker-controlled detail strings\n\tconst title = finding.title.toLowerCase();\n\treturn (\n\t\ttitle.includes('missing') ||\n\t\ttitle.includes('not found') ||\n\t\ttitle.includes('no mta-sts') ||\n\t\ttitle.includes('no dkim') ||\n\t\t/^no\\s+\\S+\\s+record/.test(title)\n\t);\n}\n\nfunction clarifyMtaStsForMailDomain(domain: string, results: CheckResult[]): CheckResult[] {\n\treturn results.map((result) => {\n\t\tif (result.category !== 'mta_sts') return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif (finding.title === 'No MTA-STS or TLS-RPT records found') {\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tdetail: `Neither MTA-STS nor TLS-RPT records are present for ${domain}. Since this domain has MX records and accepts email, adding MTA-STS and TLS-RPT is recommended to protect inbound email in transit.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustForNonMailDomain(results: CheckResult[], apexDmarcCovers: boolean): CheckResult[] {\n\tconst emailCategories: CheckCategory[] = ['spf', 'dmarc', 'dkim', 'mta_sts', 'subdomailing'];\n\treturn results.map((result) => {\n\t\tif (!emailCategories.includes(result.category)) return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif ((finding.severity === 'critical' || finding.severity === 'high') && isMissingRecordFinding(finding)) {\n\t\t\t\tconst reason = apexDmarcCovers\n\t\t\t\t\t? 'expected — no MX records and parent domain DMARC policy covers subdomains'\n\t\t\t\t\t: 'expected — domain has no MX records';\n\t\t\t\treturn { ...finding, severity: 'info' as const, detail: `${finding.detail} (${reason})` };\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustBimiForNonMailDomain(results: CheckResult[]): CheckResult[] {\n\treturn results.map((result) => {\n\t\tif (result.category !== 'bimi') return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif (finding.title === 'No BIMI record found' && finding.detail.includes('eligible for BIMI')) {\n\t\t\t\tconst bimiDomain = finding.detail.match(/at (default\\._bimi\\.\\S+)/)?.[1] ?? `default._bimi.unknown`;\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tdetail: `No BIMI record found at ${bimiDomain}. This domain does not appear to send email, so BIMI is not applicable.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustForNoSendDomain(results: CheckResult[]): CheckResult[] {\n\tconst noSendCategories: CheckCategory[] = ['dkim', 'mta_sts', 'bimi'];\n\treturn results.map((result) => {\n\t\tif (!noSendCategories.includes(result.category)) return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif ((finding.severity === 'critical' || finding.severity === 'high') && isMissingRecordFinding(finding)) {\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tseverity: 'info' as const,\n\t\t\t\t\tdetail: `${finding.detail} (expected — domain SPF policy rejects all outbound mail)`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Email Security Maturity Staging.\n * Classifies a domain's email security posture into a maturity stage (0-4)\n * based on the results of individual DNS security checks.\n */\n\nimport type { CheckResult, Finding } from '../../lib/scoring';\n\nexport interface MaturityStage {\n\tstage: number;\n\tlabel: string;\n\tdescription: string;\n\tnextStep: string;\n}\n\n/**\n * Compute the email security maturity stage from scan check results.\n * Stages range from 0 (Unprotected) to 4 (Hardened).\n */\n/**\n * Cap the maturity stage based on the overall scan score.\n * Prevents a domain from being labeled \"Hardened\" or \"Enforcing\"\n * when the actual security score indicates significant issues.\n *\n * - Score < 50 (F grade): cap at Stage 2 maximum\n * - Score < 63 (D/D+ grade): cap at Stage 3 maximum\n * - Score >= 63: no cap applied\n *\n * Stages already at or below the cap are returned unchanged.\n */\nexport function capMaturityStage(maturity: MaturityStage, score: number): MaturityStage {\n\tif (score < 50 && maturity.stage > 2) {\n\t\treturn {\n\t\t\tstage: 2,\n\t\t\tlabel: 'Monitoring (score-capped)',\n\t\t\tdescription: 'Controls are present but the overall security score is too low for a higher maturity rating.',\n\t\t\tnextStep: 'Address critical and high-severity findings to improve the overall score before advancing maturity.',\n\t\t};\n\t}\n\n\tif (score < 63 && maturity.stage > 3) {\n\t\treturn {\n\t\t\tstage: 3,\n\t\t\tlabel: 'Enforcing (score-capped)',\n\t\t\tdescription: 'Controls are present but the overall security score is too low for the highest maturity rating.',\n\t\t\tnextStep: 'Resolve remaining findings to raise the score above the D grade range and achieve full hardening.',\n\t\t};\n\t}\n\n\treturn maturity;\n}\n\nexport function computeMaturityStage(checks: CheckResult[]): MaturityStage {\n\tconst byCategory = new Map(checks.map((c) => [c.category, c]));\n\n\tconst mxCheck = byCategory.get('mx');\n\tconst spfCheck = byCategory.get('spf');\n\tconst dmarcCheck = byCategory.get('dmarc');\n\tconst dkimCheck = byCategory.get('dkim');\n\tconst mtaStsCheck = byCategory.get('mta_sts');\n\tconst dnssecCheck = byCategory.get('dnssec');\n\tconst bimiCheck = byCategory.get('bimi');\n\n\t// Non-mail domains should not receive email maturity stages.\n\t// The numeric stage values here (0 = \"Unprotected\", 1 = \"DNS-Only\") intentionally\n\t// reuse the same numbers as the mail-domain scale. This is safe because `stage` is\n\t// only ever rendered as a display value alongside `label` — it is never used as a\n\t// numeric index or compared against mail-domain stages in any downstream logic.\n\tconst hasNoMx = mxCheck != null && mxCheck.findings.some((f: Finding) => f.title === 'No MX records found');\n\tif (hasNoMx) {\n\t\tconst hasDnssec = dnssecCheck?.passed ?? false;\n\t\treturn {\n\t\t\tstage: hasDnssec ? 1 : 0,\n\t\t\tlabel: hasDnssec ? 'DNS-Only' : 'Unprotected',\n\t\t\tdescription: hasDnssec\n\t\t\t\t? 'This domain does not accept email. DNS security (DNSSEC) is in place.'\n\t\t\t\t: 'This domain does not accept email and has no DNSSEC.',\n\t\t\tnextStep: hasDnssec ? '' : 'Enable DNSSEC to protect DNS resolution integrity.',\n\t\t};\n\t}\n\n\t// Determine SPF presence\n\tconst hasSpf = spfCheck != null && !spfCheck.findings.some((f: Finding) => /No SPF record/i.test(f.title));\n\n\t// Determine DMARC presence and policy\n\tconst hasDmarc = dmarcCheck != null && !dmarcCheck.findings.some((f: Finding) => /No DMARC record/i.test(f.title));\n\tconst dmarcPolicyNone = dmarcCheck?.findings.some((f: Finding) => /policy set to none/i.test(f.title)) ?? false;\n\tconst dmarcPolicyQuarantine = dmarcCheck?.findings.some((f: Finding) => /policy set to quarantine/i.test(f.title)) ?? false;\n\t// reject = no \"policy set to none\" and no \"policy set to quarantine\" and DMARC exists\n\tconst dmarcPolicyReject = hasDmarc && !dmarcPolicyNone && !dmarcPolicyQuarantine;\n\tconst hasRua = dmarcCheck != null && !dmarcCheck.findings.some((f: Finding) => /No aggregate reporting/i.test(f.title));\n\n\t// Determine MTA-STS, DNSSEC, BIMI\n\tconst hasMtaSts = mtaStsCheck?.passed ?? false;\n\tconst hasDnssec = dnssecCheck?.passed ?? false;\n\tconst hasBimi = bimiCheck?.findings.some((f: Finding) => /BIMI record configured/i.test(f.title)) ?? false;\n\n\t// DANE presence\n\tconst daneCheck = byCategory.get('dane');\n\tconst hasDane = daneCheck?.findings.some((f: Finding) => /DANE TLSA configured/i.test(f.title)) ?? false;\n\n\t// CAA presence (passed = CAA records found)\n\tconst caaCheck = byCategory.get('caa');\n\tconst hasCaa = caaCheck?.passed ?? false;\n\n\t// DKIM \"discovered\" = at least one selector physically found (not provider-implied)\n\t// Provider-implied findings have metadata.detectionMethod === 'provider-implied'\n\tconst hasDkimDiscovered =\n\t\tdkimCheck != null &&\n\t\t!dkimCheck.findings.some((f: Finding) => /No DKIM records found|DKIM selector not discovered/i.test(f.title)) &&\n\t\t!dkimCheck.findings.some((f: Finding) => f.metadata?.detectionMethod === 'provider-implied');\n\n\t// Stage 4 — Hardened: Stage 3 + at least 2 of (MTA-STS, DNSSEC, BIMI, DANE, CAA, DKIM-discovered)\n\t// DKIM is no longer required for Stage 3 — enforcement alone (SPF + DMARC p=quarantine/reject) qualifies\n\tconst isEnforcing = hasSpf && hasDmarc && (dmarcPolicyReject || dmarcPolicyQuarantine);\n\tconst hardeningCount = [hasMtaSts, hasDnssec, hasBimi, hasDane, hasCaa, hasDkimDiscovered].filter(Boolean).length;\n\n\tif (isEnforcing && hardeningCount >= 2) {\n\t\treturn {\n\t\t\tstage: 4,\n\t\t\tlabel: 'Hardened',\n\t\t\tdescription: 'Comprehensive email and DNS security posture with defense in depth.',\n\t\t\tnextStep: '',\n\t\t};\n\t}\n\n\t// Stage 3 — Enforcing: DMARC p=quarantine or p=reject, SPF exists, DKIM exists\n\tif (isEnforcing) {\n\t\treturn {\n\t\t\tstage: 3,\n\t\t\tlabel: 'Enforcing',\n\t\t\tdescription: 'Email authentication is actively enforcing — spoofed emails are blocked or quarantined.',\n\t\t\tnextStep: 'Add MTA-STS, DNSSEC, and BIMI to reach full hardening.',\n\t\t};\n\t}\n\n\t// Stage 2 — Monitoring: SPF + DMARC with p=none and rua= present\n\tif (hasSpf && hasDmarc && dmarcPolicyNone && hasRua) {\n\t\treturn {\n\t\t\tstage: 2,\n\t\t\tlabel: 'Monitoring',\n\t\t\tdescription: 'Email authentication is published and being monitored but not enforcing.',\n\t\t\tnextStep: 'After reviewing DMARC reports, move to p=quarantine and ensure DKIM is active.',\n\t\t};\n\t}\n\n\t// Stage 1 — Basic: SPF exists but DMARC is p=none or DMARC has no rua=\n\tif (hasSpf && hasDmarc) {\n\t\treturn {\n\t\t\tstage: 1,\n\t\t\tlabel: 'Basic',\n\t\t\tdescription: 'Basic email records exist but are not enforcing or monitoring.',\n\t\t\tnextStep: 'Add DMARC aggregate reporting (rua=) and monitor for 2-4 weeks before enforcing.',\n\t\t};\n\t}\n\n\t// Stage 0 — Unprotected\n\treturn {\n\t\tstage: 0,\n\t\tlabel: 'Unprotected',\n\t\tdescription: 'No email authentication — any server can send email as this domain.',\n\t\tnextStep: 'Publish SPF and DMARC records to begin protecting your domain.',\n\t};\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport type { ScanDomainResult } from '../scan-domain';\nimport type { Finding } from '../../lib/scoring';\nimport type { OutputFormat } from '../../handlers/tool-args';\nimport { sanitizeOutputText } from '../../lib/output-sanitize';\nimport { resolveImpactNarrative } from '../explain-finding';\n\n/** Structured scan result for machine-readable consumption (e.g., CI/CD actions). */\nexport interface StructuredScanResult {\n\tdomain: string;\n\tscore: number;\n\tgrade: string;\n\tpassed: boolean;\n\tmaturityStage: number | null;\n\tmaturityLabel: string | null;\n\tcategoryScores: Record<string, number>;\n\tfindingCounts: { critical: number; high: number; medium: number; low: number };\n\tscoringProfile: string;\n\tscoringSignals: string[];\n\tscoringNote: string | null;\n\tadaptiveWeightDeltas: Record<string, number> | null;\n\t/** Percentile rank within the scoring profile population (0–100). Null when insufficient benchmark data. */\n\tpercentileRank: number | null;\n\t/** Composite email spoofability score (0–100, higher = more spoofable). Null when not computed. */\n\tspoofabilityScore: number | null;\n\t/** Category interaction effects applied as post-scoring adjustments. */\n\tinteractionEffects: Array<{ ruleId: string; penalty: number; narrative: string }>;\n\t/** Execution status per check category. 'completed' = ran normally, 'timeout' = per-check timeout, 'error' = threw. */\n\tcheckStatuses: Record<string, 'completed' | 'timeout' | 'error'>;\n\t/** DNSSEC configuration source. 'domain_configured' = domain has own DNSKEY/DS; 'tld_inherited' = inherited from TLD registry. null = not yet available. */\n\tdnssecSource: 'domain_configured' | 'tld_inherited' | null;\n\t/** CDN provider detected from HTTP response headers. null when no CDN detected or check did not run. */\n\tcdnProvider: string | null;\n\t/** Email categories that scored 100 due to web-only/non-mail profile (no MX). Downstream consumers should treat these as N/A rather than perfect. */\n\tnotApplicableCategories: string[];\n\ttimestamp: string;\n\tcached: boolean;\n}\n\n/** Optional enrichment data for structured scan results. */\nexport interface ScanResultEnrichment {\n\tpercentileRank?: number | null;\n\tspoofabilityScore?: number | null;\n}\n\n/** Build a machine-readable structured result from a scan. */\nexport function buildStructuredScanResult(result: ScanDomainResult, enrichment?: ScanResultEnrichment): StructuredScanResult {\n\t// checkStatuses\n\tconst checkStatuses: Record<string, 'completed' | 'timeout' | 'error'> = {};\n\tfor (const check of result.checks) {\n\t\tcheckStatuses[check.category] = check.checkStatus ?? 'completed';\n\t}\n\n\t// dnssecSource\n\tconst dnssecCheck = result.checks.find((c) => c.category === 'dnssec');\n\tlet dnssecSource: 'domain_configured' | 'tld_inherited' | null = null;\n\tif (dnssecCheck) {\n\t\tfor (const f of dnssecCheck.findings) {\n\t\t\tconst src = f.metadata?.dnssecSource;\n\t\t\tif (src === 'domain_configured' || src === 'tld_inherited') {\n\t\t\t\tdnssecSource = src as 'domain_configured' | 'tld_inherited';\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (dnssecSource === null && dnssecCheck.passed && (checkStatuses['dnssec'] ?? 'completed') === 'completed') {\n\t\t\tdnssecSource = 'domain_configured';\n\t\t}\n\t}\n\n\t// cdnProvider\n\tconst httpCheck = result.checks.find((c) => c.category === 'http_security');\n\tlet cdnProvider: string | null = null;\n\tif (httpCheck) {\n\t\tfor (const f of httpCheck.findings) {\n\t\t\tconst cdn = f.metadata?.cdnProvider;\n\t\t\tif (typeof cdn === 'string') {\n\t\t\t\tcdnProvider = cdn;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// notApplicableCategories\n\tconst emailCategories = ['spf', 'dmarc', 'dkim', 'mta_sts'];\n\tconst isNonMailProfile = ['non_mail', 'web_only'].includes(result.context?.profile ?? '');\n\tconst notApplicableCategories: string[] = [];\n\tif (isNonMailProfile) {\n\t\tfor (const check of result.checks) {\n\t\t\tif (emailCategories.includes(check.category)) {\n\t\t\t\tconst allInfo = check.findings.length > 0 && check.findings.every((f: Finding) => f.severity === 'info');\n\t\t\t\tconst noFindings = check.findings.length === 0 && check.score === 100;\n\t\t\t\tif (allInfo || noFindings) {\n\t\t\t\t\tnotApplicableCategories.push(check.category);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdomain: result.domain,\n\t\tscore: result.score.overall,\n\t\tgrade: result.score.grade,\n\t\tpassed: result.score.overall >= 50,\n\t\tmaturityStage: result.maturity?.stage ?? null,\n\t\tmaturityLabel: result.maturity?.label ?? null,\n\t\tcategoryScores: result.score.categoryScores,\n\t\tfindingCounts: {\n\t\t\tcritical: result.score.findings.filter((f: Finding) => f.severity === 'critical').length,\n\t\t\thigh: result.score.findings.filter((f: Finding) => f.severity === 'high').length,\n\t\t\tmedium: result.score.findings.filter((f: Finding) => f.severity === 'medium').length,\n\t\t\tlow: result.score.findings.filter((f: Finding) => f.severity === 'low').length,\n\t\t},\n\t\tscoringProfile: result.context?.profile ?? 'mail_enabled',\n\t\tscoringSignals: (result.context?.signals ?? []).map((s: string) => s.replace(/[<>&\"']/g, '')),\n\t\tscoringNote: result.scoringNote ?? null,\n\t\tadaptiveWeightDeltas: result.adaptiveWeightDeltas ?? null,\n\t\tpercentileRank: enrichment?.percentileRank ?? null,\n\t\tspoofabilityScore: enrichment?.spoofabilityScore ?? null,\n\t\tinteractionEffects: (result.interactionEffects ?? []).map((e) => ({\n\t\t\truleId: e.ruleId,\n\t\t\tpenalty: e.penalty,\n\t\t\tnarrative: e.narrative,\n\t\t})),\n\t\tcheckStatuses,\n\t\tdnssecSource,\n\t\tcdnProvider,\n\t\tnotApplicableCategories,\n\t\ttimestamp: result.timestamp,\n\t\tcached: result.cached,\n\t};\n}\n\nexport function formatScanReport(result: ScanDomainResult, format: OutputFormat = 'full'): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`DNS Security Scan: ${result.domain}`);\n\tlines.push(`${'='.repeat(40)}`);\n\tlines.push(`Overall Score: ${result.score.overall}/100 (${result.score.grade})`);\n\tlines.push(`${result.score.summary}`);\n\tlines.push('');\n\n\tif (result.maturity) {\n\t\tif (format === 'compact') {\n\t\t\tlines.push(`Maturity: Stage ${result.maturity.stage} — ${result.maturity.label}`);\n\t\t} else {\n\t\t\tlines.push(`Email Security Maturity: Stage ${result.maturity.stage} — ${result.maturity.label}`);\n\t\t\tlines.push(result.maturity.description);\n\t\t\tif (result.maturity.nextStep) {\n\t\t\t\tlines.push(`Next step: ${result.maturity.nextStep}`);\n\t\t\t}\n\t\t}\n\t\tlines.push('');\n\t}\n\n\tif (format === 'full') {\n\t\tif (result.context) {\n\t\t\tconst signalSummary = result.context.signals.length > 0 ? result.context.signals.join(', ') : 'default';\n\t\t\tlines.push(`Scoring Profile: ${result.context.profile} (${signalSummary})`);\n\t\t\tlines.push('');\n\t\t}\n\n\t\tif (result.scoringNote) {\n\t\t\tlines.push(result.scoringNote);\n\t\t\tlines.push('');\n\t\t}\n\t}\n\n\tconst isNonMailProfile = ['non_mail', 'web_only'].includes(result.context?.profile ?? '');\n\tconst naEmailCategories = new Set(['spf', 'dmarc', 'dkim', 'mta_sts']);\n\n\tlines.push('Category Scores:');\n\tlines.push('-'.repeat(30));\n\tfor (const [category, score] of Object.entries(result.score.categoryScores) as [string, number][]) {\n\t\tif (isNonMailProfile && naEmailCategories.has(category)) {\n\t\t\tconst check = result.checks?.find((c) => c.category === category);\n\t\t\tconst allInfo = check && check.findings.length > 0 && check.findings.every((f: Finding) => f.severity === 'info');\n\t\t\tconst noFindings = !check || (check.findings.length === 0 && score === 100);\n\t\t\tif (allInfo || noFindings) {\n\t\t\t\tlines.push(` ∅ ${category.toUpperCase().padEnd(10)} N/A (web-only, no MX records)`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tconst status = score >= 80 ? '✓' : score >= 50 ? '⚠' : '✗';\n\t\tlines.push(` ${status} ${category.toUpperCase().padEnd(10)} ${score}/100`);\n\t}\n\tlines.push('');\n\n\tconst nonInfoFindings = result.score.findings.filter((finding: Finding) => finding.severity !== 'info');\n\tif (nonInfoFindings.length > 0) {\n\t\tlines.push('Findings:');\n\t\tlines.push('-'.repeat(30));\n\t\tfor (const finding of nonInfoFindings) {\n\t\t\tif (format === 'compact') {\n\t\t\t\tconst isHighPriority = finding.severity === 'critical' || finding.severity === 'high';\n\t\t\t\tconst detailLimit = isHighPriority ? 4000 : 300;\n\t\t\t\tlines.push(` [${finding.severity.toUpperCase()}] ${sanitizeOutputText(finding.title, 120)} — ${sanitizeOutputText(finding.detail, detailLimit)}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlines.push(` [${finding.severity.toUpperCase()}] ${sanitizeOutputText(finding.title, 120)}`);\n\t\t\tlines.push(` ${sanitizeOutputText(finding.detail)}`);\n\t\t\tconst verificationStatus =\n\t\t\t\tfinding.category === 'subdomain_takeover' && finding.metadata?.verificationStatus\n\t\t\t\t\t? String(finding.metadata.verificationStatus)\n\t\t\t\t\t: undefined;\n\t\t\tif (verificationStatus) {\n\t\t\t\tlines.push(` Takeover Verification: ${sanitizeOutputText(verificationStatus, 80)}`);\n\t\t\t}\n\t\t\tconst confidence = finding.metadata?.confidence ? String(finding.metadata.confidence) : undefined;\n\t\t\tif (confidence) {\n\t\t\t\tlines.push(` Confidence: ${sanitizeOutputText(confidence, 80)}`);\n\t\t\t}\n\t\t\tconst narrative = resolveImpactNarrative({\n\t\t\t\tcategory: finding.category,\n\t\t\t\tseverity: finding.severity,\n\t\t\t\ttitle: finding.title,\n\t\t\t\tdetail: finding.detail,\n\t\t\t});\n\t\t\tif (narrative.impact) {\n\t\t\t\tlines.push(` Potential Impact: ${narrative.impact}`);\n\t\t\t}\n\t\t\tif (narrative.adverseConsequences) {\n\t\t\t\tlines.push(` Adverse Consequences: ${narrative.adverseConsequences}`);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlines.push('No security issues found.');\n\t}\n\n\tif (format === 'full' && result.interactionEffects && result.interactionEffects.length > 0) {\n\t\tlines.push('');\n\t\tlines.push('Interaction Effects:');\n\t\tlines.push('-'.repeat(30));\n\t\tfor (const effect of result.interactionEffects) {\n\t\t\tlines.push(` [-${effect.penalty}] ${effect.narrative}`);\n\t\t}\n\t}\n\n\tif (result.cached) {\n\t\tlines.push('');\n\t\tlines.push('(Results served from cache)');\n\t}\n\n\tlines.push('');\n\tlines.push(`Scan completed: ${result.timestamp}`);\n\treturn lines.join('\\n');\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * scan-domain orchestrator tool.\n * Runs all DNS security checks in parallel via Promise.all\n * and computes an overall security score.\n *\n * Uses KV-backed cache with 5-minute TTL for scan results when available,\n * with in-memory fallback when KV is not configured.\n * Compatible with Cloudflare Workers runtime (no Node.js APIs).\n */\n\nimport {\n\ttype CheckCategory,\n\ttype CheckResult,\n\ttype DomainContext,\n\ttype DomainProfile,\n\ttype ScanScore,\n\tbuildCheckResult,\n\tcomputeScanScore,\n\tcreateFinding,\n\tdetectDomainContext,\n\tgetProfileWeights,\n} from '../lib/scoring';\nimport {\n\tadaptiveWeightsToContext,\n\tgenerateScoringNote,\n\ttype AdaptiveWeightsResponse,\n\ttype ScanTelemetry,\n} from '../lib/adaptive-weights';\nimport { applyInteractionPenalties, type InteractionEffect } from '../lib/category-interactions';\nimport { cacheGet, cacheSet, runWithCache } from '../lib/cache';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { checkSpf } from './check-spf';\nimport { checkDmarc } from './check-dmarc';\nimport { checkDkim, applyProviderDkimContext } from './check-dkim';\nimport { checkDnssec } from './check-dnssec';\nimport { checkSsl } from './check-ssl';\nimport { checkMtaSts } from './check-mta-sts';\nimport { checkNs } from './check-ns';\nimport { checkCaa } from './check-caa';\nimport { checkBimi } from './check-bimi';\nimport { checkTlsrpt } from './check-tlsrpt';\nimport { checkSubdomainTakeover } from './check-subdomain-takeover';\nimport { checkMx } from './check-mx';\nimport { checkHttpSecurity } from './check-http-security';\nimport { checkDane } from './check-dane';\nimport { checkDaneHttps } from './check-dane-https';\nimport { checkSvcbHttps } from './check-svcb-https';\nimport { checkSubdomailing } from './check-subdomailing';\nimport { applyScanPostProcessing } from './scan/post-processing';\nimport type { ScanRuntimeOptions } from './scan/post-processing';\nimport { capMaturityStage, computeMaturityStage } from './scan/maturity-staging';\nimport type { MaturityStage } from './scan/maturity-staging';\nexport { formatScanReport, buildStructuredScanResult } from './scan/format-report';\nexport type { StructuredScanResult, ScanResultEnrichment } from './scan/format-report';\nexport type { MaturityStage } from './scan/maturity-staging';\nexport type { ScanRuntimeOptions } from './scan/post-processing';\n\n/** Cache key prefix for scan and per-check results */\nconst CACHE_PREFIX = 'cache:';\n\n/** Maximum wall-clock time for a single check within scan_domain (ms). */\nconst PER_CHECK_TIMEOUT_MS = 8_000;\n\n/** Maximum wall-clock time for the entire scan_domain orchestration (ms). */\nconst SCAN_TIMEOUT_MS = 12_000;\n\n/** In-memory cache for adaptive weight responses from the ProfileAccumulator DO. */\nconst adaptiveWeightCache = new Map<string, { weights: AdaptiveWeightsResponse; expires: number }>();\n\n/** TTL for the in-memory adaptive weight cache (ms). */\nconst ADAPTIVE_CACHE_TTL_MS = 60_000;\n\n/** Maximum entries in the adaptive weight cache before eviction. */\nconst ADAPTIVE_CACHE_MAX_ENTRIES = 100;\n\n/** Timeout for fetching adaptive weights from the DO (ms). */\nconst ADAPTIVE_FETCH_TIMEOUT_MS = 200;\n\nexport interface ScanDomainResult {\n\tdomain: string;\n\tscore: ScanScore;\n\tchecks: CheckResult[];\n\tmaturity: MaturityStage;\n\tcontext: DomainContext;\n\tcached: boolean;\n\ttimestamp: string;\n\tscoringNote: string | null;\n\tadaptiveWeightDeltas: Record<string, number> | null;\n\t/** Category interaction effects applied as post-scoring adjustments. Empty when no interactions triggered. */\n\tinteractionEffects: InteractionEffect[];\n}\n\n/**\n * Run a full DNS security scan on a domain.\n * Executes all checks in parallel and computes an overall score.\n *\n * @param domain - The domain to scan (must already be validated and sanitized by the caller)\n * @param kv - Optional KV namespace for persistent scan result caching\n * @returns Full scan result with score, individual check results, and metadata\n */\nexport async function scanDomain(domain: string, kv?: KVNamespace, runtimeOptions?: ScanRuntimeOptions): Promise<ScanDomainResult> {\n\tconst explicitProfile = runtimeOptions?.profile;\n\tconst isExplicit = explicitProfile && explicitProfile !== 'auto';\n\tconst cacheKey = isExplicit\n\t\t? `${CACHE_PREFIX}${domain}:profile:${explicitProfile}`\n\t\t: `${CACHE_PREFIX}${domain}`;\n\n\t// Check cache first (skip when force_refresh is requested)\n\tif (!runtimeOptions?.forceRefresh) {\n\t\tconst cached = await cacheGet<ScanDomainResult>(cacheKey, kv);\n\t\tif (cached) {\n\t\t\treturn { ...cached, cached: true };\n\t\t}\n\t}\n\n\t// Run all checks in parallel with per-check timeouts, wrapped in an\n\t// overall scan timeout to guarantee a timely response.\n\t// Uses Promise.allSettled so that completed checks are preserved on timeout.\n\tconst ALL_CHECK_CATEGORIES: CheckCategory[] = [\n\t\t'spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta_sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'subdomain_takeover', 'http_security', 'dane', 'mx', 'dane_https', 'svcb_https', 'subdomailing',\n\t];\n\n\t// Skip secondary DNS confirmation in scan context for speed — individual checks\n\t// still use secondary confirmation when called directly by users.\n\tconst scanDns: QueryDnsOptions = {\n\t\tskipSecondaryConfirmation: true,\n\t\tqueryCache: new Map(),\n\t\tsecondaryDoh: runtimeOptions?.secondaryDoh,\n\t};\n\n\tconst forceRefresh = runtimeOptions?.forceRefresh;\n\tconst cacheTtl = runtimeOptions?.cacheTtlSeconds;\n\n\tconst checkPromises = [\n\t\trunCachedCheck(domain, 'spf', () => safeCheck('spf', () => checkSpf(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dmarc', () => safeCheck('dmarc', () => checkDmarc(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dkim', () => safeCheck('dkim', () => checkDkim(domain, undefined, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dnssec', () => safeCheck('dnssec', () => checkDnssec(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'ssl', () => safeCheck('ssl', () => checkSsl(domain)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'mta_sts', () => safeCheck('mta_sts', () => checkMtaSts(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'ns', () => safeCheck('ns', () => checkNs(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'caa', () => safeCheck('caa', () => checkCaa(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'bimi', () => safeCheck('bimi', () => checkBimi(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'tlsrpt', () => safeCheck('tlsrpt', () => checkTlsrpt(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'subdomain_takeover', () => safeCheck('subdomain_takeover', () => checkSubdomainTakeover(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'http_security', () => safeCheck('http_security', () => checkHttpSecurity(domain)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dane', () => safeCheck('dane', () => checkDane(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dane_https', () => safeCheck('dane_https', () => checkDaneHttps(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'svcb_https', () => safeCheck('svcb_https', () => checkSvcbHttps(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'subdomailing', () => safeCheck('subdomailing', () => checkSubdomailing(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(\n\t\t\tdomain,\n\t\t\t'mx',\n\t\t\t() =>\n\t\t\t\tsafeCheck(\n\t\t\t\t\t'mx',\n\t\t\t\t\t() =>\n\t\t\t\t\t\tcheckMx(domain, {\n\t\t\t\t\t\t\tproviderSignaturesUrl: runtimeOptions?.providerSignaturesUrl,\n\t\t\t\t\t\t\tproviderSignaturesAllowedHosts: runtimeOptions?.providerSignaturesAllowedHosts,\n\t\t\t\t\t\t\tproviderSignaturesSha256: runtimeOptions?.providerSignaturesSha256,\n\t\t\t\t\t\t}, scanDns),\n\t\t\t\t),\n\t\t\tkv,\n\t\t\tcacheTtl,\n\t\t\tforceRefresh,\n\t\t),\n\t];\n\n\tlet timedOut = false;\n\tconst settled = await Promise.race([\n\t\tPromise.allSettled(checkPromises),\n\t\tnew Promise<PromiseSettledResult<CheckResult>[]>((resolve) =>\n\t\t\tsetTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\t// Snapshot whatever has settled so far by racing each promise with an immediate rejection\n\t\t\t\tresolve(\n\t\t\t\t\tPromise.allSettled(\n\t\t\t\t\t\tcheckPromises.map((p) => Promise.race([p, new Promise<never>((_, reject) => reject(new Error('__check_pending__')))])),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}, SCAN_TIMEOUT_MS),\n\t\t),\n\t]);\n\n\tlet checkResults = settled\n\t\t.filter((r): r is PromiseFulfilledResult<CheckResult> => r.status === 'fulfilled')\n\t\t.map((r) => r.value);\n\n\t// Track categories with degraded status before post-processing strips checkStatus.\n\t// Post-processing calls buildCheckResult() which creates new objects without checkStatus,\n\t// so we must record these statuses separately and re-apply them after post-processing.\n\tconst degradedStatuses = new Map<CheckCategory, 'error' | 'timeout'>();\n\tfor (const r of checkResults) {\n\t\tif (r.checkStatus === 'error' || r.checkStatus === 'timeout') {\n\t\t\tdegradedStatuses.set(r.category, r.checkStatus);\n\t\t}\n\t}\n\n\t// For any checks that didn't complete, add a timeout finding\n\tif (timedOut) {\n\t\tconst completedCategories = new Set(checkResults.map((r) => r.category));\n\t\tfor (const category of ALL_CHECK_CATEGORIES) {\n\t\t\tif (!completedCategories.has(category)) {\n\t\t\t\tconst findings = [\n\t\t\t\t\tcreateFinding(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\t`${category.toUpperCase()} check timed out`,\n\t\t\t\t\t\t'low',\n\t\t\t\t\t\t`Check did not complete within the ${SCAN_TIMEOUT_MS / 1000}s scan time limit. Try running this check individually.`,\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t\tconst result = buildCheckResult(category, findings);\n\t\t\t\tcheckResults.push({ ...result, score: 0, checkStatus: 'timeout' as const });\n\t\t\t\tdegradedStatuses.set(category, 'timeout');\n\t\t\t}\n\t\t}\n\t}\n\n\tlet result: ScanDomainResult;\n\ttry {\n\t\tcheckResults = await applyScanPostProcessing(domain, checkResults, runtimeOptions);\n\n\t\t// Re-apply score=0 and checkStatus for checks that errored or timed out.\n\t\t// Post-processing calls buildCheckResult() which creates new objects that lose checkStatus,\n\t\t// so we re-enforce the zero score and status using the degradedStatuses map recorded above.\n\t\tif (degradedStatuses.size > 0) {\n\t\t\tcheckResults = checkResults.map((r) => {\n\t\t\t\tconst status = degradedStatuses.get(r.category);\n\t\t\t\treturn status ? { ...r, score: 0, checkStatus: status } : r;\n\t\t\t});\n\t\t}\n\n\t\t// Detect domain context from check results\n\t\tlet domainContext = detectDomainContext(checkResults);\n\n\t\t// If an explicit profile was requested, override detection\n\t\tif (isExplicit) {\n\t\t\tdomainContext = {\n\t\t\t\tprofile: explicitProfile as DomainProfile,\n\t\t\t\tsignals: [...domainContext.signals, `explicit profile override: ${explicitProfile}`],\n\t\t\t\tweights: getProfileWeights(explicitProfile as DomainProfile, runtimeOptions?.scoringConfig),\n\t\t\t\tdetectedProvider: domainContext.detectedProvider,\n\t\t\t};\n\t\t}\n\n\t\t// Apply provider-informed DKIM adjustment: when a known DKIM-signing\n\t\t// provider is detected via MX, downgrade the \"not found\" finding since\n\t\t// the provider likely signs by default with a custom selector.\n\t\tif (domainContext.detectedProvider) {\n\t\t\tconst dkimIdx = checkResults.findIndex((r) => r.category === 'dkim');\n\t\t\tif (dkimIdx !== -1) {\n\t\t\t\tcheckResults[dkimIdx] = applyProviderDkimContext(checkResults[dkimIdx], domainContext.detectedProvider);\n\t\t\t}\n\t\t}\n\n\t\t// Phase 1: only pass context to scoring when an explicit profile is set.\n\t\t// For 'auto' (or unset), detection runs and is reported but scoring\n\t\t// uses the default weights (identical to pre-profile behavior).\n\t\tconst scoringContext = isExplicit ? domainContext : undefined;\n\n\t\t// Attempt to fetch adaptive weights from the ProfileAccumulator DO\n\t\tlet adaptiveResponse: AdaptiveWeightsResponse | null = null;\n\t\tif (runtimeOptions?.profileAccumulator) {\n\t\t\tadaptiveResponse = await fetchAdaptiveWeights(\n\t\t\t\truntimeOptions.profileAccumulator,\n\t\t\t\tdomainContext.profile,\n\t\t\t\tdomainContext.detectedProvider,\n\t\t\t);\n\t\t}\n\n\t\t// Add bound hits to signals if present\n\t\tif (adaptiveResponse?.boundHits.length) {\n\t\t\tdomainContext.signals.push(`adaptive bound hits: ${adaptiveResponse.boundHits.join(', ')}`);\n\t\t}\n\n\t\tlet score: ScanScore;\n\t\tlet scoringNote: string | null = null;\n\t\tlet adaptiveWeightDeltas: Record<string, number> | null = null;\n\n\t\tif (adaptiveResponse && adaptiveResponse.sampleCount > 0) {\n\t\t\tconst adaptiveWeights = adaptiveWeightsToContext(adaptiveResponse.weights, domainContext.profile);\n\t\t\tif (adaptiveWeights) {\n\t\t\t\t// Compute adaptive score\n\t\t\t\tconst adaptiveContext: DomainContext = { ...domainContext, weights: adaptiveWeights };\n\t\t\t\tconst adaptiveScore = computeScanScore(checkResults, adaptiveContext, runtimeOptions?.scoringConfig);\n\n\t\t\t\t// Compute static score for comparison\n\t\t\t\tconst staticContext: DomainContext = {\n\t\t\t\t\t...domainContext,\n\t\t\t\t\tweights: getProfileWeights(domainContext.profile, runtimeOptions?.scoringConfig),\n\t\t\t\t};\n\t\t\t\tconst staticScore = computeScanScore(checkResults, scoringContext ?? staticContext, runtimeOptions?.scoringConfig);\n\n\t\t\t\t// Compute per-category weight deltas\n\t\t\t\tconst staticWeights = getProfileWeights(domainContext.profile, runtimeOptions?.scoringConfig);\n\t\t\t\tconst deltas: Record<string, number> = {};\n\t\t\t\tfor (const cat of Object.keys(staticWeights) as CheckCategory[]) {\n\t\t\t\t\tdeltas[cat] = adaptiveWeights[cat].importance - staticWeights[cat].importance;\n\t\t\t\t}\n\n\t\t\t\tconst scoreDelta = adaptiveScore.overall - staticScore.overall;\n\t\t\t\tscoringNote = generateScoringNote(deltas, scoreDelta, domainContext.detectedProvider);\n\t\t\t\tadaptiveWeightDeltas = deltas;\n\t\t\t\t// Use the SAME scoring call as the non-adaptive path for determinism.\n\t\t\t\t// Both paths must produce identical results regardless of whether the\n\t\t\t\t// ProfileAccumulatorDO responds. The adaptive delta is reported in\n\t\t\t\t// scoringNote for analytics consumers.\n\t\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t\t} else {\n\t\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t\t}\n\t\t} else {\n\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t}\n\n\t\t// Apply category interaction penalties (post-scoring adjustment)\n\t\tconst { adjustedScore, effects: interactionEffects } = applyInteractionPenalties(score, runtimeOptions?.scoringConfig);\n\t\tscore = adjustedScore;\n\n\t\tconst rawMaturity = computeMaturityStage(checkResults);\n\t\tconst maturity = capMaturityStage(rawMaturity, score.overall);\n\n\t\tresult = {\n\t\t\tdomain,\n\t\t\tscore,\n\t\t\tchecks: checkResults,\n\t\t\tmaturity,\n\t\t\tcontext: domainContext,\n\t\t\tcached: false,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tscoringNote,\n\t\t\tadaptiveWeightDeltas,\n\t\t\tinteractionEffects,\n\t\t};\n\n\t\t// POST telemetry to DO (best-effort, non-blocking)\n\t\tif (runtimeOptions?.profileAccumulator) {\n\t\t\tconst telemetry: ScanTelemetry = {\n\t\t\t\tprofile: domainContext.profile,\n\t\t\t\tprovider: domainContext.detectedProvider,\n\t\t\t\tcategoryFindings: checkResults.map((r) => ({ category: r.category, score: r.score, passed: r.passed })),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\toverallScore: score.overall,\n\t\t\t};\n\t\t\tconst telemetryPromise = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst stub = runtimeOptions.profileAccumulator!.get(\n\t\t\t\t\t\truntimeOptions.profileAccumulator!.idFromName('global'),\n\t\t\t\t\t);\n\t\t\t\t\tawait stub.fetch(\n\t\t\t\t\t\tnew Request('https://do/ingest', {\n\t\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\t\t\t\tbody: JSON.stringify(telemetry),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t})();\n\t\t\tif (runtimeOptions.waitUntil) runtimeOptions.waitUntil(telemetryPromise);\n\t\t}\n\t} catch {\n\t\t// Post-processing or scoring failed — return whatever we have.\n\t\t// Re-apply degraded status overrides in case post-processing ran partially.\n\t\tif (degradedStatuses.size > 0) {\n\t\t\tcheckResults = checkResults.map((r) => {\n\t\t\t\tconst status = degradedStatuses.get(r.category);\n\t\t\t\treturn status ? { ...r, score: 0, checkStatus: status } : r;\n\t\t\t});\n\t\t}\n\t\tlet fallbackContext = detectDomainContext(checkResults);\n\t\tif (isExplicit) {\n\t\t\tfallbackContext = {\n\t\t\t\tprofile: explicitProfile as DomainProfile,\n\t\t\t\tsignals: [...fallbackContext.signals, `explicit profile override: ${explicitProfile}`],\n\t\t\t\tweights: getProfileWeights(explicitProfile as DomainProfile, runtimeOptions?.scoringConfig),\n\t\t\t\tdetectedProvider: fallbackContext.detectedProvider,\n\t\t\t};\n\t\t}\n\t\tconst fallbackScoringContext = isExplicit ? fallbackContext : undefined;\n\t\tconst score = computeScanScore(checkResults, fallbackScoringContext, runtimeOptions?.scoringConfig);\n\t\tconst rawMaturity = computeMaturityStage(checkResults);\n\t\tconst maturity = capMaturityStage(rawMaturity, score.overall);\n\t\tresult = {\n\t\t\tdomain,\n\t\t\tscore,\n\t\t\tchecks: checkResults,\n\t\t\tmaturity,\n\t\t\tcontext: fallbackContext,\n\t\t\tcached: false,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tscoringNote: null,\n\t\t\tadaptiveWeightDeltas: null,\n\t\t\tinteractionEffects: [],\n\t\t};\n\t}\n\n\t// Cache the result (use configurable TTL if provided)\n\t// Defer the write via waitUntil when available to avoid blocking the response.\n\tconst cachePromise = cacheSet(cacheKey, result, kv, runtimeOptions?.cacheTtlSeconds);\n\tif (runtimeOptions?.waitUntil) {\n\t\truntimeOptions.waitUntil(cachePromise);\n\t} else {\n\t\tawait cachePromise;\n\t}\n\n\treturn result;\n}\n\n/**\n * Fetch adaptive weights from the ProfileAccumulator DO with in-memory caching.\n * Returns null on failure or timeout (silently falls back to static weights).\n */\nasync function fetchAdaptiveWeights(\n\taccumulator: DurableObjectNamespace,\n\tprofile: string,\n\tprovider: string | null,\n): Promise<AdaptiveWeightsResponse | null> {\n\tconst cacheKey = `${profile}:${provider ?? ''}`;\n\tconst now = Date.now();\n\n\t// Check in-memory cache first\n\tconst cached = adaptiveWeightCache.get(cacheKey);\n\tif (cached && cached.expires > now) {\n\t\treturn cached.weights;\n\t}\n\n\ttry {\n\t\tconst stub = accumulator.get(accumulator.idFromName('global'));\n\t\tconst url = new URL('https://do/weights');\n\t\turl.searchParams.set('profile', profile);\n\t\tif (provider) url.searchParams.set('provider', provider);\n\n\t\tconst response = await Promise.race([\n\t\t\tstub.fetch(new Request(url.toString())),\n\t\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('adaptive weight fetch timeout')), ADAPTIVE_FETCH_TIMEOUT_MS)),\n\t\t]);\n\n\t\tif (!response.ok) return null;\n\n\t\tconst data = (await response.json()) as AdaptiveWeightsResponse;\n\t\tif (adaptiveWeightCache.size >= ADAPTIVE_CACHE_MAX_ENTRIES) {\n\t\t\tevictAdaptiveWeightCache();\n\t\t}\n\t\tadaptiveWeightCache.set(cacheKey, { weights: data, expires: now + ADAPTIVE_CACHE_TTL_MS });\n\t\treturn data;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Evict entries from the adaptive weight cache.\n * Removes expired entries first, then if still at capacity, evicts the entry with the oldest expiry time.\n */\nexport function evictAdaptiveWeightCache(): void {\n\tconst now = Date.now();\n\n\t// First pass: remove all expired entries\n\tfor (const [key, entry] of adaptiveWeightCache) {\n\t\tif (entry.expires <= now) {\n\t\t\tadaptiveWeightCache.delete(key);\n\t\t}\n\t}\n\n\t// If still at capacity after removing expired entries, evict the oldest by expiry\n\tif (adaptiveWeightCache.size >= ADAPTIVE_CACHE_MAX_ENTRIES) {\n\t\tlet oldestKey: string | null = null;\n\t\tlet oldestExpiry = Infinity;\n\t\tfor (const [key, entry] of adaptiveWeightCache) {\n\t\t\tif (entry.expires < oldestExpiry) {\n\t\t\t\toldestExpiry = entry.expires;\n\t\t\t\toldestKey = key;\n\t\t\t}\n\t\t}\n\t\tif (oldestKey !== null) {\n\t\t\tadaptiveWeightCache.delete(oldestKey);\n\t\t}\n\t}\n}\n\n/** Exposed for testing only — do not use in production code. */\nexport const _adaptiveWeightCacheForTest = adaptiveWeightCache;\n\nasync function runCachedCheck(\n\tdomain: string,\n\tcategory: CheckCategory,\n\trun: () => Promise<CheckResult>,\n\tkv?: KVNamespace,\n\tttlSeconds?: number,\n\tskipCache?: boolean,\n): Promise<CheckResult> {\n\treturn runWithCache(`${CACHE_PREFIX}${domain}:check:${category}`, run, kv, ttlSeconds, skipCache);\n}\n\n/**\n * Run a single check with error handling and a per-check timeout.\n * If a check fails or exceeds the timeout, returns a failed CheckResult\n * with an error/timeout finding instead of throwing, so other checks\n * can still complete.\n */\nasync function safeCheck(category: CheckCategory, fn: () => Promise<CheckResult>): Promise<CheckResult> {\n\ttry {\n\t\tconst result = await Promise.race([\n\t\t\tfn(),\n\t\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('Check timed out')), PER_CHECK_TIMEOUT_MS)),\n\t\t]);\n\t\treturn result;\n\t} catch (err) {\n\t\tconst rawMessage = err instanceof Error ? err.message : 'Check failed';\n\t\tconst SAFE_PREFIXES = ['DNS query', 'Check timed out', 'Check failed', 'Connection', 'timeout'];\n\t\tconst safeMessage = SAFE_PREFIXES.some((p) => rawMessage.startsWith(p)) ? rawMessage : 'Check failed';\n\t\tconst findings = [createFinding(category, `${category.toUpperCase()} check error`, 'high', `Check failed: ${safeMessage}`)];\n\t\tconst result = buildCheckResult(category, findings);\n\t\treturn { ...result, score: 0, checkStatus: 'error' as const };\n\t}\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/dns-types.ts","../src/lib/config.ts","../src/schemas/dns.ts","../src/lib/dns-transport.ts","../src/lib/dns-records.ts","../src/lib/adaptive-weights.ts","../src/lib/sanitize.ts","../src/lib/server-version.ts","../src/schemas/primitives.ts","../src/schemas/tool-args.ts","../src/schemas/tool-definitions.ts","../src/tools/check-bimi.ts","../src/tools/check-caa.ts","../src/tools/check-dkim.ts","../src/tools/check-dmarc.ts","../src/tools/check-dnssec.ts","../src/tools/lookalike-analysis.ts","../src/tools/check-lookalikes.ts","../src/tools/check-mta-sts.ts","../src/lib/provider-signature-source.ts","../src/lib/provider-signatures.ts","../src/tools/check-mx.ts","../src/tools/check-ns.ts","../src/tools/check-spf.ts","../src/tools/check-ssl.ts","../src/tools/check-subdomain-takeover.ts","../src/tools/check-tlsrpt.ts","../src/lib/output-sanitize.ts","../src/tools/explain-finding-data.ts","../src/tools/explain-finding.ts","../src/lib/category-interactions.ts","../src/lib/log.ts","../src/lib/cache.ts","../src/tools/check-http-security.ts","../src/tools/check-dane.ts","../src/tools/check-dane-https.ts","../src/tools/check-svcb-https.ts","../src/tools/check-subdomailing.ts","../src/tools/scan/post-processing.ts","../src/tools/scan/maturity-staging.ts","../src/tools/scan/format-report.ts","../src/tools/scan-domain.ts"],"names":["topCat","topDelta","z","makeQueryDNS","createFinding","buildCheckResult","checkDnssec","normalizeDomain","checkSubdomainTakeoverPkg","lines","scoreToGrade","checkSubdomailingCore","evidence","getParentDomain","hasDnssec","result","detectDomainContext","getProfileWeights"],"mappings":"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","file":"index.js","sourcesContent":["// SPDX-License-Identifier: BUSL-1.1\n\n/** Standard DNS record type codes */\nexport const RecordType = {\n\tA: 1,\n\tAAAA: 28,\n\tCNAME: 5,\n\tMX: 15,\n\tTXT: 16,\n\tNS: 2,\n\tSOA: 6,\n\tCAA: 257,\n\tTLSA: 52,\n\tDNSKEY: 48,\n\tDS: 43,\n\tRRSIG: 46,\n\tPTR: 12,\n\tSRV: 33,\n\tHTTPS: 65,\n} as const;\n\nexport type RecordTypeName = keyof typeof RecordType;\n\n/** A single DNS answer record from the DoH JSON response */\nexport interface DnsAnswer {\n\tname: string;\n\ttype: number;\n\tTTL: number;\n\tdata: string;\n}\n\n/** A single DNS authority record */\nexport interface DnsAuthority {\n\tname: string;\n\ttype: number;\n\tTTL: number;\n\tdata: string;\n}\n\n/** Cloudflare DoH JSON wire-format response */\nexport interface DohResponse {\n\tStatus: number;\n\tTC: boolean;\n\tRD: boolean;\n\tRA: boolean;\n\tAD: boolean;\n\tCD: boolean;\n\tQuestion: Array<{ name: string; type: number }>;\n\tAnswer?: DnsAnswer[];\n\tAuthority?: DnsAuthority[];\n}\n\n/** Configuration for a custom secondary DoH resolver (e.g., bv-dns on Oracle Cloud). */\nexport interface SecondaryDohConfig {\n\t/** DoH endpoint URL (e.g. https://doh.example.com/dns-query) */\n\tendpoint: string;\n\t/** Optional auth token sent as X-BV-Token header */\n\ttoken?: string;\n}\n\nexport interface QueryDnsOptions {\n\ttimeoutMs?: number;\n\tretries?: number;\n\tconfirmWithSecondaryOnEmpty?: boolean;\n\t/** When true, skip secondary resolver confirmation on empty results. Used in scan context for speed. */\n\tskipSecondaryConfirmation?: boolean;\n\t/** Scan-scoped DNS query cache. Stores Promises keyed by `domain:type:dnssecCheck` to deduplicate concurrent and sequential identical queries within a single scan. */\n\tqueryCache?: Map<string, Promise<DohResponse>>;\n\t/** Custom secondary DoH resolver. When set, used instead of Google DoH for empty-result confirmation. Falls back to Google if this resolver fails. */\n\tsecondaryDoh?: SecondaryDohConfig;\n}","// SPDX-License-Identifier: BUSL-1.1\n\nimport type { Tier } from '../schemas/primitives';\n\n/**\n * Centralized configuration for domain normalization and validation.\n */\nexport const BLOCKED_SUFFIXES = [\n\t'.local',\n\t'.localhost',\n\t'.internal',\n\t'.example',\n\t'.invalid',\n\t'.test',\n\t'.onion',\n\t'.lan',\n\t'.home',\n\t'.corp',\n\t'.intranet',\n];\nexport const BLOCKED_HOSTS = ['localhost', 'localhost.localdomain'];\nexport const BLOCKED_IP_PATTERNS = [\n\t/^127\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^10\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^169\\.254\\.[0-9]{1,3}\\.[0-9]{1,3}$/,\n\t/^0\\.0\\.0\\.0$/,\n\t/^::1$/,\n\t/^fc00:/i,\n\t/^fd[0-9a-f]{2}:/i,\n\t/^fe[89ab][0-9a-f]:/i,\n];\nexport const BLOCKED_DNS_REBINDING = ['.nip.io', '.sslip.io', '.xip.io', '.nip.direct'];\nexport const MAX_DOMAIN_LENGTH = 253;\nexport const MAX_LABEL_LENGTH = 63;\nexport const LABEL_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i;\n\n/** Hard limit on incoming JSON-RPC request body size (bytes). */\nexport const MAX_REQUEST_BODY_BYTES = 10_240;\n\n/** Timeout for outbound HTTPS fetches (SSL, MTA-STS policy, etc.). */\nexport const HTTPS_TIMEOUT_MS = 4_000;\n\n/** Default timeout for DNS-over-HTTPS queries. CF DoH p99 is <500ms. */\nexport const DNS_TIMEOUT_MS = 3_000;\n\n/** Default number of retry attempts for DNS-over-HTTPS queries. */\nexport const DNS_RETRIES = 1;\n\n/** Edge cache TTL (seconds) for outbound DoH fetch requests via Cloudflare's cf API. */\nexport const DOH_EDGE_CACHE_TTL = 300;\n\n/** Timeout (ms) after which a stuck INFLIGHT promise is evicted from the dedup map. */\nexport const INFLIGHT_CLEANUP_MS = 30_000;\n\n/** Base delay (ms) between DNS retry attempts. Actual delay = base * (attempt+1) + jitter. */\nexport const DNS_RETRY_BASE_DELAY_MS = 75;\n\n/**\n * When true, empty DoH answers from the primary resolver are optionally\n * confirmed with a secondary resolver to reduce false negatives.\n */\nexport const DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY = true;\n\n/** Default cache TTL in seconds. Override via CACHE_TTL_SECONDS env var. */\nexport const DEFAULT_CACHE_TTL_SECONDS = 300;\n\n/**\n * Parse CACHE_TTL_SECONDS env var, clamping to [60, 3600].\n * Returns DEFAULT_CACHE_TTL_SECONDS when absent or invalid.\n */\nexport function parseCacheTtl(envValue?: string): number {\n\tif (!envValue) return DEFAULT_CACHE_TTL_SECONDS;\n\tconst parsed = Number(envValue);\n\tif (!Number.isFinite(parsed) || parsed < 60) return DEFAULT_CACHE_TTL_SECONDS;\n\treturn Math.min(parsed, 3600);\n}\n\n/**\n * Global daily free-tier request ceiling across all unauthenticated IPs.\n * Protects from abuse by capping free usage at a service-wide level.\n * Authenticated requests are exempt.\n */\nexport const GLOBAL_DAILY_TOOL_LIMIT = 500_000;\n\n/**\n * Free-tier daily tool quotas for unauthenticated callers.\n * Tools omitted from this map are governed only by baseline per-IP rate limits.\n */\n/** MCP API key tiers with daily scan quotas. Derived from the Zod TierSchema in schemas/primitives. */\nexport type McpApiKeyTier = Tier;\n\n/** Daily scan limits per API key tier (applies per tool unless overridden by TIER_TOOL_DAILY_LIMITS). */\nexport const TIER_DAILY_LIMITS: Record<McpApiKeyTier, number> = {\n\tfree: 50,\n\tagent: 200,\n\tdeveloper: 500,\n\tenterprise: 10_000,\n\tpartner: 100_000,\n\towner: Infinity,\n};\n\n/**\n * Per-tool daily limit overrides for specific tiers.\n * When a tier+tool combo exists here, it takes precedence over the flat TIER_DAILY_LIMITS value.\n */\nexport const TIER_TOOL_DAILY_LIMITS: Partial<Record<McpApiKeyTier, Record<string, number>>> = {\n\tpartner: {\n\t\tscan_domain: 100_000,\n\t\tscan: 100_000,\n\t\tcompare_baseline: 100_000,\n\t\tcheck_spf: 500_000,\n\t\tcheck_dmarc: 500_000,\n\t\tcheck_dkim: 500_000,\n\t\tcheck_mx: 500_000,\n\t\tcheck_ns: 500_000,\n\t\tcheck_ssl: 500_000,\n\t\tcheck_dnssec: 500_000,\n\t\tcheck_mta_sts: 500_000,\n\t\tcheck_caa: 500_000,\n\t\tcheck_bimi: 500_000,\n\t\tcheck_tlsrpt: 500_000,\n\t\tcheck_lookalikes: 50_000,\n\t\tcheck_shadow_domains: 50_000,\n\t\tcheck_txt_hygiene: 500_000,\n\t\tcheck_http_security: 500_000,\n\t\tcheck_dane: 500_000,\n\t\tcheck_mx_reputation: 50_000,\n\t\tcheck_srv: 500_000,\n\t\tcheck_zone_hygiene: 500_000,\n\t\tcheck_subdomailing: 500_000,\n\t\texplain_finding: 500_000,\n\t},\n};\n\nexport const FREE_TOOL_DAILY_LIMITS: Record<string, number> = {\n\tscan_domain: 75,\n\tscan: 75,\n\tbatch_scan: 20,\n\tcompare_domains: 15,\n\tcheck_spf: 200,\n\tcheck_dmarc: 200,\n\tcheck_dkim: 200,\n\tcheck_mx: 200,\n\tcheck_ns: 200,\n\tcheck_ssl: 200,\n\tcheck_dnssec: 200,\n\tcheck_mta_sts: 200,\n\tcheck_caa: 200,\n\tcheck_bimi: 200,\n\tcheck_tlsrpt: 200,\n\tcheck_lookalikes: 20,\n\texplain_finding: 200,\n\tcompare_baseline: 150,\n\tcheck_shadow_domains: 20,\n\tcheck_txt_hygiene: 200,\n\tcheck_http_security: 200,\n\tcheck_dane: 200,\n\tcheck_mx_reputation: 20,\n\tcheck_srv: 200,\n\tcheck_zone_hygiene: 200,\n\tcheck_subdomailing: 200,\n\tgenerate_fix_plan: 75,\n\tgenerate_spf_record: 200,\n\tgenerate_dmarc_record: 200,\n\tgenerate_dkim_config: 200,\n\tgenerate_mta_sts_policy: 200,\n\tget_benchmark: 100,\n\tget_provider_insights: 50,\n\tassess_spoofability: 150,\n\tcheck_resolver_consistency: 50,\n\tmap_supply_chain: 75,\n\tanalyze_drift: 75,\n\tvalidate_fix: 200,\n\tgenerate_rollout_plan: 150,\n\tresolve_spf_chain: 100,\n\tdiscover_subdomains: 50,\n\tmap_compliance: 75,\n\tsimulate_attack_paths: 75,\n};\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\n\n/** DNS answer record from DoH response. */\nexport const DnsAnswerSchema = z.object({\n\tname: z.string(),\n\ttype: z.number(),\n\tTTL: z.number().optional(),\n\tdata: z.string(),\n});\n\n/** DNS authority record from DoH response. */\nexport const DnsAuthoritySchema = z.object({\n\tname: z.string(),\n\ttype: z.number(),\n\tTTL: z.number().optional(),\n\tdata: z.string(),\n});\n\n/** Complete DoH JSON response. Validates shape before casting. */\nexport const DohResponseSchema = z\n\t.object({\n\t\tStatus: z.number().finite(),\n\t\tTC: z.boolean().optional(),\n\t\tRD: z.boolean().optional(),\n\t\tRA: z.boolean().optional(),\n\t\tAD: z.boolean().optional(),\n\t\tCD: z.boolean().optional(),\n\t\tQuestion: z.array(z.object({ name: z.string(), type: z.unknown() })).optional(),\n\t\tAnswer: z.array(DnsAnswerSchema).optional(),\n\t\tAuthority: z.array(DnsAuthoritySchema).optional(),\n\t})\n\t.passthrough();\n\n/** Parsed CAA record. */\nexport const CaaRecordSchema = z.object({\n\tflags: z.number(),\n\ttag: z.string(),\n\tvalue: z.string(),\n});\n\n/** Parsed TLSA record. */\nexport const TlsaRecordSchema = z.object({\n\tusage: z.number(),\n\tselector: z.number(),\n\tmatchingType: z.number(),\n\tcertData: z.string(),\n});\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { DNS_TIMEOUT_MS, DNS_RETRIES, DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY, DOH_EDGE_CACHE_TTL, DNS_RETRY_BASE_DELAY_MS } from './config';\nimport { type DohResponse, type QueryDnsOptions, RecordType, type RecordTypeName } from './dns-types';\nimport { DohResponseSchema } from '../schemas/dns';\n\nconst DOH_ENDPOINT = 'https://cloudflare-dns.com/dns-query';\nconst GOOGLE_DOH_ENDPOINT = 'https://dns.google/resolve';\n\nfunction buildDohUrl(endpoint: string, domain: string, type: RecordTypeName, dnssecCheck: boolean): string {\n\tconst params = new URLSearchParams({\n\t\tname: domain,\n\t\ttype,\n\t\t...(dnssecCheck ? { cd: '0' } : {}),\n\t});\n\n\treturn `${endpoint}?${params.toString()}`;\n}\n\nfunction hasTypedAnswers(response: DohResponse, type: RecordTypeName): boolean {\n\treturn (response.Answer ?? []).some((answer) => answer.type === RecordType[type]);\n}\n\nfunction retryDelay(attempt: number): Promise<void> {\n\treturn new Promise((r) => setTimeout(r, DNS_RETRY_BASE_DELAY_MS * (attempt + 1) + Math.random() * 50));\n}\n\n/**\n * Fetch a DoH response from a URL.\n *\n * @param token - Optional auth token sent as `X-BV-Token` (for custom secondary resolvers).\n * @param useEdgeCache - If true, attaches Cloudflare `cf` cache directive. Omit for external origins.\n */\nasync function fetchDohResponse(\n\turl: string,\n\ttimeoutMs: number,\n\topts?: { token?: string; useEdgeCache?: boolean },\n): Promise<DohResponse | null> {\n\ttry {\n\t\tconst headers: Record<string, string> = { Accept: 'application/dns-json' };\n\t\tif (opts?.token) headers['X-BV-Token'] = opts.token;\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: 'GET',\n\t\t\theaders,\n\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t...(opts?.useEdgeCache ? { cf: { cacheTtl: DOH_EDGE_CACHE_TTL, cacheEverything: true } } : {}),\n\t\t});\n\t\tif (!response.ok) return null;\n\t\tconst data = await response.json();\n\t\tconst parsed = DohResponseSchema.safeParse(data);\n\t\tif (!parsed.success) return null;\n\t\treturn parsed.data as DohResponse;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Error thrown when a DNS query fails */\nexport class DnsQueryError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly domain: string,\n\t\tpublic readonly recordType: string,\n\t\tpublic readonly status?: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'DnsQueryError';\n\t}\n}\n\n/**\n * Query Cloudflare DoH for DNS records.\n *\n * When `opts.queryCache` is provided, deduplicates concurrent and sequential\n * identical queries within a single scan by caching the Promise keyed by\n * `domain:type:dnssecCheck`. Failed queries are evicted so retries can re-attempt.\n *\n * @param domain - The domain name to query\n * @param type - DNS record type name (e.g. \"TXT\", \"MX\", \"A\")\n * @param dnssecCheck - If true, sets the CD=0 flag to request DNSSEC validation\n * @returns The full DoH JSON response\n */\nexport async function queryDns(domain: string, type: RecordTypeName, dnssecCheck = false, opts?: QueryDnsOptions): Promise<DohResponse> {\n\tconst cache = opts?.queryCache;\n\tif (!cache) {\n\t\treturn queryDnsUncached(domain, type, dnssecCheck, opts);\n\t}\n\n\tconst cacheKey = `${domain}:${type}:${dnssecCheck}`;\n\tconst existing = cache.get(cacheKey);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\n\tconst promise = queryDnsUncached(domain, type, dnssecCheck, opts);\n\tcache.set(cacheKey, promise);\n\tpromise.catch(() => cache.delete(cacheKey));\n\treturn promise;\n}\n\nasync function queryDnsUncached(domain: string, type: RecordTypeName, dnssecCheck = false, opts?: QueryDnsOptions): Promise<DohResponse> {\n\tconst timeoutMs = opts?.timeoutMs ?? DNS_TIMEOUT_MS;\n\tconst retries = opts?.retries ?? DNS_RETRIES;\n\tconst confirmWithSecondaryOnEmpty = opts?.confirmWithSecondaryOnEmpty ?? DNS_CONFIRM_WITH_SECONDARY_ON_EMPTY;\n\tconst url = buildDohUrl(DOH_ENDPOINT, domain, type, dnssecCheck);\n\n\tfor (let attempt = 0; attempt <= retries; attempt++) {\n\t\tlet response: Response;\n\n\t\ttry {\n\t\t\tresponse = await fetch(url, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { Accept: 'application/dns-json' },\n\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t\tcf: { cacheTtl: DOH_EDGE_CACHE_TTL, cacheEverything: true },\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (err instanceof DOMException && err.name === 'AbortError') {\n\t\t\t\tif (attempt < retries) {\n\t\t\t\t\tawait retryDelay(attempt);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new DnsQueryError(`DNS query timed out after ${timeoutMs}ms`, domain, type);\n\t\t\t}\n\t\t\tif (attempt < retries) {\n\t\t\t\tawait retryDelay(attempt);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DnsQueryError(`DNS query failed: ${err instanceof Error ? err.message : String(err)}`, domain, type);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tif (attempt < retries && response.status >= 500) {\n\t\t\t\tawait retryDelay(attempt);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DnsQueryError(`DoH returned HTTP ${response.status}`, domain, type, response.status);\n\t\t}\n\n\t\tconst raw = await response.json();\n\t\tconst validated = DohResponseSchema.safeParse(raw);\n\t\tif (!validated.success) {\n\t\t\tthrow new DnsQueryError('Invalid DoH response format', domain, type);\n\t\t}\n\t\tconst data = validated.data as DohResponse;\n\n\t\tif (confirmWithSecondaryOnEmpty && !opts?.skipSecondaryConfirmation && !hasTypedAnswers(data, type)) {\n\t\t\t// Try custom secondary (bv-dns) first if configured\n\t\t\tif (opts?.secondaryDoh?.endpoint) {\n\t\t\t\tconst bvDns = await fetchDohResponse(\n\t\t\t\t\tbuildDohUrl(opts.secondaryDoh.endpoint, domain, type, dnssecCheck),\n\t\t\t\t\ttimeoutMs,\n\t\t\t\t\t{ token: opts.secondaryDoh.token },\n\t\t\t\t);\n\t\t\t\tif (bvDns && hasTypedAnswers(bvDns, type)) {\n\t\t\t\t\treturn bvDns;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Google DoH as final fallback\n\t\t\tconst google = await fetchDohResponse(\n\t\t\t\tbuildDohUrl(GOOGLE_DOH_ENDPOINT, domain, type, dnssecCheck),\n\t\t\t\ttimeoutMs,\n\t\t\t\t{ useEdgeCache: true },\n\t\t\t);\n\t\t\tif (google && hasTypedAnswers(google, type)) {\n\t\t\t\treturn google;\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tthrow new DnsQueryError('DNS query failed after retries', domain, type);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { queryDns } from './dns-transport';\nimport { RecordType, type QueryDnsOptions, type RecordTypeName } from './dns-types';\nimport { CaaRecordSchema, TlsaRecordSchema } from '../schemas/dns';\n\n/** Parsed CAA record with flags, tag, and value */\nexport interface CaaRecord {\n\tflags: number;\n\ttag: string;\n\tvalue: string;\n}\n\n/** Parsed PTR record hostname */\nexport interface PtrRecord {\n\thostname: string;\n}\n\n/** Parsed SRV record with priority, weight, port, and target */\nexport interface SrvRecord {\n\tpriority: number;\n\tweight: number;\n\tport: number;\n\ttarget: string;\n}\n\n/** Parsed TLSA record with usage, selector, matching type, and certificate data */\nexport interface TlsaRecord {\n\tusage: number;\n\tselector: number;\n\tmatchingType: number;\n\tcertData: string;\n}\n\n/**\n * Query DNS and return just the answer data strings.\n * Returns an empty array if no answers are found.\n */\nexport async function queryDnsRecords(domain: string, type: RecordTypeName, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst resp = await queryDns(domain, type, false, opts);\n\treturn (resp.Answer ?? []).filter((answer) => answer.type === RecordType[type]).map((answer) => answer.data);\n}\n\n/**\n * Query TXT records, concatenate multi-string values, and unescape DNS\n * presentation-format backslash sequences.\n *\n * Cloudflare DoH returns TXT data with surrounding quotes and multiple\n * strings separated by `\" \"`. Per RFC 7208 §3.3, multi-string TXT records\n * MUST be concatenated without adding spaces. Some nameservers also emit\n * RFC 1035 §5.1 backslash escapes (e.g. `\\;` for a literal semicolon);\n * we unescape both `\\X` (single-char) and `\\DDD` (decimal octet) forms.\n */\nexport async function queryTxtRecords(domain: string, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst records = await queryDnsRecords(domain, 'TXT', opts);\n\treturn records.map((record) =>\n\t\tunescapeDnsTxt(\n\t\t\trecord\n\t\t\t\t.replace(/\" \"/g, '')\n\t\t\t\t.replace(/^\"|\"$/g, ''),\n\t\t),\n\t);\n}\n\n/**\n * Unescape DNS presentation-format backslash sequences in TXT record data.\n * Handles `\\DDD` (decimal octet 000–255) and `\\X` (literal character).\n *\n * Some DoH providers double-escape (e.g. `\\\\;` in the JS string for what\n * should be a plain `;`), so we loop until the string stabilises.\n */\nexport function unescapeDnsTxt(text: string): string {\n\tconst unescape = (s: string) =>\n\t\ts.replace(/\\\\(\\d{3})|\\\\(.)/g, (_, decimal, ch) => {\n\t\t\tif (decimal !== undefined) {\n\t\t\t\tconst code = parseInt(decimal, 10);\n\t\t\t\treturn code <= 255 ? String.fromCharCode(code) : `\\\\${decimal}`;\n\t\t\t}\n\t\t\treturn ch;\n\t\t});\n\n\tlet result = text;\n\tfor (let i = 0; i < 2; i++) {\n\t\tconst next = unescape(result);\n\t\tif (next === result) break;\n\t\tresult = next;\n\t}\n\treturn result;\n}\n\n/**\n * Check if a domain has valid DNSSEC by examining the AD (Authenticated Data) flag.\n * Returns true if the response was DNSSEC-validated.\n */\nexport async function checkDnssec(domain: string, opts?: QueryDnsOptions): Promise<boolean> {\n\tconst resp = await queryDns(domain, 'A', true, opts);\n\treturn resp.AD === true;\n}\n\n/**\n * Parse a single CAA record data string.\n * Handles both human-readable format (e.g. `0 issue \"letsencrypt.org\"`)\n * and Cloudflare DoH hex wire format (e.g. `\\# 19 00 05 69 73 73 75 65...`).\n *\n * Wire format bytes: flags(1) + tag_length(1) + tag(tag_length) + value(rest)\n */\nexport function parseCaaRecord(data: string): CaaRecord | null {\n\tif (data.startsWith('\\\\#') || data.startsWith('#')) {\n\t\tconst parts = data.trim().split(/\\s+/);\n\t\tconst hexStart = parts[0] === '\\\\#' || parts[0] === '#' ? 2 : 1;\n\t\tconst hexBytes = parts.slice(hexStart);\n\t\tif (hexBytes.length < 3) return null;\n\n\t\tconst flags = parseInt(hexBytes[0], 16);\n\t\tconst tagLen = parseInt(hexBytes[1], 16);\n\t\tif (isNaN(flags) || isNaN(tagLen) || hexBytes.length < 2 + tagLen) return null;\n\n\t\tconst tag = hexBytes\n\t\t\t.slice(2, 2 + tagLen)\n\t\t\t.map((hexByte) => String.fromCharCode(parseInt(hexByte, 16)))\n\t\t\t.join('');\n\t\tconst value = hexBytes\n\t\t\t.slice(2 + tagLen)\n\t\t\t.map((hexByte) => String.fromCharCode(parseInt(hexByte, 16)))\n\t\t\t.join('');\n\n\t\tconst record = { flags, tag: tag.toLowerCase(), value };\n\t\treturn CaaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\tconst match = data.match(/^(\\d+)\\s+(\\S+)\\s+\"?([^\"]*)\"?\\s*$/);\n\tif (match) {\n\t\tconst record = {\n\t\t\tflags: parseInt(match[1], 10),\n\t\t\ttag: match[2].toLowerCase(),\n\t\t\tvalue: match[3],\n\t\t};\n\t\treturn CaaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\treturn null;\n}\n\n/**\n * Query CAA records and parse them into structured objects.\n * Handles both human-readable and hex wire format from DoH.\n */\nexport async function queryCaaRecords(domain: string, opts?: QueryDnsOptions): Promise<CaaRecord[]> {\n\tconst records = await queryDnsRecords(domain, 'CAA', opts);\n\treturn records.map(parseCaaRecord).filter((record): record is CaaRecord => record !== null);\n}\n\n/**\n * Query MX records and parse them into priority + exchange pairs.\n */\nexport async function queryMxRecords(domain: string, opts?: QueryDnsOptions): Promise<Array<{ priority: number; exchange: string }>> {\n\tconst records = await queryDnsRecords(domain, 'MX', opts);\n\treturn records.map((record) => {\n\t\tconst parts = record.split(' ');\n\t\treturn {\n\t\t\tpriority: parseInt(parts[0], 10),\n\t\t\texchange: parts.slice(1).join(' ').replace(/\\.$/, ''),\n\t\t};\n\t});\n}\n\n/**\n * Query PTR records for an IP address by constructing the reverse DNS name.\n * For IPv4 address `192.0.2.1`, queries `1.2.0.192.in-addr.arpa`.\n * Returns an array of PTR hostnames with trailing dots stripped.\n */\nexport async function queryPtrRecords(ip: string, opts?: QueryDnsOptions): Promise<string[]> {\n\tconst reverseName = ip.split('.').reverse().join('.') + '.in-addr.arpa';\n\tconst records = await queryDnsRecords(reverseName, 'PTR', opts);\n\treturn records.map((record) => record.replace(/\\.$/, ''));\n}\n\n/**\n * Query SRV records and parse them into structured objects.\n * SRV data format: `priority weight port target`\n */\nexport async function querySrvRecords(\n\tname: string,\n\topts?: QueryDnsOptions,\n): Promise<Array<{ priority: number; weight: number; port: number; target: string }>> {\n\tconst records = await queryDnsRecords(name, 'SRV', opts);\n\treturn records.map((record) => {\n\t\tconst parts = record.split(' ');\n\t\treturn {\n\t\t\tpriority: parseInt(parts[0], 10),\n\t\t\tweight: parseInt(parts[1], 10),\n\t\t\tport: parseInt(parts[2], 10),\n\t\t\ttarget: parts.slice(3).join(' ').replace(/\\.$/, ''),\n\t\t};\n\t});\n}\n\n/**\n * Parse a TLSA record data string into structured fields.\n * Handles both human-readable format (`usage selector matchingType certData`)\n * and hex wire format (data starting with `\\#`).\n *\n * Returns null if the data cannot be parsed.\n */\nexport function parseTlsaRecord(data: string): TlsaRecord | null {\n\tif (data.startsWith('\\\\#') || data.startsWith('#')) {\n\t\tconst parts = data.trim().split(/\\s+/);\n\t\tconst hexStart = parts[0] === '\\\\#' || parts[0] === '#' ? 2 : 1;\n\t\tconst hexBytes = parts.slice(hexStart);\n\t\tif (hexBytes.length < 4) return null;\n\n\t\tconst usage = parseInt(hexBytes[0], 16);\n\t\tconst selector = parseInt(hexBytes[1], 16);\n\t\tconst matchingType = parseInt(hexBytes[2], 16);\n\t\tif (isNaN(usage) || isNaN(selector) || isNaN(matchingType)) return null;\n\n\t\tconst certData = hexBytes.slice(3).join('');\n\t\tconst record = { usage, selector, matchingType, certData };\n\t\treturn TlsaRecordSchema.safeParse(record).success ? record : null;\n\t}\n\n\tconst parts = data.trim().split(/\\s+/);\n\tif (parts.length < 4) return null;\n\n\tconst usage = parseInt(parts[0], 10);\n\tconst selector = parseInt(parts[1], 10);\n\tconst matchingType = parseInt(parts[2], 10);\n\tif (isNaN(usage) || isNaN(selector) || isNaN(matchingType)) return null;\n\n\tconst certData = parts.slice(3).join('');\n\tconst record = { usage, selector, matchingType, certData };\n\treturn TlsaRecordSchema.safeParse(record).success ? record : null;\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Adaptive weight computation for context-aware scoring.\n *\n * Uses exponential moving averages (EMA) of per-category failure rates,\n * collected by the ProfileAccumulator Durable Object, to adjust static\n * importance weights at scoring time. A maturity-gated blend ensures\n * weights stay close to static until enough telemetry has accumulated.\n */\n\nimport type { CheckCategory } from './scoring-model';\nimport type { DomainProfile } from './context-profiles';\nimport { PROFILE_WEIGHTS } from './context-profiles';\n\n// ─── Telemetry interfaces ──────────────────────────────────────────────\n\n/** A single scan's telemetry payload sent to the ProfileAccumulator DO. */\nexport interface ScanTelemetry {\n\tprofile: string;\n\tprovider: string | null;\n\tcategoryFindings: Array<{ category: string; score: number; passed: boolean }>;\n\ttimestamp: number;\n\t/** Overall scan score (0–100). Used for intelligence layer aggregation (histogram, cohort, trends). */\n\toverallScore?: number;\n}\n\n/** Response from the adaptive weights endpoint. */\nexport interface AdaptiveWeightsResponse {\n\tprofile: string;\n\tprovider: string | null;\n\tsampleCount: number;\n\tblendFactor: number;\n\tweights: Record<string, number>;\n\tboundHits: string[];\n}\n\n/** Min/max bounds for an adaptive weight value. */\nexport interface WeightBound {\n\tmin: number;\n\tmax: number;\n}\n\n// ─── Constants ─────────────────────────────────────────────────────────\n\n/** How aggressively deviation from baseline adjusts the weight (0–1). */\nexport const SENSITIVITY = 0.5;\n\n/** Sample count at which blending reaches 100% adaptive. */\nexport const MATURITY_THRESHOLD = 200;\n\n/** EMA span (number of recent observations the average reflects). */\nexport const EMA_SPAN = 200;\n\n/** EMA smoothing factor derived from span. */\nexport const EMA_ALPHA = 2 / (EMA_SPAN + 1);\n\n/** Minimum |scoreDelta| before a scoring note is generated. */\nexport const SCORING_NOTE_DELTA_THRESHOLD = 3;\n\n/** Expected failure rate per category across all domains (prior). */\nexport const BASELINE_FAILURE_RATES: Record<string, number> = {\n\tdmarc: 0.40,\n\tspf: 0.25,\n\tdkim: 0.35,\n\tssl: 0.08,\n\tmta_sts: 0.85,\n\tdnssec: 0.80,\n\tmx: 0.05,\n\tcaa: 0.70,\n\tns: 0.03,\n\tbimi: 0.95,\n\ttlsrpt: 0.90,\n\tsubdomain_takeover: 0.10,\n\tlookalikes: 0.00,\n};\n\n// ─── Weight bounds ─────────────────────────────────────────────────────\n\n/** Categories treated as \"critical mail\" for bound computation in mail-centric profiles. */\nconst CRITICAL_MAIL_CATEGORIES = new Set<string>(['dmarc', 'spf', 'dkim', 'ssl']);\n\n/** Profiles where critical-mail floor applies. */\nconst CRITICAL_MAIL_PROFILES = new Set<string>(['mail_enabled', 'enterprise_mail']);\n\n/**\n * Compute default min/max bounds for an adaptive weight.\n *\n * Critical-mail categories get a higher floor (min 5) to prevent\n * important email-auth checks from being zeroed out.\n */\nexport function defaultBounds(staticWeight: number, isCriticalMail: boolean): WeightBound {\n\tconst minFloor = isCriticalMail ? 5 : 0;\n\treturn {\n\t\tmin: Math.max(minFloor, Math.floor(staticWeight * 0.5)),\n\t\tmax: Math.ceil(staticWeight * 2) + 3,\n\t};\n}\n\n/** Pre-computed bounds for every profile × category combination. */\nexport const WEIGHT_BOUNDS: Record<DomainProfile, Record<CheckCategory, WeightBound>> = (() => {\n\tconst profiles = Object.keys(PROFILE_WEIGHTS) as DomainProfile[];\n\tconst result = {} as Record<DomainProfile, Record<CheckCategory, WeightBound>>;\n\n\tfor (const profile of profiles) {\n\t\tconst weights = PROFILE_WEIGHTS[profile];\n\t\tconst categories = Object.keys(weights) as CheckCategory[];\n\t\tconst profileBounds = {} as Record<CheckCategory, WeightBound>;\n\n\t\tfor (const cat of categories) {\n\t\t\tconst isCritical = CRITICAL_MAIL_PROFILES.has(profile) && CRITICAL_MAIL_CATEGORIES.has(cat);\n\t\t\tprofileBounds[cat] = defaultBounds(weights[cat].importance, isCritical);\n\t\t}\n\n\t\tresult[profile] = profileBounds;\n\t}\n\n\treturn result;\n})();\n\n// ─── Computation functions ─────────────────────────────────────────────\n\n/**\n * Compute a single adaptive weight from EMA failure rate and baseline.\n *\n * @returns The clamped weight and whether a bound was hit ('min' | 'max' | null).\n */\nexport function computeAdaptiveWeight(params: {\n\tstaticWeight: number;\n\temaFailureRate: number;\n\tbaselineFailureRate: number;\n\tbounds: WeightBound;\n}): { weight: number; boundHit: 'min' | 'max' | null } {\n\tconst { staticWeight, emaFailureRate, baselineFailureRate, bounds } = params;\n\n\tconst deviation = emaFailureRate - baselineFailureRate;\n\tconst rawAdjustment = deviation * SENSITIVITY * staticWeight;\n\tconst adaptive = staticWeight + rawAdjustment;\n\tconst clamped = Math.max(bounds.min, Math.min(bounds.max, adaptive));\n\n\tlet boundHit: 'min' | 'max' | null = null;\n\tif (clamped <= bounds.min && adaptive < bounds.min) {\n\t\tboundHit = 'min';\n\t} else if (clamped >= bounds.max && adaptive > bounds.max) {\n\t\tboundHit = 'max';\n\t}\n\n\treturn { weight: clamped, boundHit };\n}\n\n/**\n * Blend static and adaptive weights based on sample maturity.\n *\n * Returns `(1 - blendFactor) * staticWeight + blendFactor * adaptiveWeight`\n * where `blendFactor = min(1.0, sampleCount / MATURITY_THRESHOLD)`.\n */\nexport function blendWeights(staticWeight: number, adaptiveWeight: number, sampleCount: number): number {\n\tconst blendFactor = Math.min(1.0, sampleCount / MATURITY_THRESHOLD);\n\treturn (1 - blendFactor) * staticWeight + blendFactor * adaptiveWeight;\n}\n\n// ─── Type adapter ──────────────────────────────────────────────────────\n\n/**\n * Convert a DO-returned weight map to a CheckCategory-keyed importance record.\n *\n * Falls back to the static profile weight for any category not present in the\n * DO response. Returns `null` if any value is non-finite or negative.\n */\nexport function adaptiveWeightsToContext(\n\tdoWeights: Record<string, number>,\n\tprofile: DomainProfile,\n): Record<CheckCategory, { importance: number }> | null {\n\tconst staticWeights = PROFILE_WEIGHTS[profile];\n\tconst categories = Object.keys(staticWeights) as CheckCategory[];\n\tconst result = {} as Record<CheckCategory, { importance: number }>;\n\n\tfor (const cat of categories) {\n\t\tconst value = cat in doWeights ? doWeights[cat] : staticWeights[cat].importance;\n\t\tif (!isFinite(value) || value < 0) {\n\t\t\treturn null;\n\t\t}\n\t\tresult[cat] = { importance: value };\n\t}\n\n\treturn result;\n}\n\n// ─── Scoring note generation ───────────────────────────────────────────\n\n/**\n * Generate a human-readable note explaining adaptive weight shifts.\n *\n * Returns `null` if the absolute score delta is below the threshold.\n */\nexport function generateScoringNote(\n\tweightDeltas: Record<string, number>,\n\tscoreDelta: number,\n\tprovider: string | null,\n): string | null {\n\tif (Math.abs(scoreDelta) < SCORING_NOTE_DELTA_THRESHOLD) {\n\t\treturn null;\n\t}\n\n\t// Collect significant deltas (|delta| >= 2) sorted by magnitude descending\n\tconst significant = Object.entries(weightDeltas)\n\t\t.filter(([, d]) => Math.abs(d) >= 2)\n\t\t.sort((a, b) => Math.abs(b[1]) - Math.abs(a[1]));\n\n\tif (significant.length === 0) {\n\t\t// No individually significant deltas but overall threshold met — use the largest anyway\n\t\tconst all = Object.entries(weightDeltas).sort((a, b) => Math.abs(b[1]) - Math.abs(a[1]));\n\t\tif (all.length === 0) return null;\n\t\tconst [topCat, topDelta] = all[0];\n\t\treturn formatNote(topCat, topDelta, provider);\n\t}\n\n\tif (significant.length >= 3) {\n\t\tconst [topCat] = significant[0];\n\t\treturn `Several checks were weighted differently based on patterns seen across similar domains. The biggest shift was in ${topCat.toUpperCase()}.`;\n\t}\n\n\tconst [topCat, topDelta] = significant[0];\n\treturn formatNote(topCat, topDelta, provider);\n}\n\n/** Format a single-category scoring note. */\nfunction formatNote(category: string, delta: number, provider: string | null): string {\n\tconst cat = category.toUpperCase();\n\n\tif (delta > 0 && provider) {\n\t\tconst providerDisplay = capitalizeWords(provider);\n\t\treturn `${cat} carried more weight because domains using ${providerDisplay} frequently have issues in this area.`;\n\t}\n\n\tif (delta > 0) {\n\t\treturn `${cat} carried more weight in this scan because it is a common issue across similar domains.`;\n\t}\n\n\treturn `${cat} carried less weight because similar domains rarely have issues there.`;\n}\n\n/** Capitalize the first letter of each word. */\nfunction capitalizeWords(s: string): string {\n\treturn s.replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n// For IDN/Unicode normalization\nimport * as punycode from 'punycode/';\n// Centralized normalization config\nimport {\n\tBLOCKED_SUFFIXES,\n\tBLOCKED_HOSTS,\n\tBLOCKED_IP_PATTERNS,\n\tBLOCKED_DNS_REBINDING,\n\tMAX_DOMAIN_LENGTH,\n\tMAX_LABEL_LENGTH,\n\tLABEL_REGEX,\n} from './config';\n/**\n * Input sanitization and validation utilities for the DNS Security MCP Server.\n * Handles domain validation, input cleaning, and MCP error response helpers.\n * Compatible with Cloudflare Workers runtime (no Node.js APIs).\n */\n\nexport interface ValidationResult {\n\tvalid: boolean;\n\terror?: string;\n}\n\n/**\n * Parse a numeric IPv4 segment using decimal, octal, or hex notation.\n * Returns null when the token is not a numeric IP segment.\n */\nfunction parseIpv4NumberToken(token: string): number | null {\n\tif (!token) return null;\n\n\tlet radix = 10;\n\tlet digits = token;\n\tif (/^0x[0-9a-f]+$/i.test(token)) {\n\t\tradix = 16;\n\t\tdigits = token.slice(2);\n\t} else if (/^0[0-7]+$/.test(token) && token.length > 1) {\n\t\tradix = 8;\n\t}\n\n\tif (digits.length === 0) return null;\n\tconst value = Number.parseInt(digits, radix);\n\tif (!Number.isFinite(value) || value < 0) return null;\n\treturn value;\n}\n\n/**\n * Canonicalize IPv4 literals that may use short/octal/hex forms.\n * Returns null when input is not an IPv4 host literal candidate.\n */\nfunction canonicalizeIpv4Literal(input: string): string | null {\n\tif (!/^[0-9a-fx.]+$/i.test(input)) return null;\n\n\tconst parts = input.split('.');\n\tif (parts.length < 1 || parts.length > 4) return null;\n\tif (parts.some((part) => part.length === 0)) return null;\n\n\tconst values: number[] = [];\n\tfor (const part of parts) {\n\t\tconst parsed = parseIpv4NumberToken(part);\n\t\tif (parsed === null) return null;\n\t\tvalues.push(parsed);\n\t}\n\n\tlet ipAsUint32 = 0;\n\tif (values.length === 1) {\n\t\tif (values[0] > 0xffffffff) return null;\n\t\tipAsUint32 = values[0] >>> 0;\n\t} else if (values.length === 2) {\n\t\tif (values[0] > 0xff || values[1] > 0xffffff) return null;\n\t\tipAsUint32 = ((values[0] << 24) | values[1]) >>> 0;\n\t} else if (values.length === 3) {\n\t\tif (values[0] > 0xff || values[1] > 0xff || values[2] > 0xffff) return null;\n\t\tipAsUint32 = ((values[0] << 24) | (values[1] << 16) | values[2]) >>> 0;\n\t} else {\n\t\tif (values.some((value) => value > 0xff)) return null;\n\t\tipAsUint32 = ((values[0] << 24) | (values[1] << 16) | (values[2] << 8) | values[3]) >>> 0;\n\t}\n\n\tconst oct1 = (ipAsUint32 >>> 24) & 0xff;\n\tconst oct2 = (ipAsUint32 >>> 16) & 0xff;\n\tconst oct3 = (ipAsUint32 >>> 8) & 0xff;\n\tconst oct4 = ipAsUint32 & 0xff;\n\treturn `${oct1}.${oct2}.${oct3}.${oct4}`;\n}\n\n/**\n * Validate and sanitize a domain name for DNS queries.\n * Rejects localhost, private/reserved TLDs, IP addresses, and malformed domains.\n */\n\nexport function validateDomain(input: string): ValidationResult {\n\tif (!input || typeof input !== 'string') {\n\t\treturn { valid: false, error: 'Domain name is required' };\n\t}\n\n\t// Check for invisible/non-printable Unicode (except space, dot, hyphen)\n\tconst invisiblePattern = /[\\p{C}\\p{Zl}\\p{Zp}\\u200B-\\u200D\\uFEFF]/gu;\n\tif (invisiblePattern.test(input)) {\n\t\treturn { valid: false, error: 'Domain contains invalid Unicode or cannot be converted to ASCII' };\n\t}\n\tconst cleaned = input.replace(invisiblePattern, '').trim();\n\tif (cleaned.length === 0) {\n\t\treturn { valid: false, error: 'Domain name is required' };\n\t}\n\n\t// Normalize Unicode to NFC, lowercase, remove trailing dot\n\tlet domain = cleaned.normalize('NFC').toLowerCase();\n\tif (domain.endsWith('.')) domain = domain.slice(0, -1);\n\n\t// Convert Unicode/emoji/IDN to punycode for validation\n\tlet asciiDomain: string;\n\ttry {\n\t\tasciiDomain = punycode.toASCII(domain);\n\t} catch {\n\t\treturn { valid: false, error: 'Domain contains invalid Unicode or cannot be converted to ASCII' };\n\t}\n\n\tif (asciiDomain.length > MAX_DOMAIN_LENGTH) {\n\t\treturn { valid: false, error: `Domain exceeds maximum length of ${MAX_DOMAIN_LENGTH} characters` };\n\t}\n\n\t// Check blocked exact hostnames\n\tif (BLOCKED_HOSTS.includes(asciiDomain)) {\n\t\treturn { valid: false, error: `Domain \"${asciiDomain}\" is not allowed: reserved hostname` };\n\t}\n\n\t// Check blocked suffixes\n\tfor (const suffix of BLOCKED_SUFFIXES) {\n\t\tif (asciiDomain === suffix.slice(1) || asciiDomain.endsWith(suffix)) {\n\t\t\treturn { valid: false, error: `Domain \"${asciiDomain}\" is not allowed: reserved TLD \"${suffix}\"` };\n\t\t}\n\t}\n\n\t// Canonicalize non-standard IPv4 literals (e.g. 127.1, 0177.0.0.1)\n\t// and reject all IP literal forms (public, private, and special).\n\tconst canonicalIpv4 = canonicalizeIpv4Literal(asciiDomain);\n\tif (canonicalIpv4) {\n\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t}\n\n\t// Reject dotted numeric host literals that are IPv4-like but malformed/out-of-range.\n\tif (/^\\d+(?:\\.\\d+){1,3}$/.test(asciiDomain)) {\n\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t}\n\n\t// Check if it looks like an IP address (blocked)\n\tfor (const pattern of BLOCKED_IP_PATTERNS) {\n\t\tif (pattern.test(asciiDomain)) {\n\t\t\treturn { valid: false, error: `IP addresses are not allowed: \"${asciiDomain}\"` };\n\t\t}\n\t}\n\n\t// Check for DNS rebinding services\n\tfor (const suffix of BLOCKED_DNS_REBINDING) {\n\t\tif (asciiDomain === suffix.slice(1) || asciiDomain.endsWith(suffix)) {\n\t\t\treturn { valid: false, error: 'Domain uses a DNS rebinding service and is not allowed' };\n\t\t}\n\t}\n\n\t// Validate domain label structure (punycode labels)\n\tconst labels = asciiDomain.split('.');\n\tif (labels.length < 2) {\n\t\treturn { valid: false, error: 'Domain must have at least two labels (e.g., example.com)' };\n\t}\n\tfor (const label of labels) {\n\t\tif (label.length === 0) {\n\t\t\treturn { valid: false, error: 'Domain contains empty label (consecutive dots)' };\n\t\t}\n\t\t// Strip HTML/script tags from label before including in error messages\n\t\tconst safeLabel = label.replace(/[<>]/g, '').slice(0, 63);\n\t\tif (label.length > MAX_LABEL_LENGTH) {\n\t\t\treturn { valid: false, error: `Label \"${safeLabel}\" exceeds maximum length of ${MAX_LABEL_LENGTH} characters` };\n\t\t}\n\t\tif (!LABEL_REGEX.test(label)) {\n\t\t\treturn { valid: false, error: `Label \"${safeLabel}\" contains invalid characters` };\n\t\t}\n\t}\n\n\treturn { valid: true };\n}\n\n/**\n * Sanitize a domain string: trim, lowercase, remove trailing dot.\n * Call validateDomain first to ensure the domain is valid.\n */\nexport function sanitizeDomain(input: string): string {\n\t// Remove invisible/non-printable Unicode (except space, dot, hyphen)\n\tconst cleaned = input.replace(/[\\p{C}\\p{Zl}\\p{Zp}\\u200B-\\u200D\\uFEFF]/gu, '').trim();\n\tif (cleaned.length === 0) return '';\n\tlet domain = cleaned.normalize('NFC').toLowerCase();\n\tif (domain.endsWith('.')) domain = domain.slice(0, -1);\n\t// Convert Unicode/emoji/IDN to punycode for DNS queries\n\ttry {\n\t\treturn punycode.toASCII(domain);\n\t} catch {\n\t\treturn '';\n\t}\n}\n\n/**\n * Sanitize arbitrary text input for safe logging/display.\n * Removes control characters except newlines and tabs, and truncates length.\n */\nexport function sanitizeInput(input: string, maxLength = 500): string {\n\tif (typeof input !== 'string') return '';\n\tconst sanitized = input.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\treturn sanitized.slice(0, maxLength);\n}\n\n\n","// SPDX-License-Identifier: BUSL-1.1\n\n/** Server version — keep in sync with package.json */\nexport const SERVER_VERSION = '2.2.2';\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\n\n/**\n * Domain name — shape validation only (length 1-253).\n *\n * Intentional two-layer design: this schema validates the string shape so Zod can\n * reject obviously invalid input early (empty strings, oversized payloads). The\n * second layer — `validateDomain()` + `sanitizeDomain()` from `lib/sanitize.ts` —\n * handles structural validation (label rules, TLD checks), SSRF protection\n * (blocked IPs/TLDs), and punycode normalization. That second layer runs after Zod\n * in `extractAndValidateDomain()` (handlers/tool-args.ts).\n */\nexport const DomainSchema = z.string().min(1).max(253);\n\n/** Session ID — exactly 64 lowercase hex characters. */\nexport const SessionIdSchema = z.string().regex(/^[0-9a-f]{64}$/);\n\n/** DKIM selector — valid DNS label, max 63 chars. Trims and lowercases input before validation. */\nexport const DkimSelectorSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.string().max(63).regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/));\n\n/** Internal route tool name — lowercase + underscores, max 30 chars. */\nexport const ToolNameSchema = z.string().min(1).max(30).regex(/^[a-z_]+$/);\n\n/** Safe label for array elements (provider names, MX hosts). */\nexport const SafeLabelSchema = z.string().min(1).max(253);\n\n/** Scoring profile (with auto). Used by scan_domain. Trims and lowercases input. */\nexport const ProfileSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['auto', 'mail_enabled', 'enterprise_mail', 'non_mail', 'web_only', 'minimal']));\n\n/** Scoring profile (without auto). Used by get_benchmark, get_provider_insights. Trims and lowercases input. */\nexport const BenchmarkProfileSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['mail_enabled', 'enterprise_mail', 'non_mail', 'web_only', 'minimal']));\n\n/** Output format. Trims and lowercases input before validation. */\nexport const FormatSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['full', 'compact']));\n\n/** DNS record type for resolver consistency. Trims and uppercases input before validation. */\nexport const RecordTypeSchema = z.string().transform(s => s.trim().toUpperCase()).pipe(z.enum(['A', 'AAAA', 'MX', 'TXT', 'NS', 'CNAME', 'SOA', 'CAA']));\n\n/** Security grade. */\nexport const GradeSchema = z.enum(['A+', 'A', 'B+', 'B', 'C+', 'C', 'D+', 'D', 'F']);\n\n/** API key tier. */\nexport const TierSchema = z.enum(['free', 'agent', 'developer', 'enterprise', 'partner', 'owner']);\n\n/** DMARC policy for generate_dmarc_record. Trims and lowercases input. */\nexport const DmarcPolicySchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['none', 'quarantine', 'reject']));\n\n/** Explain finding status values. Trims and lowercases input. */\nexport const ExplainStatusSchema = z.string().transform(s => s.trim().toLowerCase()).pipe(z.enum(['pass', 'fail', 'warning', 'critical', 'high', 'medium', 'low', 'info']));\n\n/** Inferred types for external use. */\nexport type Profile = z.infer<typeof ProfileSchema>;\nexport type BenchmarkProfile = z.infer<typeof BenchmarkProfileSchema>;\nexport type OutputFormat = z.infer<typeof FormatSchema>;\nexport type Grade = z.infer<typeof GradeSchema>;\nexport type Tier = z.infer<typeof TierSchema>;\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\nimport {\n\tDomainSchema,\n\tFormatSchema,\n\tProfileSchema,\n\tBenchmarkProfileSchema,\n\tDkimSelectorSchema,\n\tRecordTypeSchema,\n\tGradeSchema,\n\tSafeLabelSchema,\n\tDmarcPolicySchema,\n\tExplainStatusSchema,\n} from './primitives';\n\n/** Domain + optional format — shared by most check tools. */\nexport const BaseDomainArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** scan_domain */\nexport const ScanDomainArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tprofile: ProfileSchema.optional().describe('Scoring profile. Default \"auto\" detects.'),\n\tforce_refresh: z.boolean().optional().describe('Bypass cache and run a fresh scan. Useful after DNS changes.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** batch_scan */\nexport const BatchScanArgs = z.object({\n\tdomains: z.array(z.string().min(1).max(253)).min(1).max(10).describe('Domains to scan (max 10 per request)'),\n\tforce_refresh: z.boolean().optional().describe('Bypass cache and run fresh scans.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** compare_domains */\nexport const CompareDomainsArgs = z.object({\n\tdomains: z.array(z.string().min(1).max(253)).min(2).max(5).describe('Domains to compare (2–5 domains)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** check_dkim */\nexport const CheckDkimArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\tselector: DkimSelectorSchema.optional().describe('DKIM selector. Omit to probe common ones.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** check_resolver_consistency */\nexport const CheckResolverConsistencyArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to check (e.g., example.com)'),\n\trecord_type: RecordTypeSchema.optional().describe('Record type. Omit for A/AAAA/MX/TXT/NS.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_spf_record */\nexport const GenerateSpfArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\t// SafeLabelSchema provides min(1)/max(253); .regex() adds a stacking refinement in Zod v4 (does not override).\n\tinclude_providers: z.array(SafeLabelSchema.regex(/^[a-z0-9._-]+$/i)).max(15).optional().describe('Providers to include (e.g., [\"google\"]).'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_dmarc_record */\nexport const GenerateDmarcArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\tpolicy: DmarcPolicySchema.optional().describe('Policy (default \"reject\").'),\n\trua_email: z.string().max(254).optional().describe('Report email. Default: dmarc-reports@{domain}.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_dkim_config */\nexport const GenerateDkimConfigArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\tprovider: z.string().max(100).optional().describe('Provider (e.g., \"google\"). Omit for generic.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_mta_sts_policy */\nexport const GenerateMtaStsArgs = z.object({\n\tdomain: DomainSchema.describe('Domain (e.g., example.com)'),\n\t// SafeLabelSchema provides min(1)/max(253); .regex() adds a stacking refinement in Zod v4 (does not override).\n\tmx_hosts: z.array(SafeLabelSchema.regex(/^[^\\s\\x00-\\x1f\\x7f]*$/)).max(20).optional().describe('MX hosts. Omit to detect from DNS.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** explain_finding */\nexport const ExplainFindingArgs = z.object({\n\tcheckType: z.string().min(1).max(100).describe(\"Check type (e.g., 'SPF', 'DMARC').\"),\n\tstatus: ExplainStatusSchema.describe('Finding severity or status.'),\n\tdetails: z.string().max(2000).optional().describe('Additional detail from check result.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** compare_baseline */\nexport const CompareBaselineArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to scan and compare.'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n\tbaseline: z.object({\n\t\tgrade: GradeSchema.optional().describe('Min grade (e.g., \"B+\").'),\n\t\tscore: z.number().min(0).max(100).optional().describe('Min score (0-100).'),\n\t\trequire_dmarc_enforce: z.boolean().optional().describe('Require DMARC enforce.'),\n\t\trequire_spf: z.boolean().optional().describe('Require SPF.'),\n\t\trequire_dkim: z.boolean().optional().describe('Require DKIM.'),\n\t\trequire_dnssec: z.boolean().optional().describe('Require DNSSEC.'),\n\t\trequire_mta_sts: z.boolean().optional().describe('Require MTA-STS.'),\n\t\trequire_caa: z.boolean().optional().describe('Require CAA.'),\n\t\tmax_critical_findings: z.number().int().min(0).optional().describe('Max critical findings (default 0).'),\n\t\tmax_high_findings: z.number().int().min(0).optional().describe('Max high findings allowed.'),\n\t}).passthrough().describe('Policy baseline requirements.'),\n}).passthrough();\n\n/** get_benchmark */\nexport const GetBenchmarkArgs = z.object({\n\tprofile: BenchmarkProfileSchema.optional().describe('Profile to benchmark (default \"mail_enabled\").'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** get_provider_insights */\nexport const GetProviderInsightsArgs = z.object({\n\tprovider: z.string().min(1).describe('Provider (e.g., \"google workspace\").'),\n\tprofile: BenchmarkProfileSchema.optional().describe('Profile (default \"mail_enabled\").'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** assess_spoofability — same as BaseDomainArgs */\nexport const AssessSpoofabilityArgs = BaseDomainArgs;\n\n/** generate_fix_plan — same as BaseDomainArgs */\nexport const GenerateFixPlanArgs = BaseDomainArgs;\n\nconst CheckNameSchema = z.string().transform((v) => v.toLowerCase().trim()).pipe(\n\tz.enum(['spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta_sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'http_security', 'dane']),\n);\n\nconst TimelineSchema = z.string().transform((v) => v.toLowerCase()).pipe(\n\tz.enum(['aggressive', 'standard', 'conservative']),\n);\n\nconst TargetPolicySchema = z.string().transform((v) => v.toLowerCase()).pipe(\n\tz.enum(['quarantine', 'reject']),\n);\n\n/** validate_fix */\nexport const ValidateFixArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to validate the fix for'),\n\tcheck: CheckNameSchema.describe('Check name to re-run (e.g., \"dmarc\", \"spf\")'),\n\texpected: z.string().max(1000).optional().describe('Expected DNS record value to verify against'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** map_supply_chain — same as BaseDomainArgs */\nexport const MapSupplyChainArgs = BaseDomainArgs;\n\n/** analyze_drift */\nexport const AnalyzeDriftArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to analyze drift for'),\n\tbaseline: z.string().min(1).max(50_000).describe('Previous ScanScore JSON or \"cached\" to use last cached scan'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/** generate_rollout_plan */\nexport const GenerateRolloutPlanArgs = z.object({\n\tdomain: DomainSchema.describe('Domain to generate rollout plan for'),\n\ttarget_policy: TargetPolicySchema.optional().describe('Target DMARC policy (default: reject)'),\n\ttimeline: TimelineSchema.optional().describe('Rollout speed: aggressive, standard, conservative (default: standard)'),\n\tformat: FormatSchema.optional().describe('Output verbosity. Auto-detected if omitted.'),\n}).passthrough();\n\n/**\n * Map of every tool name to its Zod argument schema.\n * Used for runtime validation in tools.ts and for inputSchema generation.\n */\nexport const TOOL_SCHEMA_MAP: Record<string, z.ZodTypeAny> = {\n\tcheck_mx: BaseDomainArgs,\n\tcheck_spf: BaseDomainArgs,\n\tcheck_dmarc: BaseDomainArgs,\n\tcheck_dkim: CheckDkimArgs,\n\tcheck_dnssec: BaseDomainArgs,\n\tcheck_ssl: BaseDomainArgs,\n\tcheck_mta_sts: BaseDomainArgs,\n\tcheck_ns: BaseDomainArgs,\n\tcheck_caa: BaseDomainArgs,\n\tcheck_bimi: BaseDomainArgs,\n\tcheck_tlsrpt: BaseDomainArgs,\n\tcheck_lookalikes: BaseDomainArgs,\n\tcheck_shadow_domains: BaseDomainArgs,\n\tcheck_txt_hygiene: BaseDomainArgs,\n\tcheck_http_security: BaseDomainArgs,\n\tcheck_dane: BaseDomainArgs,\n\tcheck_dane_https: BaseDomainArgs,\n\tcheck_svcb_https: BaseDomainArgs,\n\tcheck_mx_reputation: BaseDomainArgs,\n\tcheck_srv: BaseDomainArgs,\n\tcheck_zone_hygiene: BaseDomainArgs,\n\tcheck_subdomailing: BaseDomainArgs,\n\tscan_domain: ScanDomainArgs,\n\tbatch_scan: BatchScanArgs,\n\tcompare_domains: CompareDomainsArgs,\n\tcompare_baseline: CompareBaselineArgs,\n\tgenerate_fix_plan: GenerateFixPlanArgs,\n\tgenerate_spf_record: GenerateSpfArgs,\n\tgenerate_dmarc_record: GenerateDmarcArgs,\n\tgenerate_dkim_config: GenerateDkimConfigArgs,\n\tgenerate_mta_sts_policy: GenerateMtaStsArgs,\n\tget_benchmark: GetBenchmarkArgs,\n\tget_provider_insights: GetProviderInsightsArgs,\n\tassess_spoofability: AssessSpoofabilityArgs,\n\tcheck_resolver_consistency: CheckResolverConsistencyArgs,\n\texplain_finding: ExplainFindingArgs,\n\tvalidate_fix: ValidateFixArgs,\n\tmap_supply_chain: MapSupplyChainArgs,\n\tanalyze_drift: AnalyzeDriftArgs,\n\tgenerate_rollout_plan: GenerateRolloutPlanArgs,\n\tresolve_spf_chain: BaseDomainArgs,\n\tdiscover_subdomains: BaseDomainArgs,\n\tmap_compliance: BaseDomainArgs,\n\tsimulate_attack_paths: BaseDomainArgs,\n};\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { z } from 'zod';\nimport {\n\tBaseDomainArgs,\n\tScanDomainArgs,\n\tBatchScanArgs,\n\tCompareDomainsArgs,\n\tCheckDkimArgs,\n\tCheckResolverConsistencyArgs,\n\tGenerateSpfArgs,\n\tGenerateDmarcArgs,\n\tGenerateDkimConfigArgs,\n\tGenerateMtaStsArgs,\n\tExplainFindingArgs,\n\tCompareBaselineArgs,\n\tGetBenchmarkArgs,\n\tGetProviderInsightsArgs,\n\tValidateFixArgs,\n\tMapSupplyChainArgs,\n\tAnalyzeDriftArgs,\n\tGenerateRolloutPlanArgs,\n\tTOOL_SCHEMA_MAP,\n} from './tool-args';\n\nexport type ToolGroup = 'email_auth' | 'infrastructure' | 'brand_threats' | 'dns_hygiene' | 'intelligence' | 'remediation' | 'meta';\nexport type ToolTier = 'core' | 'protective' | 'hardening';\n\nexport interface McpTool {\n\tname: string;\n\tdescription: string;\n\tinputSchema: {\n\t\ttype: string;\n\t\tproperties: Record<string, unknown>;\n\t\trequired?: string[];\n\t\t[key: string]: unknown;\n\t};\n\tannotations?: {\n\t\ttitle?: string;\n\t\treadOnlyHint?: boolean;\n\t\tdestructiveHint?: boolean;\n\t\tidempotentHint?: boolean;\n\t\topenWorldHint?: boolean;\n\t};\n\t/** Functional group for client-side tool discoverability. Not used in dispatch. */\n\tgroup: ToolGroup;\n\t/** Scoring tier from the three-tier model. Absent for non-scoring tools (meta/intelligence/remediation). */\n\ttier?: ToolTier;\n\t/** True when this tool is included in the scan_domain parallel orchestration. */\n\tscanIncluded: boolean;\n}\n\ninterface ToolDef {\n\tdescription: string;\n\tschema: z.ZodTypeAny;\n\tgroup: ToolGroup;\n\ttier?: ToolTier;\n\tscanIncluded: boolean;\n}\n\n/** DNS/security acronyms that should be uppercased in human-readable tool titles. */\nconst KNOWN_ACRONYMS = new Set(['mx', 'spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta', 'sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'http', 'https', 'dane', 'svcb', 'srv', 'txt', 'doh', 'rpm']);\n\n/** Convert a snake_case tool name to a human-readable title. e.g. \"check_mta_sts\" → \"Check MTA STS\" */\nfunction toolNameToTitle(name: string): string {\n\treturn name\n\t\t.split('_')\n\t\t.map((word) => (KNOWN_ACRONYMS.has(word) ? word.toUpperCase() : word.charAt(0).toUpperCase() + word.slice(1)))\n\t\t.join(' ');\n}\n\n/** Convert a Zod schema to a JSON Schema object suitable for MCP inputSchema. */\nfunction toInputSchema(schema: z.ZodTypeAny): McpTool['inputSchema'] {\n\tconst jsonSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n\tdelete jsonSchema.$schema;\n\t// Clean up additionalProperties: {} (equivalent to not having it, but cleaner)\n\tif (\n\t\tjsonSchema.additionalProperties !== undefined &&\n\t\ttypeof jsonSchema.additionalProperties === 'object' &&\n\t\tjsonSchema.additionalProperties !== null &&\n\t\tObject.keys(jsonSchema.additionalProperties).length === 0\n\t) {\n\t\tdelete jsonSchema.additionalProperties;\n\t}\n\treturn jsonSchema as McpTool['inputSchema'];\n}\n\n/** All 43 MCP tool definitions. */\nconst TOOL_DEFS: Record<string, ToolDef> = {\n\tcheck_mx: {\n\t\tdescription: 'Validate MX records and email provider detection.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_spf: {\n\t\tdescription: 'Validate SPF syntax, policy, and trust surface.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dmarc: {\n\t\tdescription: 'Validate DMARC policy, alignment, and reporting.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dkim: {\n\t\tdescription: 'Probe DKIM selectors and validate key strength.',\n\t\tschema: CheckDkimArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dnssec: {\n\t\tdescription: 'Verify DNSSEC validation and DNSKEY/DS records.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_ssl: {\n\t\tdescription: 'Verify SSL/TLS certificate and HTTPS config.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'core',\n\t\tscanIncluded: true,\n\t},\n\tcheck_mta_sts: {\n\t\tdescription: 'Validate MTA-STS SMTP encryption policy.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_ns: {\n\t\tdescription: 'Analyze NS delegation and provider diversity.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_caa: {\n\t\tdescription: 'Check authorized Certificate Authorities via CAA.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_bimi: {\n\t\tdescription: 'Validate BIMI record and VMC evidence.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_tlsrpt: {\n\t\tdescription: 'Validate TLS-RPT SMTP failure reporting.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_http_security: {\n\t\tdescription: 'Audit HTTP security headers (CSP, COOP, etc.).',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dane: {\n\t\tdescription: 'Verify DANE/TLSA certificate pinning.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: true,\n\t},\n\tcheck_dane_https: {\n\t\tdescription: 'Verify DANE certificate pinning for HTTPS via TLSA records at _443._tcp.{domain}.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_svcb_https: {\n\t\tdescription: 'Validate HTTPS/SVCB records (RFC 9460) for modern transport capability advertisement.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tcheck_lookalikes: {\n\t\tdescription: 'Detect active typosquat/lookalike domains. Standalone.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'protective',\n\t\tscanIncluded: false,\n\t},\n\tcheck_subdomailing: {\n\t\tdescription: 'Detect SubdoMailing risk by analyzing SPF include chain for takeover-vulnerable domains.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'protective',\n\t\tscanIncluded: true,\n\t},\n\tscan_domain: {\n\t\tdescription: 'Full DNS and email security audit. Score, grade, maturity, findings. Start here.',\n\t\tschema: ScanDomainArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tbatch_scan: {\n\t\tdescription: 'Scan up to 10 domains at once. Returns score, grade, and finding counts per domain.',\n\t\tschema: BatchScanArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcompare_domains: {\n\t\tdescription: 'Side-by-side security comparison of 2–5 domains. Shows scores, category gaps, and unique weaknesses.',\n\t\tschema: CompareDomainsArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcompare_baseline: {\n\t\tdescription: 'Compare domain security against a policy baseline.',\n\t\tschema: CompareBaselineArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tcheck_shadow_domains: {\n\t\tdescription: 'Find TLD variants with email auth gaps. Standalone.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'brand_threats',\n\t\ttier: 'protective',\n\t\tscanIncluded: false,\n\t},\n\tcheck_txt_hygiene: {\n\t\tdescription: 'Audit TXT records for stale entries and SaaS exposure.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'dns_hygiene',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_mx_reputation: {\n\t\tdescription: 'Check MX blocklist status and reverse DNS.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'email_auth',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_srv: {\n\t\tdescription: 'Probe SRV records for service footprint.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tcheck_zone_hygiene: {\n\t\tdescription: 'Audit SOA propagation and sensitive subdomains.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'infrastructure',\n\t\ttier: 'hardening',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_fix_plan: {\n\t\tdescription: 'Generate prioritized remediation plan with effort estimates.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_spf_record: {\n\t\tdescription: 'Generate corrected SPF record from detected providers.',\n\t\tschema: GenerateSpfArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_dmarc_record: {\n\t\tdescription: 'Generate DMARC record with configurable policy.',\n\t\tschema: GenerateDmarcArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_dkim_config: {\n\t\tdescription: 'Generate DKIM setup instructions and DNS record.',\n\t\tschema: GenerateDkimConfigArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_mta_sts_policy: {\n\t\tdescription: 'Generate MTA-STS record and policy file.',\n\t\tschema: GenerateMtaStsArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tget_benchmark: {\n\t\tdescription: 'Get score benchmarks: percentiles, mean, top failures.',\n\t\tschema: GetBenchmarkArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tget_provider_insights: {\n\t\tdescription: 'Get provider cohort benchmarks and common issues.',\n\t\tschema: GetProviderInsightsArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tassess_spoofability: {\n\t\tdescription: 'Composite email spoofability score (0-100).',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tcheck_resolver_consistency: {\n\t\tdescription: 'Check DNS consistency across 4 public resolvers.',\n\t\tschema: CheckResolverConsistencyArgs,\n\t\tgroup: 'infrastructure',\n\t\tscanIncluded: false,\n\t},\n\texplain_finding: {\n\t\tdescription: 'Explain a finding with impact and remediation.',\n\t\tschema: ExplainFindingArgs,\n\t\tgroup: 'meta',\n\t\tscanIncluded: false,\n\t},\n\tmap_supply_chain: {\n\t\tdescription: 'Map third-party service dependencies from DNS records. Correlates SPF, NS, TXT verifications, SRV services, and CAA to show who can send as you, control your DNS, and what services are integrated.',\n\t\tschema: MapSupplyChainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tanalyze_drift: {\n\t\tdescription: 'Compare current security posture against a previous baseline. Shows what improved, regressed, or changed.',\n\t\tschema: AnalyzeDriftArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tvalidate_fix: {\n\t\tdescription: 'Re-check a specific control after applying a fix. Confirms whether the finding is resolved.',\n\t\tschema: ValidateFixArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tgenerate_rollout_plan: {\n\t\tdescription: 'Generate a phased DMARC enforcement timeline with exact DNS records per phase.',\n\t\tschema: GenerateRolloutPlanArgs,\n\t\tgroup: 'remediation',\n\t\tscanIncluded: false,\n\t},\n\tresolve_spf_chain: {\n\t\tdescription: 'Recursively resolve the full SPF include chain. Shows lookup count, tree depth, and flags issues like circular includes or exceeding the 10-lookup limit.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tdiscover_subdomains: {\n\t\tdescription: 'Discover subdomains via Certificate Transparency logs. Reveals shadow IT, forgotten services, and unauthorized certificate issuance.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tmap_compliance: {\n\t\tdescription: 'Map scan findings to compliance frameworks: NIST 800-177, PCI DSS 4.0, SOC 2, CIS Controls. Shows pass/fail/partial status per control.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n\tsimulate_attack_paths: {\n\t\tdescription: 'Analyze current DNS posture and enumerate specific attack paths an adversary could exploit, with severity, feasibility, steps, and mitigations.',\n\t\tschema: BaseDomainArgs,\n\t\tgroup: 'intelligence',\n\t\tscanIncluded: false,\n\t},\n};\n\nexport const TOOLS: McpTool[] = Object.entries(TOOL_DEFS).map(([name, def]) => ({\n\tname,\n\tdescription: def.description,\n\tinputSchema: toInputSchema(def.schema),\n\tannotations: {\n\t\ttitle: toolNameToTitle(name),\n\t\treadOnlyHint: true,\n\t\tdestructiveHint: false,\n\t\tidempotentHint: true,\n\t\topenWorldHint: true,\n\t},\n\tgroup: def.group,\n\t...(def.tier !== undefined && { tier: def.tier }),\n\tscanIncluded: def.scanIncluded,\n}));\n\nexport { TOOL_SCHEMA_MAP };\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * BIMI (Brand Indicators for Message Identification) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkBIMI } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check BIMI records for a domain.\n * Validates the presence and configuration of BIMI TXT records,\n * including logo URL format and VMC authority evidence.\n */\nexport async function checkBimi(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkBIMI(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * CAA (Certificate Authority Authorization) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkCAA } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check CAA records for a domain.\n * Validates that CAA records exist and are properly configured.\n */\nexport async function checkCaa(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkCAA(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DKIM (DomainKeys Identified Mail) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n * Retains applyProviderDkimContext for scan_domain post-processing.\n */\n\nimport { checkDKIM, createFinding, buildCheckResult } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\n/**\n * Email providers with high confidence of default DKIM signing.\n */\nconst HIGH_CONFIDENCE_DKIM_PROVIDERS = new Set([\n\t'amazon ses',\n\t'sendgrid',\n\t'mailgun',\n\t'postmark',\n\t'google workspace',\n\t'microsoft 365',\n]);\n\n/**\n * Email providers that typically sign with DKIM but vary by configuration.\n */\nconst MEDIUM_CONFIDENCE_DKIM_PROVIDERS = new Set(['proofpoint', 'mimecast']);\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DKIM records for a domain.\n * Probes common selectors at <selector>._domainkey.<domain>.\n * Optionally accepts a specific selector to check.\n */\nexport async function checkDkim(domain: string, selector?: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDKIM(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000, selector },\n\t) as Promise<CheckResult>;\n}\n\n/**\n * Apply provider-informed context to DKIM results.\n * Called as a post-processing step in scan_domain after MX-based provider detection completes.\n * When a known DKIM-signing provider is detected, downgrades the \"No DKIM records found\"\n * finding from HIGH to MEDIUM since the provider likely signs outbound mail by default.\n */\nexport function applyProviderDkimContext(dkimResult: CheckResult, provider: string): CheckResult {\n\tconst normalizedProvider = provider.toLowerCase();\n\tconst notFoundIdx = dkimResult.findings.findIndex(\n\t\t(f) => /No DKIM records found/i.test(f.title) && f.severity === 'high',\n\t);\n\tif (notFoundIdx === -1) return dkimResult;\n\n\tconst selectorsChecked = (dkimResult.findings[notFoundIdx].metadata?.selectorsChecked as string[]) ?? [];\n\tconst newFindings = [...dkimResult.findings];\n\n\tif (HIGH_CONFIDENCE_DKIM_PROVIDERS.has(normalizedProvider)) {\n\t\tnewFindings[notFoundIdx] = createFinding(\n\t\t\t'dkim',\n\t\t\t'DKIM selector not discovered',\n\t\t\t'medium',\n\t\t\t`No DKIM selectors were found among the tested set, but ${provider} is detected as the email provider and signs outbound mail by default. DKIM is likely present with a custom selector.`,\n\t\t\t{\n\t\t\t\tconfidence: 'heuristic',\n\t\t\t\tdetectionMethod: 'provider-implied',\n\t\t\t\tprovider: normalizedProvider,\n\t\t\t\tselectorsChecked,\n\t\t\t},\n\t\t);\n\t} else if (MEDIUM_CONFIDENCE_DKIM_PROVIDERS.has(normalizedProvider)) {\n\t\tnewFindings[notFoundIdx] = createFinding(\n\t\t\t'dkim',\n\t\t\t'DKIM selector not discovered',\n\t\t\t'medium',\n\t\t\t`No DKIM selectors were found among the tested set. ${provider} is detected as the email provider and typically signs outbound mail.`,\n\t\t\t{\n\t\t\t\tconfidence: 'heuristic',\n\t\t\t\tdetectionMethod: 'provider-implied',\n\t\t\t\tprovider: normalizedProvider,\n\t\t\t\tselectorsChecked,\n\t\t\t},\n\t\t);\n\t\tnewFindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'dkim',\n\t\t\t\t'DKIM provider signing unverified',\n\t\t\t\t'low',\n\t\t\t\t`${provider} signing policy varies by configuration — DKIM presence cannot be confirmed without selector discovery.`,\n\t\t\t\t{ confidence: 'heuristic' },\n\t\t\t),\n\t\t);\n\t}\n\n\treturn buildCheckResult('dkim', newFindings) as CheckResult;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DMARC (Domain-based Message Authentication, Reporting & Conformance) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDMARC } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nexport { parseDmarcTags } from '@blackveil/dns-checks';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DMARC records for a domain.\n * Queries _dmarc.<domain> TXT records and validates policy configuration.\n */\nexport async function checkDmarc(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDMARC(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DNSSEC (DNS Security Extensions) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDNSSEC } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { buildCheckResult, createFinding } from '../lib/scoring';\nimport type { CheckResult } from '../lib/scoring';\n\nexport { parseDnskeyAlgorithm, parseDsRecord } from '@blackveil/dns-checks';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DNSSEC configuration for a domain.\n * Verifies the AD (Authenticated Data) flag, checks for DNSKEY/DS records,\n * and audits algorithm and digest type security.\n * Augments results with dnssecSource metadata: 'domain_configured' or 'tld_inherited'.\n */\nexport async function checkDnssec(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\tconst baseResult = await checkDNSSEC(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as CheckResult;\n\n\t// Skip augmentation when DNSSEC is definitively absent, failed, or misconfigured at the domain level.\n\t// 'DNSSEC chain of trust incomplete' means the domain has DNSKEY but no DS — it is domain-operator-configured\n\t// (just broken), not TLD-inherited. 'DNSSEC validation failing' means records exist but fail verification.\n\tconst dnssecAbsent =\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC not enabled') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC check failed') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC chain of trust incomplete') ||\n\t\tbaseResult.findings.some((f) => f.title === 'DNSSEC validation failing');\n\tif (dnssecAbsent) {\n\t\treturn baseResult;\n\t}\n\n\t// Detect whether the domain has its own DNSKEY/DS (domain_configured) or inherits from TLD\n\tconst [dnskeyResult, dsResult] = await Promise.allSettled([\n\t\tqueryDnsRecords(domain, 'DNSKEY', dnsOptions),\n\t\tqueryDnsRecords(domain, 'DS', dnsOptions),\n\t]);\n\n\tconst hasDnskey = dnskeyResult.status === 'fulfilled' && dnskeyResult.value.length > 0;\n\tconst hasDs = dsResult.status === 'fulfilled' && dsResult.value.length > 0;\n\tconst dnssecSource = hasDnskey && hasDs ? 'domain_configured' : 'tld_inherited';\n\n\tif (dnssecSource === 'tld_inherited') {\n\t\tconst inheritedFinding = createFinding(\n\t\t\t'dnssec',\n\t\t\t'DNSSEC inherited from TLD',\n\t\t\t'info',\n\t\t\t`DNSSEC validation passes but ${domain} does not have its own DNSKEY or DS records. DNSSEC protection is inherited from the TLD registry, not configured by the domain owner.`,\n\t\t\t{ dnssecSource: 'tld_inherited' },\n\t\t);\n\t\treturn buildCheckResult('dnssec', [...baseResult.findings, inheritedFinding]);\n\t}\n\n\t// domain_configured — tag the first non-info finding with the source, or add a carrier finding\n\tif (baseResult.findings.length > 0) {\n\t\tconst [first, ...rest] = baseResult.findings;\n\t\tconst tagged = { ...first, metadata: { ...(first.metadata ?? {}), dnssecSource: 'domain_configured' } };\n\t\treturn buildCheckResult('dnssec', [tagged, ...rest]);\n\t}\n\n\tconst configuredFinding = createFinding(\n\t\t'dnssec',\n\t\t'DNSSEC configured by domain owner',\n\t\t'info',\n\t\t`${domain} has DNSKEY and DS records — DNSSEC is explicitly configured by the domain owner.`,\n\t\t{ dnssecSource: 'domain_configured' },\n\t);\n\treturn buildCheckResult('dnssec', [configuredFinding]);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Lookalike domain generation utilities.\n * Generates typosquat/lookalike domain permutations using multiple strategies:\n * adjacent key swaps, character omission, character duplication, dot insertion,\n * common TLD swaps, and homoglyph substitution.\n */\n\nimport { LABEL_REGEX, MAX_DOMAIN_LENGTH, MAX_LABEL_LENGTH } from '../lib/config';\n\n/** QWERTY keyboard adjacency map for typosquat detection */\nconst QWERTY_ADJACENT: Record<string, string[]> = {\n\tq: ['w', 'a'],\n\tw: ['q', 'e', 's', 'a'],\n\te: ['w', 'r', 'd', 's'],\n\tr: ['e', 't', 'f', 'd'],\n\tt: ['r', 'y', 'g', 'f'],\n\ty: ['t', 'u', 'h', 'g'],\n\tu: ['y', 'i', 'j', 'h'],\n\ti: ['u', 'o', 'k', 'j'],\n\to: ['i', 'p', 'l', 'k'],\n\tp: ['o', 'l'],\n\ta: ['q', 'w', 's', 'z'],\n\ts: ['a', 'w', 'e', 'd', 'z', 'x'],\n\td: ['s', 'e', 'r', 'f', 'x', 'c'],\n\tf: ['d', 'r', 't', 'g', 'c', 'v'],\n\tg: ['f', 't', 'y', 'h', 'v', 'b'],\n\th: ['g', 'y', 'u', 'j', 'b', 'n'],\n\tj: ['h', 'u', 'i', 'k', 'n', 'm'],\n\tk: ['j', 'i', 'o', 'l', 'm'],\n\tl: ['k', 'o', 'p'],\n\tz: ['a', 's', 'x'],\n\tx: ['z', 's', 'd', 'c'],\n\tc: ['x', 'd', 'f', 'v'],\n\tv: ['c', 'f', 'g', 'b'],\n\tb: ['v', 'g', 'h', 'n'],\n\tn: ['b', 'h', 'j', 'm'],\n\tm: ['n', 'j', 'k'],\n};\n\n/** Homoglyph substitution pairs (one substitution at a time) */\nconst HOMOGLYPHS: Array<[string, string]> = [\n\t['o', '0'],\n\t['0', 'o'],\n\t['l', '1'],\n\t['1', 'l'],\n\t['i', '1'],\n\t['1', 'i'],\n\t['l', 'i'],\n\t['i', 'l'],\n\t['rn', 'm'],\n\t['m', 'rn'],\n\t['vv', 'w'],\n\t['w', 'vv'],\n];\n\n/** Common TLD swap pairs */\nconst TLD_SWAPS: Array<[string, string]> = [\n\t['.com', '.co'],\n\t['.com', '.net'],\n\t['.com', '.org'],\n\t['.com', '.io'],\n\t['.co.nz', '.com'],\n\t['.com.au', '.com'],\n];\n\n/** Maximum number of permutations to return */\nconst MAX_PERMUTATIONS = 50;\n\n/**\n * Split a domain into base (before TLD) and TLD parts.\n * Handles multi-part TLDs like .co.nz and .com.au.\n */\nfunction splitDomainTld(domain: string): { base: string; tld: string } {\n\tconst multiPartTlds = ['.co.nz', '.com.au', '.co.uk', '.org.uk', '.net.au', '.org.au'];\n\tfor (const multiTld of multiPartTlds) {\n\t\tif (domain.endsWith(multiTld)) {\n\t\t\treturn { base: domain.slice(0, -multiTld.length), tld: multiTld };\n\t\t}\n\t}\n\tconst lastDot = domain.lastIndexOf('.');\n\tif (lastDot === -1) return { base: domain, tld: '' };\n\treturn { base: domain.slice(0, lastDot), tld: domain.slice(lastDot) };\n}\n\n/**\n * Check whether a domain string is structurally valid.\n * Labels must be 1-63 chars, alphanumeric + hyphens, total <= 253 chars.\n */\nfunction isDomainValid(domain: string): boolean {\n\tif (domain.length > MAX_DOMAIN_LENGTH) return false;\n\tconst labels = domain.split('.');\n\tif (labels.length < 2) return false;\n\tfor (const label of labels) {\n\t\tif (label.length === 0 || label.length > MAX_LABEL_LENGTH) return false;\n\t\tif (!LABEL_REGEX.test(label)) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Generate lookalike/typosquat domain permutations for a given domain.\n * Applies six strategies: adjacent key swaps, character omission, character duplication,\n * dot insertion, common TLD swaps, and homoglyph substitution.\n *\n * Returns up to 50 unique, valid, alphabetically sorted permutations.\n */\nexport function generateLookalikes(domain: string): string[] {\n\tconst normalizedDomain = domain.toLowerCase();\n\tconst { base, tld } = splitDomainTld(normalizedDomain);\n\tconst candidates = new Set<string>();\n\n\t// 1. Adjacent key swaps — swap each char in base with QWERTY adjacent keys\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst ch = base[i];\n\t\tconst adjacent = QWERTY_ADJACENT[ch];\n\t\tif (adjacent) {\n\t\t\tfor (const adj of adjacent) {\n\t\t\t\tconst permuted = base.slice(0, i) + adj + base.slice(i + 1);\n\t\t\t\tcandidates.add(permuted + tld);\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Character omission — remove one char at a time from base\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst permuted = base.slice(0, i) + base.slice(i + 1);\n\t\tif (permuted.length > 0) {\n\t\t\tcandidates.add(permuted + tld);\n\t\t}\n\t}\n\n\t// 3. Character duplication — double one char at a time in base\n\tfor (let i = 0; i < base.length; i++) {\n\t\tconst permuted = base.slice(0, i) + base[i] + base[i] + base.slice(i + 1);\n\t\tcandidates.add(permuted + tld);\n\t}\n\n\t// 4. Dot insertion — insert dots between chars in base (both parts must be >= 2 chars)\n\tfor (let i = 1; i < base.length; i++) {\n\t\tconst left = base.slice(0, i);\n\t\tconst right = base.slice(i);\n\t\tif (left.length >= 2 && right.length >= 2) {\n\t\t\tcandidates.add(left + '.' + right + tld);\n\t\t}\n\t}\n\n\t// 5. Common TLD swaps — swap to different TLD if original matches\n\tfor (const [fromTld, toTld] of TLD_SWAPS) {\n\t\tif (tld === fromTld) {\n\t\t\tcandidates.add(base + toTld);\n\t\t} else if (tld === toTld) {\n\t\t\tcandidates.add(base + fromTld);\n\t\t}\n\t}\n\n\t// 6. Homoglyph substitution — one substitution at a time in base\n\tfor (const [from, to] of HOMOGLYPHS) {\n\t\tlet searchIdx = 0;\n\t\twhile (searchIdx <= base.length - from.length) {\n\t\t\tconst idx = base.indexOf(from, searchIdx);\n\t\t\tif (idx === -1) break;\n\t\t\tconst permuted = base.slice(0, idx) + to + base.slice(idx + from.length);\n\t\t\tcandidates.add(permuted + tld);\n\t\t\tsearchIdx = idx + 1;\n\t\t}\n\t}\n\n\t// Filter, dedup, and cap\n\tconst results = Array.from(candidates)\n\t\t.filter((candidate) => candidate !== normalizedDomain && isDomainValid(candidate))\n\t\t.sort();\n\n\treturn results.slice(0, MAX_PERMUTATIONS);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Lookalike domain detection tool.\n * Generates typosquat/lookalike domain permutations and checks for\n * active DNS registrations and mail infrastructure.\n * Standalone check — not included in scan_domain due to query volume.\n */\n\nimport { queryDnsRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult, Finding } from '../lib/scoring';\nimport { buildCheckResult, createFinding } from '../lib/scoring';\nimport { generateLookalikes } from './lookalike-analysis';\n\n/** Default and minimum batch sizes for adaptive batching */\nexport const INITIAL_BATCH_SIZE = 10;\nexport const MIN_BATCH_SIZE = 3;\nexport const BACKOFF_DELAY_MS = 500;\nexport const FAILURE_THRESHOLD = 2;\n\n/** Maximum wall-clock time for the entire lookalike check (ms). */\nconst LOOKALIKE_TIMEOUT_MS = 20_000;\n\n/** Canary label used for wildcard detection on parent domains */\nexport const WILDCARD_CANARY_LABEL = '_bv-wc-probe';\n\n/** Lean DNS options for Phase 1 existence checks — fast, no retries, no secondary confirmation. */\nexport const PHASE1_DNS_OPTS: QueryDnsOptions = {\n\ttimeoutMs: 2000,\n\tretries: 0,\n\tskipSecondaryConfirmation: true,\n};\n\ninterface LookalikeResult {\n\tdomain: string;\n\thasA: boolean;\n\thasMX: boolean;\n}\n\n/** Minimum number of NS records that must overlap to consider domains as sharing nameservers. */\nconst SHARED_NS_THRESHOLD = 1;\n\n/**\n * Check whether an MX record represents real mail infrastructure.\n * RFC 7505 null MX (\"0 .\") explicitly means \"no mail accepted\" and must be excluded.\n */\nfunction isRealMxRecord(data: string): boolean {\n\t// Null MX: priority 0, exchange \".\" — RFC 7505\n\tconst trimmed = data.trim();\n\treturn trimmed !== '0 .' && trimmed !== '0\\t.';\n}\n\n/**\n * Check a single lookalike domain for DNS and MX records.\n * Filters out null MX records (RFC 7505) to avoid false positives.\n */\nasync function probeLookalike(domain: string): Promise<LookalikeResult> {\n\tconst [aRecords, mxRecords] = await Promise.allSettled([\n\t\tqueryDnsRecords(domain, 'A'),\n\t\tqueryDnsRecords(domain, 'MX'),\n\t]);\n\n\tconst realMxRecords =\n\t\tmxRecords.status === 'fulfilled' ? mxRecords.value.filter(isRealMxRecord) : [];\n\n\treturn {\n\t\tdomain,\n\t\thasA: aRecords.status === 'fulfilled' && aRecords.value.length > 0,\n\t\thasMX: realMxRecords.length > 0,\n\t};\n}\n\n/**\n * Count the number of labels (dot-separated segments) in a domain.\n */\nfunction labelCount(domain: string): number {\n\treturn domain.split('.').length;\n}\n\n/**\n * Extract the parent domain from a dot-insertion permutation.\n * E.g., \"blackve.ilsecurity.com\" → \"ilsecurity.com\"\n */\nfunction getParentDomain(domain: string): string {\n\tconst parts = domain.split('.');\n\treturn parts.slice(1).join('.');\n}\n\n/**\n * Detect wildcard DNS on a set of parent domains by probing a canary subdomain.\n * Returns a Set of parent domains that have wildcard A records.\n */\nasync function detectWildcardParents(parentDomains: string[]): Promise<Set<string>> {\n\tconst wildcardParents = new Set<string>();\n\tconst probes = parentDomains.map(async (parent) => {\n\t\ttry {\n\t\t\tconst canary = `${WILDCARD_CANARY_LABEL}.${parent}`;\n\t\t\tconst records = await queryDnsRecords(canary, 'A');\n\t\t\tif (records.length > 0) {\n\t\t\t\twildcardParents.add(parent);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Query failed — not a wildcard\n\t\t}\n\t});\n\tawait Promise.allSettled(probes);\n\treturn wildcardParents;\n}\n\n/**\n * Phase 1: Fast NS existence check for all domains in parallel.\n * Returns only domains that have NS records (i.e., are registered),\n * along with their normalized NS record data for ownership comparison.\n */\nasync function filterByNsExistence(domains: string[]): Promise<{ registered: string[]; nsMap: Map<string, Set<string>> }> {\n\tconst nsMap = new Map<string, Set<string>>();\n\tconst results = await Promise.allSettled(\n\t\tdomains.map(async (domain) => {\n\t\t\tconst ns = await queryDnsRecords(domain, 'NS', PHASE1_DNS_OPTS);\n\t\t\tif (ns.length > 0) {\n\t\t\t\tnsMap.set(domain, normalizeNsSet(ns));\n\t\t\t}\n\t\t\treturn { domain, hasNs: ns.length > 0 };\n\t\t}),\n\t);\n\tconst registered = results\n\t\t.filter(\n\t\t\t(r): r is PromiseFulfilledResult<{ domain: string; hasNs: boolean }> =>\n\t\t\t\tr.status === 'fulfilled' && r.value.hasNs,\n\t\t)\n\t\t.map((r) => r.value.domain);\n\treturn { registered, nsMap };\n}\n\n/**\n * Normalize a set of NS record values for comparison.\n * Strips trailing dots, lowercases, and returns a Set.\n */\nfunction normalizeNsSet(nsRecords: string[]): Set<string> {\n\treturn new Set(nsRecords.map((ns) => ns.replace(/\\.$/, '').toLowerCase()));\n}\n\n/**\n * Check whether two NS sets share at least SHARED_NS_THRESHOLD nameservers.\n * Shared nameservers are a strong signal that both domains are controlled by the same entity.\n */\nfunction sharesNameservers(primaryNs: Set<string>, lookalikeNs: Set<string>): boolean {\n\tlet overlap = 0;\n\tfor (const ns of lookalikeNs) {\n\t\tif (primaryNs.has(ns)) {\n\t\t\toverlap++;\n\t\t\tif (overlap >= SHARED_NS_THRESHOLD) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Query NS records for the primary domain to use for ownership comparison.\n * Returns an empty set if the query fails.\n */\nasync function queryPrimaryNs(domain: string): Promise<Set<string>> {\n\ttry {\n\t\tconst ns = await queryDnsRecords(domain, 'NS', PHASE1_DNS_OPTS);\n\t\treturn normalizeNsSet(ns);\n\t} catch {\n\t\treturn new Set<string>();\n\t}\n}\n\n/**\n * Run permutation probes with adaptive batch sizing and backoff.\n * Starts at INITIAL_BATCH_SIZE, halves on repeated failures (floor at MIN_BATCH_SIZE),\n * recovers on clean batches.\n */\nasync function probeWithAdaptiveBatching(\n\tpermutations: string[],\n): Promise<PromiseSettledResult<LookalikeResult>[]> {\n\tconst allResults: PromiseSettledResult<LookalikeResult>[] = [];\n\tlet batchSize = INITIAL_BATCH_SIZE;\n\tlet delayMs = 0;\n\n\tfor (let i = 0; i < permutations.length; i += batchSize) {\n\t\tif (delayMs > 0) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, delayMs));\n\t\t}\n\n\t\tconst batch = permutations.slice(i, i + batchSize);\n\t\tconst batchResults = await Promise.allSettled(batch.map((d) => probeLookalike(d)));\n\t\tallResults.push(...batchResults);\n\n\t\t// Count failures in this batch\n\t\tconst failures = batchResults.filter((r) => r.status === 'rejected').length;\n\t\tif (failures > FAILURE_THRESHOLD) {\n\t\t\t// Back off: halve batch size (floor to MIN_BATCH_SIZE) and add delay\n\t\t\tbatchSize = Math.max(MIN_BATCH_SIZE, Math.floor(batchSize / 2));\n\t\t\tdelayMs = BACKOFF_DELAY_MS;\n\t\t} else if (delayMs > 0 && failures === 0) {\n\t\t\t// Recover: if a clean batch after backoff, try increasing again\n\t\t\tbatchSize = Math.min(INITIAL_BATCH_SIZE, batchSize + 2);\n\t\t\tdelayMs = 0;\n\t\t}\n\t}\n\n\treturn allResults;\n}\n\n/**\n * Detect registered lookalike/typosquat domains with DNS or mail infrastructure.\n * Generates domain permutations and checks for active registrations using adaptive batching.\n * Filters out false positives from wildcard DNS on parent domains and null MX records.\n */\nexport async function checkLookalikes(domain: string): Promise<CheckResult> {\n\treturn Promise.race([\n\t\tcheckLookalikesCore(domain),\n\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('Lookalike check timed out')), LOOKALIKE_TIMEOUT_MS)),\n\t]).catch(() => {\n\t\treturn buildCheckResult('lookalikes', [\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'Lookalike check incomplete',\n\t\t\t\t'info',\n\t\t\t\t'Lookalike check did not complete. This check generates many DNS queries — try again shortly, as partial results are cached.',\n\t\t\t),\n\t\t]);\n\t});\n}\n\nasync function checkLookalikesCore(domain: string): Promise<CheckResult> {\n\tconst findings: Finding[] = [];\n\tconst permutations = generateLookalikes(domain);\n\n\tif (permutations.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`No lookalike domain permutations could be generated for ${domain}.`,\n\t\t\t),\n\t\t);\n\t\treturn buildCheckResult('lookalikes', findings);\n\t}\n\n\t// Identify dot-insertion permutations (they have more labels than the original domain)\n\tconst originalLabelCount = labelCount(domain);\n\tconst dotInsertionParents = new Map<string, string[]>(); // parent → [permutations]\n\tconst nonDotInsertionPerms: string[] = [];\n\n\tfor (const perm of permutations) {\n\t\tif (labelCount(perm) > originalLabelCount) {\n\t\t\tconst parent = getParentDomain(perm);\n\t\t\tconst existing = dotInsertionParents.get(parent);\n\t\t\tif (existing) {\n\t\t\t\texisting.push(perm);\n\t\t\t} else {\n\t\t\t\tdotInsertionParents.set(parent, [perm]);\n\t\t\t}\n\t\t} else {\n\t\t\tnonDotInsertionPerms.push(perm);\n\t\t}\n\t}\n\n\t// Detect wildcard DNS on parent domains of dot-insertion permutations\n\tconst wildcardParents = dotInsertionParents.size > 0\n\t\t? await detectWildcardParents([...dotInsertionParents.keys()])\n\t\t: new Set<string>();\n\n\t// Filter out permutations whose parent has wildcard DNS\n\tconst filteredDotInsertionPerms: string[] = [];\n\tfor (const [parent, perms] of dotInsertionParents) {\n\t\tif (!wildcardParents.has(parent)) {\n\t\t\tfilteredDotInsertionPerms.push(...perms);\n\t\t}\n\t}\n\n\tconst permsToProbe = [...nonDotInsertionPerms, ...filteredDotInsertionPerms];\n\n\t// Phase 1: Fast NS existence check — filter out unregistered domains\n\t// Also query the primary domain's NS for ownership comparison\n\tconst [nsResult, primaryNs] = await Promise.all([\n\t\tfilterByNsExistence(permsToProbe),\n\t\tqueryPrimaryNs(domain),\n\t]);\n\tconst { registered: registeredPerms, nsMap: lookalikeNsMap } = nsResult;\n\n\tif (registeredPerms.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`Checked ${permutations.length} domain permutations of ${domain}. No active registrations detected.`,\n\t\t\t),\n\t\t);\n\t\treturn buildCheckResult('lookalikes', findings);\n\t}\n\n\t// Phase 2: Detail probe only registered domains\n\tconst probeResults = await probeWithAdaptiveBatching(registeredPerms);\n\tconst results: LookalikeResult[] = [];\n\tfor (const result of probeResults) {\n\t\tif (result.status === 'fulfilled') {\n\t\t\tresults.push(result.value);\n\t\t}\n\t}\n\n\t// Classify results — check for shared nameservers with primary domain to detect defensive registrations\n\tlet highCount = 0;\n\tfor (const result of results) {\n\t\tconst lookalikeNs = lookalikeNsMap.get(result.domain);\n\t\tconst sameOwner = primaryNs.size > 0 && lookalikeNs !== undefined && sharesNameservers(primaryNs, lookalikeNs);\n\n\t\tif (sameOwner) {\n\t\t\t// Shared nameservers — likely a defensive registration by the same entity\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain likely owned by same entity: ${result.domain}`,\n\t\t\t\t\t'info',\n\t\t\t\t\t`The domain ${result.domain} shares nameservers with ${domain}, indicating it is likely a defensive registration by the same owner.${result.hasMX ? ' Has active mail infrastructure.' : ''}${result.hasA ? ' Has web presence.' : ''}`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX, sharedNs: true },\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (result.hasMX) {\n\t\t\thighCount++;\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain with mail infrastructure: ${result.domain}`,\n\t\t\t\t\t'high',\n\t\t\t\t\t`The domain ${result.domain} is registered with active mail servers (MX records), which could be used for phishing or email spoofing targeting ${domain}.`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX },\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (result.hasA) {\n\t\t\tfindings.push(\n\t\t\t\tcreateFinding(\n\t\t\t\t\t'lookalikes',\n\t\t\t\t\t`Lookalike domain registered: ${result.domain}`,\n\t\t\t\t\t'medium',\n\t\t\t\t\t`The domain ${result.domain} is registered (has web presence) but no mail infrastructure detected. It could still be used for phishing websites targeting ${domain}.`,\n\t\t\t\t\t{ lookalikeDomain: result.domain, hasA: result.hasA, hasMX: result.hasMX },\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Summary finding for high-severity lookalikes\n\tif (highCount > 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t`${highCount} lookalike domain${highCount > 1 ? 's' : ''} with mail capability detected`,\n\t\t\t\t'high',\n\t\t\t\t`${highCount} lookalike domain${highCount > 1 ? 's' : ''} of ${domain} ${highCount > 1 ? 'have' : 'has'} active mail infrastructure, presenting a phishing risk. Consider monitoring these domains and implementing DMARC with p=reject to protect your brand.`,\n\t\t\t\t{ lookalikeDomainCount: highCount },\n\t\t\t),\n\t\t);\n\t}\n\n\t// If no active lookalikes found\n\tif (findings.length === 0) {\n\t\tfindings.push(\n\t\t\tcreateFinding(\n\t\t\t\t'lookalikes',\n\t\t\t\t'No active lookalike domains detected',\n\t\t\t\t'info',\n\t\t\t\t`Checked ${permutations.length} domain permutations of ${domain}. No active registrations with DNS or mail infrastructure detected.`,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn buildCheckResult('lookalikes', findings);\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * MTA-STS (Mail Transfer Agent Strict Transport Security) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkMTASTS } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check MTA-STS configuration for a domain.\n * Queries _mta-sts.<domain> TXT records and optionally fetches the policy file.\n */\nexport async function checkMtaSts(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkMTASTS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? HTTPS_TIMEOUT_MS, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nexport interface ProviderSignature {\n\tname: string;\n\tdomains: string[];\n\tselectorHints?: string[];\n}\n\nexport interface ProviderSignaturePayload {\n\tversion?: string;\n\tinbound?: ProviderSignature[];\n\toutbound?: ProviderSignature[];\n}\n\nexport interface ProviderSourceResult {\n\tversion: string;\n\tsource: 'runtime' | 'stale' | 'built-in';\n\tfetchedAt: string;\n\tdegraded: boolean;\n\tinbound: ProviderSignature[];\n\toutbound: ProviderSignature[];\n}\n\nexport interface LoadProviderSignaturesOptions {\n\tsourceUrl?: string;\n\tallowedHosts?: string[];\n\texpectedSha256?: string;\n\ttimeoutMs?: number;\n\tretries?: number;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 2500;\nexport const DEFAULT_RETRIES = 1;\nexport const RUNTIME_SIGNATURE_CACHE_TTL_MS = 5 * 60 * 1000;\n\nexport const BUILT_IN_SIGNATURES: ProviderSignaturePayload = {\n\tversion: 'built-in-2026-03-04',\n\tinbound: [\n\t\t{ name: 'Google Workspace', domains: ['google.com', 'googlemail.com'], selectorHints: ['google'] },\n\t\t{ name: 'Microsoft 365', domains: ['outlook.com', 'protection.outlook.com'], selectorHints: ['selector1', 'selector2'] },\n\t\t{ name: 'Proofpoint', domains: ['pphosted.com'] },\n\t\t{ name: 'Mimecast', domains: ['mimecast.com'], selectorHints: ['mimecast'] },\n\t\t{ name: 'Mailgun', domains: ['mailgun.org'] },\n\t\t{ name: 'SendGrid', domains: ['sendgrid.net'] },\n\t\t{ name: 'Amazon SES', domains: ['amazonses.com'] },\n\t],\n\toutbound: [],\n};\n\nexport function normalizeSha256(value: string): string {\n\treturn value.trim().toLowerCase().replace(/^sha256:/, '');\n}\n\nexport function normalizeAllowedHosts(input: string[] | undefined): string[] {\n\tif (!Array.isArray(input)) return [];\n\treturn input.map((host) => host.trim().toLowerCase()).filter((host) => host.length > 0);\n}\n\nexport function validateRuntimeSourceUrl(sourceUrl: string, allowedHosts: string[]): URL {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(sourceUrl);\n\t} catch {\n\t\tthrow new Error('Invalid provider signature source URL');\n\t}\n\n\tif (url.protocol !== 'https:') {\n\t\tthrow new Error('Invalid provider signature source URL: HTTPS is required');\n\t}\n\n\tif (allowedHosts.length > 0 && !allowedHosts.includes(url.hostname.toLowerCase())) {\n\t\tthrow new Error('Invalid provider signature source URL: host is not allowlisted');\n\t}\n\n\treturn url;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n\tconst digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));\n\treturn Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction normalizeDomain(value: string): string {\n\treturn value.trim().toLowerCase().replace(/\\.$/, '');\n}\n\nfunction normalizeProviderSignatures(input: ProviderSignature[] | undefined): ProviderSignature[] {\n\tif (!Array.isArray(input)) return [];\n\n\treturn input\n\t\t.map((provider) => {\n\t\t\tconst name = typeof provider?.name === 'string' ? provider.name.trim() : '';\n\t\t\tconst domains = Array.isArray(provider?.domains)\n\t\t\t\t? provider.domains.map((domain) => normalizeDomain(String(domain))).filter((domain) => domain.length > 0)\n\t\t\t\t: [];\n\t\t\tconst selectorHints = Array.isArray(provider?.selectorHints)\n\t\t\t\t? provider.selectorHints.map((selector) => String(selector).trim().toLowerCase()).filter((selector) => selector.length > 0)\n\t\t\t\t: [];\n\t\t\treturn { name, domains, ...(selectorHints.length > 0 ? { selectorHints } : {}) };\n\t\t})\n\t\t.filter((provider) => provider.name.length > 0 && provider.domains.length > 0);\n}\n\nexport function buildResult(\n\tpayload: ProviderSignaturePayload,\n\tsource: ProviderSourceResult['source'],\n\tdegraded: boolean,\n): ProviderSourceResult {\n\tconst inbound = normalizeProviderSignatures(payload.inbound);\n\tconst outbound = normalizeProviderSignatures(payload.outbound);\n\n\treturn {\n\t\tversion: payload.version?.trim() || BUILT_IN_SIGNATURES.version || 'unknown',\n\t\tsource,\n\t\tfetchedAt: new Date().toISOString(),\n\t\tdegraded,\n\t\tinbound,\n\t\toutbound,\n\t};\n}\n\nexport function isValidSignaturePayload(payload: unknown): payload is ProviderSignaturePayload {\n\tif (!payload || typeof payload !== 'object') return false;\n\tconst record = payload as Record<string, unknown>; // typeof payload === 'object' is checked above\n\tif (record.version !== undefined && typeof record.version !== 'string') return false;\n\tif (record.inbound !== undefined && !Array.isArray(record.inbound)) return false;\n\tif (record.outbound !== undefined && !Array.isArray(record.outbound)) return false;\n\treturn true;\n}\n\nexport async function fetchProviderPayload(\n\turl: string,\n\ttimeoutMs: number,\n\tretries: number,\n\texpectedSha256?: string,\n): Promise<ProviderSignaturePayload | null> {\n\tfor (let attempt = 0; attempt <= retries; attempt++) {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { Accept: 'application/json' },\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tredirect: 'manual',\n\t\t\t});\n\t\t\tif (response.status >= 300 && response.status < 400) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!response.ok) {\n\t\t\t\tif (attempt < retries && response.status >= 500) continue;\n\t\t\t\tthrow new Error(`Provider signature source returned HTTP ${response.status}`);\n\t\t\t}\n\n\t\t\tconst MAX_BODY_BYTES = 1_048_576; // 1 MB — provider signature JSON from pinned source\n\t\t\tconst contentLength = parseInt(response.headers?.get('content-length') ?? '0', 10);\n\t\t\tif (contentLength > MAX_BODY_BYTES) {\n\t\t\t\tthrow new Error(`Provider signature source exceeds ${MAX_BODY_BYTES} bytes (Content-Length: ${contentLength})`);\n\t\t\t}\n\t\t\tconst rawPayload = await response.text();\n\t\t\tif (rawPayload.length > MAX_BODY_BYTES) {\n\t\t\t\tthrow new Error(`Provider signature source exceeds ${MAX_BODY_BYTES} bytes`);\n\t\t\t}\n\t\t\tif (!expectedSha256) {\n\t\t\t\tthrow new Error('Provider signature source requires a pinned SHA-256 digest');\n\t\t\t}\n\n\t\t\tconst digest = await sha256Hex(rawPayload);\n\t\t\tif (digest !== normalizeSha256(expectedSha256)) {\n\t\t\t\tthrow new Error('Provider signature source failed SHA-256 verification');\n\t\t\t}\n\n\t\t\tconst payload = JSON.parse(rawPayload) as unknown;\n\t\t\tif (!isValidSignaturePayload(payload)) {\n\t\t\t\tthrow new Error('Provider signature source returned an invalid payload shape');\n\t\t\t}\n\n\t\t\treturn payload;\n\t\t} catch (error) {\n\t\t\tif (attempt < retries) continue;\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new Error(`Provider signature source timed out after ${timeoutMs}ms`);\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\tthrow new Error('Failed to load provider signatures');\n}","// SPDX-License-Identifier: BUSL-1.1\n\nimport {\n\tBUILT_IN_SIGNATURES,\n\tbuildResult,\n\tDEFAULT_RETRIES,\n\tDEFAULT_TIMEOUT_MS,\n\tfetchProviderPayload,\n\ttype LoadProviderSignaturesOptions,\n\tnormalizeAllowedHosts,\n\ttype ProviderSignature,\n\ttype ProviderSourceResult,\n\tRUNTIME_SIGNATURE_CACHE_TTL_MS,\n\tvalidateRuntimeSourceUrl,\n} from './provider-signature-source';\n\ninterface ProviderMatchEvidence {\n\tprovider: string;\n\tmatches: string[];\n}\n\nlet lastKnownGood: ProviderSourceResult | null = null;\nlet runtimeSignatureCache: {\n\tsourceUrl: string;\n\tresult: ProviderSourceResult;\n\texpiresAt: number;\n} | null = null;\n\nfunction normalizeDomain(value: string): string {\n\treturn value.trim().toLowerCase().replace(/\\.$/, '');\n}\n\nfunction boundarySuffixMatch(hostname: string, suffix: string): boolean {\n\tconst host = normalizeDomain(hostname);\n\tconst normalizedSuffix = normalizeDomain(suffix);\n\tif (!host || !normalizedSuffix) return false;\n\treturn host === normalizedSuffix || host.endsWith(`.${normalizedSuffix}`);\n}\n\n\nexport async function loadProviderSignatures(options?: LoadProviderSignaturesOptions): Promise<ProviderSourceResult> {\n\tconst timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\tconst retries = options?.retries ?? DEFAULT_RETRIES;\n\tconst sourceUrl = options?.sourceUrl?.trim();\n\tconst allowedHosts = normalizeAllowedHosts(options?.allowedHosts);\n\tconst expectedSha256 = options?.expectedSha256?.trim();\n\n\tif (!sourceUrl) {\n\t\treturn buildResult(BUILT_IN_SIGNATURES, 'built-in', false);\n\t}\n\n\tconst now = Date.now();\n\tif (runtimeSignatureCache && runtimeSignatureCache.sourceUrl === sourceUrl && runtimeSignatureCache.expiresAt > now) {\n\t\treturn runtimeSignatureCache.result;\n\t}\n\n\ttry {\n\t\tconst validatedUrl = validateRuntimeSourceUrl(sourceUrl, allowedHosts);\n\t\tconst payload = await fetchProviderPayload(validatedUrl.toString(), timeoutMs, retries, expectedSha256);\n\t\tif (!payload) {\n\t\t\tthrow new Error('Provider signature source returned a redirect');\n\t\t}\n\t\tconst result = buildResult(payload, 'runtime', false);\n\t\tlastKnownGood = result;\n\t\truntimeSignatureCache = {\n\t\t\tsourceUrl,\n\t\t\tresult,\n\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t};\n\t\treturn result;\n\t} catch {\n\t\tif (lastKnownGood) {\n\t\t\tconst staleResult = { ...lastKnownGood, source: 'stale' as const, degraded: true, fetchedAt: new Date().toISOString() };\n\t\t\truntimeSignatureCache = {\n\t\t\t\tsourceUrl,\n\t\t\t\tresult: staleResult,\n\t\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t\t};\n\t\t\treturn staleResult;\n\t\t}\n\t\tconst fallbackResult = buildResult(BUILT_IN_SIGNATURES, 'built-in', true);\n\t\truntimeSignatureCache = {\n\t\t\tsourceUrl,\n\t\t\tresult: fallbackResult,\n\t\t\texpiresAt: now + RUNTIME_SIGNATURE_CACHE_TTL_MS,\n\t\t};\n\t\treturn fallbackResult;\n\t}\n}\n\n/**\n * Test helper to reset provider signature loader state between cases.\n * @internal Exported for test use only.\n */\nexport function resetProviderSignatureState(): void {\n\tlastKnownGood = null;\n\truntimeSignatureCache = null;\n}\n\nexport function detectProviderMatches(hosts: string[], signatures: ProviderSignature[]): ProviderMatchEvidence[] {\n\tconst normalizedHosts = hosts.map((host) => normalizeDomain(host)).filter((host) => host.length > 0);\n\tconst matches: ProviderMatchEvidence[] = [];\n\n\tfor (const provider of signatures) {\n\t\tconst providerMatches = new Set<string>();\n\t\tfor (const host of normalizedHosts) {\n\t\t\tif (provider.domains.some((domain) => boundarySuffixMatch(host, domain))) {\n\t\t\t\tproviderMatches.add(host);\n\t\t\t}\n\t\t}\n\t\tif (providerMatches.size > 0) {\n\t\t\tmatches.push({ provider: provider.name, matches: Array.from(providerMatches) });\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nexport function detectProviderMatchesBySelectors(selectors: string[], signatures: ProviderSignature[]): ProviderMatchEvidence[] {\n\tconst normalizedSelectors = selectors.map((selector) => selector.trim().toLowerCase()).filter((selector) => selector.length > 0);\n\tconst matches: ProviderMatchEvidence[] = [];\n\n\tfor (const provider of signatures) {\n\t\tconst hints = provider.selectorHints ?? [];\n\t\tif (hints.length === 0) continue;\n\n\t\tconst providerMatches = normalizedSelectors.filter((selector) => hints.includes(selector));\n\t\tif (providerMatches.length > 0) {\n\t\t\tmatches.push({ provider: provider.name, matches: Array.from(new Set(providerMatches)) });\n\t\t}\n\t}\n\n\treturn matches;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * MX record check tool for MCP server.\n * Thin wrapper around @blackveil/dns-checks — delegates core logic to the shared package.\n * Adds provider detection post-processing on top of the package result.\n */\n\nimport { checkMX, createFinding } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { detectProviderMatches, loadProviderSignatures } from '../lib/provider-signatures';\n\nexport interface CheckMxOptions {\n\tproviderSignaturesUrl?: string;\n\tproviderSignaturesAllowedHosts?: string[];\n\tproviderSignaturesSha256?: string;\n}\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/** Check MX record configuration for a domain */\nexport async function checkMx(domain: string, options?: CheckMxOptions, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\tconst timeout = dnsOptions?.timeoutMs ?? 5000;\n\n\t// Run core MX check from shared package\n\tconst baseResult = await checkMX(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout },\n\t) as CheckResult;\n\n\t// Early return if MX check already returned critical/error findings (no MX records, etc.)\n\t// Only add provider detection when we have meaningful MX records\n\tconst hasCritical = baseResult.findings.some((f) => f.severity === 'critical');\n\tconst hasMediumQueryFailed = baseResult.findings.some((f) => f.title === 'DNS query failed');\n\tif (hasCritical || hasMediumQueryFailed) {\n\t\treturn baseResult;\n\t}\n\n\t// Provider detection post-processing\n\tconst findings = [...baseResult.findings];\n\n\ttry {\n\t\t// Re-query MX records to get raw strings for provider matching\n\t\tconst mxAnswers = await queryDnsRecords(domain, 'MX', dnsOptions);\n\t\tconst mxTargets = mxAnswers.map((answer) => {\n\t\t\tconst parts = answer.split(' ');\n\t\t\treturn (parts.slice(1).join(' ') || '').replace(/\\.$/, '').toLowerCase();\n\t\t}).filter(Boolean);\n\n\t\tif (mxTargets.length > 0) {\n\t\t\tconst providerSignatures = await loadProviderSignatures({\n\t\t\t\tsourceUrl: options?.providerSignaturesUrl,\n\t\t\t\tallowedHosts: options?.providerSignaturesAllowedHosts,\n\t\t\t\texpectedSha256: options?.providerSignaturesSha256,\n\t\t\t});\n\t\t\tconst inboundMatches = detectProviderMatches(mxTargets, providerSignatures.inbound);\n\n\t\t\tif (inboundMatches.length > 0) {\n\t\t\t\tconst providerNames = inboundMatches.map((m) => m.provider).join(', ');\n\t\t\t\tconst evidence = inboundMatches.map((m) => `${m.provider}: ${m.matches.join(', ')}`).join('; ');\n\t\t\t\tconst providerConfidence = providerSignatures.source === 'runtime' ? 0.95 : providerSignatures.source === 'stale' ? 0.75 : 0.7;\n\n\t\t\t\tfindings.push(\n\t\t\t\t\tcreateFinding('mx', 'Managed email provider detected', 'info', `Inbound provider(s): ${providerNames}. Evidence: ${evidence}.`, {\n\t\t\t\t\t\tdetectionType: 'inbound',\n\t\t\t\t\t\tproviders: inboundMatches.map((m) => ({ name: m.provider, matches: m.matches })),\n\t\t\t\t\t\tproviderConfidence,\n\t\t\t\t\t\tsignatureSource: providerSignatures.source,\n\t\t\t\t\t\tsignatureVersion: providerSignatures.version,\n\t\t\t\t\t\tsignatureFetchedAt: providerSignatures.fetchedAt,\n\t\t\t\t\t}) as (typeof findings)[0],\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (providerSignatures.degraded) {\n\t\t\t\tfindings.push(\n\t\t\t\t\tcreateFinding(\n\t\t\t\t\t\t'mx',\n\t\t\t\t\t\t'Provider signature source unavailable',\n\t\t\t\t\t\t'info',\n\t\t\t\t\t\t`Provider detection used ${providerSignatures.source === 'stale' ? 'stale cached' : 'built-in fallback'} signatures.`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdetectionType: 'inbound',\n\t\t\t\t\t\t\tproviderConfidence: providerSignatures.source === 'stale' ? 0.55 : 0.45,\n\t\t\t\t\t\t\tsignatureSource: providerSignatures.source,\n\t\t\t\t\t\t\tsignatureVersion: providerSignatures.version,\n\t\t\t\t\t\t\tsignatureFetchedAt: providerSignatures.fetchedAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t) as (typeof findings)[0],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Provider detection failure is non-critical — return base result\n\t}\n\n\treturn { ...baseResult, findings };\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * NS (Name Server) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkNS } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check nameserver configuration for a domain.\n * Validates NS records exist, checks for diversity, and verifies responsiveness.\n */\nexport async function checkNs(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkNS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SPF (Sender Policy Framework) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSPF } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\n/**\n * Build a DNSQueryFunction adapter that routes TXT queries through queryTxtRecords\n * (which strips surrounding quotes from DoH TXT data) and all other record types\n * through queryDnsRecords.\n */\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check SPF records for a domain.\n * Looks for v=spf1 TXT records and validates their configuration.\n * Recursively expands include chains to compute true DNS lookup count.\n */\nexport async function checkSpf(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSPF(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SSL/TLS certificate check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSSL } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\n/**\n * Check SSL/TLS configuration for a domain.\n * Validates HTTPS connectivity, HSTS headers, and HTTP→HTTPS redirect.\n */\nexport async function checkSsl(domain: string): Promise<CheckResult> {\n\treturn checkSSL(domain, fetch, { timeout: HTTPS_TIMEOUT_MS }) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Subdomain Takeover / Dangling CNAME Detection Tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSubdomainTakeover as checkSubdomainTakeoverPkg } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check for dangling CNAME records on known/active subdomains.\n * Flags orphaned records and potential takeover vectors.\n */\nexport async function checkSubdomainTakeover(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSubdomainTakeoverPkg(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? HTTPS_TIMEOUT_MS, fetchFn: fetch },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * TLS-RPT (SMTP TLS Reporting) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkTLSRPT } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check TLS-RPT records for a domain.\n * Validates the presence and configuration of SMTP TLS Reporting records.\n */\nexport async function checkTlsrpt(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkTLSRPT(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { sanitizeInput } from './sanitize';\n\nconst MARKDOWN_SYNTAX = /[`*_#[\\]()>|<]/g;\n\n/**\n * Characters that can inject HTML or dangerous markdown constructs.\n * Excludes `_` (common in DNS names like `_dmarc`, `_mta-sts`) and\n * `()` (used in natural-language detail text) which are safe in finding details.\n */\nconst DNS_DATA_UNSAFE = /[`*#[\\]>|<]/g;\n\n/**\n * Sanitize DNS-sourced data before it enters finding detail strings.\n * Strips C0 control characters (preserving tab/newline), replaces HTML/markdown\n * injection characters, but does NOT truncate — DNS data in findings can be\n * longer than display output.\n */\nexport function sanitizeDnsData(input: string): string {\n\treturn input\n\t\t.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '')\n\t\t.replace(DNS_DATA_UNSAFE, ' ')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim();\n}\n\nexport function sanitizeOutputText(input: string, maxLength = 240): string {\n\tconst trimmed = sanitizeInput(input, maxLength * 2)\n\t\t.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, '')\n\t\t.replace(MARKDOWN_SYNTAX, ' ')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim();\n\n\tif (trimmed.length <= maxLength) {\n\t\treturn trimmed;\n\t}\n\n\treturn `${trimmed.slice(0, maxLength - 3).trimEnd()}...`;\n}","export interface ExplanationTemplate {\n\ttitle: string;\n\tseverity: string;\n\texplanation: string;\n\timpact?: string;\n\tadverseConsequences?: string;\n\trecommendation: string;\n\treferences: string[];\n}\n\nexport interface ImpactNarrative {\n\timpact?: string;\n\tadverseConsequences?: string;\n}\n\nexport interface SpecificImpactRule extends ImpactNarrative {\n\tcheckType?: string;\n\ttitleIncludes?: string[];\n\tdetailIncludes?: string[];\n}\n\nexport const EXPLANATIONS: Record<string, ExplanationTemplate> = {\n\tSUBDOMAIN_TAKEOVER_CRITICAL: {\n\t\ttitle: 'Dangling CNAME — Subdomain Takeover Risk',\n\t\tseverity: 'critical',\n\t\texplanation:\n\t\t\t'A subdomain points to a third-party service (e.g., CloudFront, Heroku) that does not resolve. This is a potential subdomain takeover vector, allowing attackers to claim the orphaned resource and control the subdomain.',\n\t\timpact: 'Attackers may host malicious content or capture traffic on a trusted subdomain, enabling phishing and session abuse.',\n\t\tadverseConsequences:\n\t\t\t'Brand trust can be damaged, users can be redirected to attacker infrastructure, and incident response costs can increase.',\n\t\trecommendation: 'Remove or update the CNAME record to point to a valid, owned resource. Regularly audit DNS for orphaned records.',\n\t\treferences: [\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t\t'https://www.hackerone.com/blog/Guide-Subdomain-Takeover',\n\t\t\t'https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html',\n\t\t],\n\t},\n\tSUBDOMAIN_TAKEOVER_HIGH: {\n\t\ttitle: 'CNAME Resolution Failed — Manual Review Needed',\n\t\tseverity: 'high',\n\t\texplanation:\n\t\t\t'A subdomain CNAME points to a third-party service but the target could not be resolved. This may indicate a takeover risk or DNS misconfiguration.',\n\t\timpact: 'If the target is orphaned, an attacker may be able to claim it and gain control of the affected subdomain.',\n\t\tadverseConsequences: 'Users may be exposed to fraudulent pages and the organization may face reputation damage until DNS is remediated.',\n\t\trecommendation: 'Manually review the CNAME target and remove or update if orphaned. Use DNS monitoring tools for ongoing checks.',\n\t\treferences: [\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t\t'https://www.hackerone.com/blog/Guide-Subdomain-Takeover',\n\t\t],\n\t},\n\tSUBDOMAIN_TAKEOVER_INFO: {\n\t\ttitle: 'No Dangling CNAME Records Found',\n\t\tseverity: 'info',\n\t\texplanation: 'No subdomain takeover vectors detected among known/active subdomains. DNS configuration is secure for this check.',\n\t\trecommendation: 'Continue regular DNS audits and monitoring for new subdomains or changes.',\n\t\treferences: ['https://github.com/EdOverflow/can-i-take-over-xyz'],\n\t},\n\tSUBDOMAILING_CRITICAL: {\n\t\ttitle: 'Dangling CNAME in SPF Include Chain — SubdoMailing Risk',\n\t\tseverity: 'critical',\n\t\texplanation:\n\t\t\t'An SPF include domain has a dangling CNAME record pointing to a third-party service that does not resolve. An attacker could register the orphaned resource, gain control of the SPF include, and send authenticated email as the target domain.',\n\t\timpact: 'Full email authentication bypass — attacker-sent messages pass SPF checks and may pass DMARC alignment.',\n\t\tadverseConsequences:\n\t\t\t'Targeted phishing campaigns sent from a trusted domain identity, bypassing email security filters at scale.',\n\t\trecommendation: 'Remove the include mechanism from the SPF record or update it to point to a valid, owned resource. Audit all SPF includes periodically.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t\t'https://github.com/EdOverflow/can-i-take-over-xyz',\n\t\t],\n\t},\n\tSUBDOMAILING_HIGH: {\n\t\ttitle: 'Dangling NS Delegation in SPF Include Chain',\n\t\tseverity: 'high',\n\t\texplanation:\n\t\t\t'An SPF include domain has nameservers that do not resolve. An attacker could register the NS target domains and take control of DNS for the include domain, enabling SPF authorization hijacking.',\n\t\timpact: 'Potential email authentication bypass if the attacker registers the unresolvable nameserver domains.',\n\t\tadverseConsequences:\n\t\t\t'Spoofed emails could pass SPF validation, eroding trust and enabling impersonation attacks.',\n\t\trecommendation: 'Remove the include mechanism or ensure its nameservers resolve correctly. Consider consolidating SPF includes to domains under your direct control.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSUBDOMAILING_LOW: {\n\t\ttitle: 'Void SPF Include',\n\t\tseverity: 'low',\n\t\texplanation:\n\t\t\t'An SPF include domain has no SPF record. While not immediately exploitable, this wastes a DNS lookup and could become a risk if the domain is abandoned or expires.',\n\t\trecommendation: 'Remove unused include mechanisms from the SPF record to reduce lookup waste and attack surface.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSUBDOMAILING_INFO: {\n\t\ttitle: 'No SubdoMailing Risk Detected',\n\t\tseverity: 'info',\n\t\texplanation: 'All SPF include and redirect domains resolve correctly with no takeover indicators. The SPF include chain is secure for this check.',\n\t\trecommendation: 'Continue periodic audits of SPF include domains, especially after vendor changes.',\n\t\treferences: [\n\t\t\t'https://guardio.co/blog/subdomailing',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7208',\n\t\t],\n\t},\n\tSPF_PASS: {\n\t\ttitle: 'SPF Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'SPF (Sender Policy Framework) is properly configured. The domain specifies which mail servers are authorized to send email on its behalf.',\n\t\trecommendation: 'Maintain your current SPF configuration. Ensure you update it when adding new email sending sources.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208'],\n\t},\n\tSPF_FAIL: {\n\t\ttitle: 'SPF Validation Failed',\n\t\tseverity: 'fail',\n\t\texplanation: 'SPF validation failed - emails from this domain are being rejected because the sending server is not authorized.',\n\t\timpact: 'Email authentication becomes unreliable, and spoofed or misrouted messages may evade expected controls.',\n\t\tadverseConsequences:\n\t\t\t'Legitimate email delivery can degrade, while impersonation attempts can increase helpdesk and abuse handling load.',\n\t\trecommendation:\n\t\t\t'Review your SPF record and ensure all legitimate email sources are included. Common issue: using -all but missing include statements.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208', 'https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/'],\n\t},\n\tSPF_WARNING: {\n\t\ttitle: 'SPF Soft Fail',\n\t\tseverity: 'warning',\n\t\texplanation: 'SPF uses a soft fail (~all) policy. Emails that fail SPF will be accepted but may be flagged as suspicious.',\n\t\timpact: 'Failing SPF messages are often still accepted, so spoofed mail may continue reaching recipients.',\n\t\tadverseConsequences: 'Phishing risk remains elevated and security teams may need to manually triage suspicious mail.',\n\t\trecommendation: 'Upgrade to hard fail (-all) after verifying all legitimate sources are in your SPF record.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208#section-8.1'],\n\t},\n\tSPF_MISSING: {\n\t\ttitle: 'No SPF Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'SPF (Sender Policy Framework) is a DNS TXT record that specifies which mail servers are authorized to send email on behalf of your domain. Without SPF, any server can send email pretending to be from your domain.',\n\t\timpact: 'Any internet host can attempt to send email as your domain, making sender impersonation significantly easier.',\n\t\tadverseConsequences: 'Spoofing and phishing campaigns can harm brand trust, increase abuse complaints, and impair deliverability.',\n\t\trecommendation: \"Add a TXT record to your domain's DNS with a valid SPF policy. Start with: v=spf1 include:<your-email-provider> -all\",\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7208', 'https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/'],\n\t},\n\tDMARC_PASS: {\n\t\ttitle: 'DMARC Policy Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DMARC (Domain-based Message Authentication, Reporting & Conformance) is properly configured with a policy that provides protection against email spoofing.',\n\t\trecommendation:\n\t\t\t'Monitor your DMARC reports to ensure legitimate email is not being blocked. Consider enabling reject policy for stronger protection.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489'],\n\t},\n\tDMARC_FAIL: {\n\t\ttitle: 'No DMARC Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'DMARC builds on SPF and DKIM to provide email authentication policy. Without DMARC, receivers have no policy guidance for handling authentication failures.',\n\t\timpact: 'Receiving systems cannot consistently quarantine or reject forged messages that fail authentication.',\n\t\tadverseConsequences: 'Domain spoofing can reach inboxes more often, increasing phishing exposure and reputational damage.',\n\t\trecommendation: 'Add a TXT record at _dmarc.<domain> with at minimum: v=DMARC1; p=quarantine; rua=mailto:dmarc@<domain>',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489', 'https://www.cloudflare.com/learning/dns/dns-records/dns-dmarc-record/'],\n\t},\n\tDMARC_WARNING: {\n\t\ttitle: 'DMARC Policy Not Enforcing',\n\t\tseverity: 'warning',\n\t\texplanation: \"DMARC policy is set to 'none' (monitoring only) or 'quarantine'. This provides limited protection against spoofing.\",\n\t\timpact: 'Authentication failures may not be fully blocked, allowing some malicious mail to be delivered.',\n\t\tadverseConsequences: 'Attackers can still impersonate the domain in recipient inboxes, leading to fraud and support overhead.',\n\t\trecommendation: \"After reviewing DMARC reports, upgrade the policy to 'reject' to actively protect against email spoofing.\",\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc7489#section-6.3'],\n\t},\n\tDKIM_PASS: {\n\t\ttitle: 'DKIM Validated',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DKIM (DomainKeys Identified Mail) is properly configured. Outgoing emails are digitally signed and can be verified by receivers.',\n\t\trecommendation: 'Maintain your DKIM configuration. Rotate keys periodically as per your security policy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6376'],\n\t},\n\tDKIM_FAIL: {\n\t\ttitle: 'No DKIM Records Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t\"DKIM adds a digital signature to outgoing emails, allowing receivers to verify the email was sent by an authorized server and wasn't modified in transit.\",\n\t\timpact: 'Receivers lose a key authenticity signal, which weakens anti-spoofing and anti-tampering protections.',\n\t\tadverseConsequences:\n\t\t\t'Legitimate email may be distrusted while fraudulent messages are harder to distinguish, hurting deliverability and trust.',\n\t\trecommendation: 'Configure DKIM signing with your email provider. They will provide the DKIM DNS records to publish.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6376', 'https://www.cloudflare.com/learning/dns/dns-records/dns-dkim-record/'],\n\t},\n\tDNSSEC_PASS: {\n\t\ttitle: 'DNSSEC Enabled',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'DNSSEC is properly configured with valid cryptographic signatures. This protects against DNS spoofing and cache poisoning attacks.',\n\t\trecommendation: 'Maintain your DNSSEC configuration. Monitor for any validation failures in your logs.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc4033'],\n\t},\n\tDNSSEC_FAIL: {\n\t\ttitle: 'DNSSEC Not Validated',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t\"DNSSEC adds cryptographic signatures to DNS records, preventing DNS spoofing and cache poisoning attacks. Without DNSSEC, attackers can redirect your domain's traffic.\",\n\t\timpact: 'DNS responses can be forged in transit, enabling redirection to attacker-controlled infrastructure.',\n\t\tadverseConsequences: 'Users may be sent to malicious destinations, causing credential theft, service disruption, and incident response costs.',\n\t\trecommendation: 'Enable DNSSEC through your domain registrar and DNS provider. Most providers offer one-click DNSSEC activation.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc4033', 'https://www.cloudflare.com/dns/dnssec/how-dnssec-works/'],\n\t},\n\tSSL_PASS: {\n\t\ttitle: 'SSL/TLS Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'The domain properly serves content over HTTPS with a valid certificate.',\n\t\trecommendation: 'Maintain your SSL certificate. Consider implementing HSTS for additional security.',\n\t\treferences: ['https://https.cio.gov/hsts/'],\n\t},\n\tSSL_FAIL: {\n\t\ttitle: 'HTTPS Not Available',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'The domain does not have a valid SSL/TLS certificate or the HTTPS server is not responding. This means traffic to the domain is not encrypted.',\n\t\timpact: 'Network attackers can intercept or tamper with data exchanged between users and the site.',\n\t\tadverseConsequences: 'Credentials and sensitive data may be exposed, and browser trust warnings can reduce conversion and user confidence.',\n\t\trecommendation: \"Install a valid SSL/TLS certificate. Free certificates are available from Let's Encrypt or Cloudflare.\",\n\t\treferences: ['https://letsencrypt.org/', 'https://www.cloudflare.com/ssl/'],\n\t},\n\tSSL_WARNING: {\n\t\ttitle: 'Mixed Content or Redirect Issues',\n\t\tseverity: 'warning',\n\t\texplanation: 'HTTPS is available but there may be issues with redirects or mixed content.',\n\t\timpact: 'Some resources may still load insecurely, creating opportunities for content manipulation or privacy leakage.',\n\t\tadverseConsequences: 'User sessions and page integrity can be weakened, and security posture may fail audit expectations.',\n\t\trecommendation: 'Ensure all resources load over HTTPS and implement proper redirects from HTTP to HTTPS.',\n\t\treferences: ['https://www.cloudflare.com/ssl/'],\n\t},\n\tSSL_MEDIUM: {\n\t\ttitle: 'HSTS or Redirect Issues',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'HTTPS is available but the domain is missing HSTS (Strict-Transport-Security) headers or does not redirect HTTP to HTTPS. Without HSTS, browsers may still attempt insecure connections.',\n\t\timpact: 'Clients may be downgraded to insecure HTTP connections, especially on first visit or hostile networks.',\n\t\tadverseConsequences: 'Session data can be exposed in transit and users remain vulnerable to downgrade or interception attacks.',\n\t\trecommendation:\n\t\t\t'Add a Strict-Transport-Security header with max-age of at least 1 year (31536000). Configure your web server to redirect all HTTP requests to HTTPS.',\n\t\treferences: ['https://https.cio.gov/hsts/', 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security'],\n\t},\n\tSSL_LOW: {\n\t\ttitle: 'HSTS Configuration Suboptimal',\n\t\tseverity: 'low',\n\t\texplanation:\n\t\t\t'HSTS is configured but could be improved. Common issues include a short max-age value or missing includeSubDomains directive.',\n\t\timpact: 'Partial HSTS coverage leaves windows where transport security guarantees are weaker than expected.',\n\t\tadverseConsequences: 'Subdomains or returning sessions may still face avoidable downgrade exposure and policy non-compliance findings.',\n\t\trecommendation:\n\t\t\t'Set max-age to at least 31536000 (1 year) and include the includeSubDomains directive. Consider adding your domain to the HSTS preload list.',\n\t\treferences: [\n\t\t\t'https://hstspreload.org/',\n\t\t\t'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security',\n\t\t],\n\t},\n\tMTA_STS_PASS: {\n\t\ttitle: 'MTA-STS Enabled',\n\t\tseverity: 'pass',\n\t\texplanation: 'MTA-STS (Mail Transfer Agent Strict Transport Security) is properly configured and enforces TLS for incoming email.',\n\t\trecommendation: 'Monitor your MTA-STS reports to ensure legitimate mail servers can deliver successfully.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tMTA_STS_FAIL: {\n\t\ttitle: 'No MTA-STS Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'MTA-STS enforces TLS encryption for incoming email, preventing downgrade attacks where an attacker forces email to be sent unencrypted.',\n\t\timpact: 'Inbound SMTP sessions are more susceptible to TLS downgrade and interception attempts.',\n\t\tadverseConsequences: 'Sensitive email content can be exposed in transit, raising confidentiality and compliance risks.',\n\t\trecommendation:\n\t\t\t'Publish an MTA-STS TXT record at _mta-sts.<domain> and host a policy file at https://mta-sts.<domain>/.well-known/mta-sts.txt',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tMTA_STS_WARNING: {\n\t\ttitle: 'MTA-STS in Testing Mode',\n\t\tseverity: 'warning',\n\t\texplanation: 'MTA-STS is configured but in testing mode (mode=testing) rather than enforcement mode.',\n\t\timpact: 'Delivery behavior is monitored but not enforced, so some insecure transport paths may still be accepted.',\n\t\tadverseConsequences: 'Security gaps can persist longer and confidentiality controls for inbound mail remain partially effective.',\n\t\trecommendation: 'After verifying all mail servers can successfully deliver over TLS, upgrade to mode=enforce.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8461'],\n\t},\n\tNS_PASS: {\n\t\ttitle: 'Nameservers Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'The domain has properly configured nameservers that are responding to queries.',\n\t\trecommendation: 'Maintain your current nameserver configuration. Use at least two geographically distributed nameservers for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035'],\n\t},\n\tNS_FAIL: {\n\t\ttitle: 'Nameserver Issues Detected',\n\t\tseverity: 'fail',\n\t\texplanation: 'One or more nameservers for this domain are not responding or are misconfigured, which can cause DNS resolution failures.',\n\t\timpact: 'Resolvers may fail to resolve the domain, degrading access to web, API, and mail services.',\n\t\tadverseConsequences: 'Users can experience outages, failed transactions, and business continuity disruptions.',\n\t\trecommendation: 'Verify all listed nameservers are operational and properly configured. Ensure NS records match those at the registrar.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035', 'https://www.cloudflare.com/learning/dns/dns-records/dns-ns-record/'],\n\t},\n\tNS_WARNING: {\n\t\ttitle: 'Nameserver Configuration Suboptimal',\n\t\tseverity: 'warning',\n\t\texplanation: 'Nameservers are functional but the configuration could be improved for better reliability or security.',\n\t\timpact: 'Single points of failure or weak diversity can reduce DNS resilience during provider or network incidents.',\n\t\tadverseConsequences: 'Availability and latency can degrade under stress, increasing user-facing instability.',\n\t\trecommendation: 'Consider adding additional nameservers for redundancy and ensuring they are geographically distributed.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc1035'],\n\t},\n\tCAA_PASS: {\n\t\ttitle: 'CAA Records Configured',\n\t\tseverity: 'pass',\n\t\texplanation: 'CAA (Certificate Authority Authorization) records are properly configured, restricting which CAs can issue certificates for this domain.',\n\t\trecommendation: 'Maintain your CAA records. Review periodically to ensure they reflect your current certificate issuance needs.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659'],\n\t},\n\tCAA_FAIL: {\n\t\ttitle: 'No CAA Records Found',\n\t\tseverity: 'fail',\n\t\texplanation: 'No CAA records are present for this domain. Without CAA, any certificate authority can issue certificates for your domain.',\n\t\timpact: 'Certificate issuance controls are broad, increasing the chance of unauthorized or misissued certificates.',\n\t\tadverseConsequences: 'Attackers may abuse misissuance for impersonation and interception, with trust and compliance implications.',\n\t\trecommendation: 'Add CAA DNS records to restrict certificate issuance to your authorized CAs (e.g., \"0 issue letsencrypt.org\").',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659', 'https://www.cloudflare.com/learning/dns/dns-records/dns-caa-record/'],\n\t},\n\tCAA_WARNING: {\n\t\ttitle: 'CAA Configuration Incomplete',\n\t\tseverity: 'warning',\n\t\texplanation: 'CAA records exist but may not fully restrict certificate issuance. Consider adding iodef or wildcard policies.',\n\t\timpact: 'Incomplete CAA policy can leave gaps in issuance constraints for wildcard or incident-reporting scenarios.',\n\t\tadverseConsequences: 'Certificate governance may be weaker than intended, increasing operational and audit risk.',\n\t\trecommendation: 'Review your CAA records and add an iodef tag for incident reporting. Consider restricting wildcard certificate issuance separately.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc8659'],\n\t},\n\tMX_PASS: {\n\t\ttitle: 'MX Records Validated',\n\t\tseverity: 'pass',\n\t\texplanation: 'MX (Mail Exchange) records are properly configured, directing email to the correct mail servers.',\n\t\trecommendation: 'Maintain your MX records. Ensure backup MX entries exist for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_FAIL: {\n\t\ttitle: 'No MX Records Found',\n\t\tseverity: 'fail',\n\t\texplanation: 'No MX records are present for this domain. Without MX records, email delivery to this domain will fail or fall back to A record delivery.',\n\t\timpact: 'Mail routing is unreliable or unavailable for intended recipients on this domain.',\n\t\tadverseConsequences: 'Inbound communications may be lost, causing business disruption and missed security notifications.',\n\t\trecommendation: 'Add MX records pointing to your mail server. If this domain does not handle email, consider adding a null MX record (0 .).',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321', 'https://datatracker.ietf.org/doc/html/rfc7505'],\n\t},\n\tMX_WARNING: {\n\t\ttitle: 'MX Configuration Suboptimal',\n\t\tseverity: 'warning',\n\t\texplanation: 'MX records exist but the configuration could be improved, such as missing backup MX or unusual priority values.',\n\t\timpact: 'Mail delivery reliability is reduced during server failures or routing anomalies.',\n\t\tadverseConsequences: 'Message delays and intermittent delivery failures can affect operations and customer support.',\n\t\trecommendation: 'Review MX priorities and add at least one backup MX record for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_INFO: {\n\t\ttitle: 'MX Records Present',\n\t\tseverity: 'info',\n\t\texplanation: 'Mail exchange records are properly configured for this domain.',\n\t\trecommendation: 'No action required. Ensure backup MX records exist for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_LOW: {\n\t\ttitle: 'MX Configuration Could Be Improved',\n\t\tseverity: 'low',\n\t\texplanation: 'MX records are present but the configuration has minor issues such as missing backup MX records.',\n\t\timpact: 'Resilience to mail infrastructure outages is lower than recommended.',\n\t\tadverseConsequences: 'Short outages can become user-visible delivery delays and increase operational toil.',\n\t\trecommendation: 'Add at least one backup MX record with a different priority for redundancy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_HIGH: {\n\t\ttitle: 'MX Configuration Error',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'MX records have a configuration error such as pointing to an IP address instead of a hostname (violating RFC 5321) or referencing a hostname that does not resolve to any address record.',\n\t\timpact: 'Standards-incompatible or unresolvable MX targets can cause mail rejection or routing failures across sending systems.',\n\t\tadverseConsequences: 'Business-critical messages may bounce, delaying incident response and external communication.',\n\t\trecommendation:\n\t\t\t'Update MX records to point to valid hostnames, not IP addresses. Ensure all MX targets resolve to valid A/AAAA records.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321'],\n\t},\n\tMX_MEDIUM: {\n\t\ttitle: 'No MX Records Found',\n\t\tseverity: 'medium',\n\t\texplanation:\n\t\t\t'No MX records are present for this domain. Email delivery will fall back to A record delivery or fail entirely.',\n\t\timpact: 'Email reception may fail or behave inconsistently depending on sender fallback behavior.',\n\t\tadverseConsequences: 'Organizations may miss customer, partner, or security messages, creating operational and reputational risk.',\n\t\trecommendation:\n\t\t\t'If this domain should receive email, add MX records. If not, publish a null MX record per RFC 7505 to explicitly declare that.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc5321', 'https://datatracker.ietf.org/doc/html/rfc7505'],\n\t},\n\tDANE_HTTPS_PASS: {\n\t\ttitle: 'DANE TLSA Configured for HTTPS',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'TLSA records at _443._tcp.{domain} pin the web server certificate to DNS, providing an additional layer of TLS trust beyond the CA system. Combined with DNSSEC, this prevents unauthorized CAs from issuing fraudulent certificates for the domain.',\n\t\trecommendation: 'Maintain your DANE HTTPS configuration. Ensure TLSA records are updated whenever TLS certificates are renewed.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_FAIL: {\n\t\ttitle: 'No DANE TLSA for HTTPS',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'No TLSA records were found at _443._tcp.{domain}. DANE certificate pinning for HTTPS provides an additional trust anchor beyond the CA system, preventing unauthorized certificate issuance attacks.',\n\t\timpact: 'Certificate issuance for this domain relies solely on the CA trust hierarchy.',\n\t\tadverseConsequences:\n\t\t\t'A compromised or rogue CA can issue a valid certificate for the domain, enabling MITM attacks that bypass standard browser trust checks.',\n\t\trecommendation:\n\t\t\t'Implement DANE-EE (usage 3) TLSA records at _443._tcp.{domain} and ensure DNSSEC is enabled. Use SHA-256 (matching type 1) or SHA-512 (matching type 2) for the certificate data hash.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_WARNING: {\n\t\ttitle: 'DANE HTTPS Configuration Warning',\n\t\tseverity: 'warning',\n\t\texplanation:\n\t\t\t'DANE TLSA records exist for the HTTPS endpoint but the configuration has issues that reduce their security value, such as DANE without DNSSEC or weak matching types.',\n\t\timpact: 'DANE protection is partially effective but can be bypassed or subverted.',\n\t\tadverseConsequences:\n\t\t\t'Attackers may be able to spoof or modify TLSA records if DNSSEC is absent, negating the security benefit of DANE.',\n\t\trecommendation:\n\t\t\t'Enable DNSSEC on the domain and use DANE-EE (usage 3) with SHA-256 matching (type 1) for best security.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc6698',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc7671',\n\t\t],\n\t},\n\tDANE_HTTPS_INFO: {\n\t\ttitle: 'DANE HTTPS Record Present',\n\t\tseverity: 'info',\n\t\texplanation: 'A TLSA record is configured at _443._tcp.{domain}, enabling DANE certificate pinning for HTTPS.',\n\t\trecommendation: 'Keep TLSA records synchronized with your TLS certificate. Automate renewal if possible.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc6698'],\n\t},\n\tSVCB_HTTPS_PASS: {\n\t\ttitle: 'HTTPS Record Configured',\n\t\tseverity: 'pass',\n\t\texplanation:\n\t\t\t'HTTPS/SVCB records (RFC 9460) are present and advertise modern transport capabilities. This enables clients to negotiate HTTP/2 or HTTP/3 without an initial redirect and optionally distributes ECH parameters for privacy.',\n\t\trecommendation: 'Maintain your HTTPS records. Consider enabling ECH for enhanced connection privacy.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc9460',\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc8446',\n\t\t],\n\t},\n\tSVCB_HTTPS_FAIL: {\n\t\ttitle: 'No HTTPS Record Found',\n\t\tseverity: 'fail',\n\t\texplanation:\n\t\t\t'No HTTPS record (type 65, RFC 9460) was found for this domain. HTTPS records advertise modern transport capabilities (ALPN, ECH) and allow clients to connect securely and efficiently without an initial redirect round-trip.',\n\t\timpact: 'Clients cannot discover HTTP/2 or HTTP/3 support via DNS, requiring an additional round-trip.',\n\t\tadverseConsequences:\n\t\t\t'Connection setup is slower, privacy from ECH is unavailable, and the domain misses opportunities for TLS optimization.',\n\t\trecommendation:\n\t\t\t'Publish an HTTPS record with at minimum alpn=\"h2,h3\" to enable HTTP/2 and HTTP/3 advertisement. If using Cloudflare or similar CDN, this may be automatically managed.',\n\t\treferences: [\n\t\t\t'https://datatracker.ietf.org/doc/html/rfc9460',\n\t\t\t'https://blog.cloudflare.com/speeding-up-https-and-http-3-negotiation-with-dns/',\n\t\t],\n\t},\n\tSVCB_HTTPS_WARNING: {\n\t\ttitle: 'HTTPS Record Configuration Warning',\n\t\tseverity: 'warning',\n\t\texplanation:\n\t\t\t'HTTPS records are present but the configuration is suboptimal — for example, no ALPN parameters or missing HTTP/2 support.',\n\t\timpact: 'Clients cannot fully leverage the capabilities advertised in the HTTPS record.',\n\t\tadverseConsequences:\n\t\t\t'Performance benefits from SVCB are partially lost and ECH privacy may be unavailable.',\n\t\trecommendation:\n\t\t\t'Update HTTPS records to include alpn=\"h2,h3\" and consider adding ECH parameters. Ensure alias mode targets also have valid HTTPS records.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc9460'],\n\t},\n\tSVCB_HTTPS_INFO: {\n\t\ttitle: 'HTTPS Record Present',\n\t\tseverity: 'info',\n\t\texplanation: 'An HTTPS/SVCB record is configured, advertising modern connection capabilities for this domain.',\n\t\trecommendation: 'No action required. Consider adding ECH for enhanced privacy.',\n\t\treferences: ['https://datatracker.ietf.org/doc/html/rfc9460'],\n\t},\n};\n\nexport const DEFAULT_EXPLANATION: ExplanationTemplate = {\n\ttitle: 'Security Check Complete',\n\tseverity: 'info',\n\texplanation: \"This check has been completed. Review the findings above for details on your domain's security posture.\",\n\trecommendation: 'Refer to the specific check documentation for detailed remediation steps.',\n\treferences: ['https://www.cloudflare.com/learning/dns/what-is-dns/'],\n};\n\nexport const CATEGORY_TO_CHECKTYPE: Record<string, string> = {\n\tspf: 'SPF',\n\tdmarc: 'DMARC',\n\tdkim: 'DKIM',\n\tdnssec: 'DNSSEC',\n\tssl: 'SSL',\n\tmta_sts: 'MTA_STS',\n\tns: 'NS',\n\tcaa: 'CAA',\n\tmx: 'MX',\n\tsubdomain_takeover: 'SUBDOMAIN_TAKEOVER',\n\tsubdomailing: 'SUBDOMAILING',\n\tdane_https: 'DANE_HTTPS',\n\tsvcb_https: 'SVCB_HTTPS',\n};\n\nexport const CATEGORY_FALLBACK_IMPACT: Record<string, ImpactNarrative> = {\n\tSPF: {\n\t\timpact: 'SPF coverage is weak, so unauthorized senders can spoof domain identity more easily.',\n\t\tadverseConsequences: 'Phishing attempts and deliverability disputes increase security and support workload.',\n\t},\n\tDMARC: {\n\t\timpact: 'DMARC enforcement is reduced or absent at receiving systems.',\n\t\tadverseConsequences: 'Forged messages are more likely to reach users and erode brand trust.',\n\t},\n\tDKIM: {\n\t\timpact: 'DKIM assurance is weak, reducing message integrity and sender-authenticity confidence.',\n\t\tadverseConsequences: 'Legitimate messages may be distrusted while impersonation attempts become harder to detect.',\n\t},\n\tDNSSEC: {\n\t\timpact: 'DNS answers are more exposed to spoofing and tampering in transit.',\n\t\tadverseConsequences: 'Users can be redirected to attacker infrastructure, causing security and availability incidents.',\n\t},\n\tSSL: {\n\t\timpact: 'Transport security guarantees are reduced, increasing interception and tampering risk.',\n\t\tadverseConsequences: 'Sensitive user data may be exposed and browser trust can decline.',\n\t},\n\tMTA_STS: {\n\t\timpact: 'Inbound SMTP delivery is not consistently protected from downgrade attacks.',\n\t\tadverseConsequences: 'Confidential email content may be exposed in transit, increasing compliance risk.',\n\t},\n\tNS: {\n\t\timpact: 'DNS resolution reliability is reduced, which weakens service reachability.',\n\t\tadverseConsequences: 'Users may experience outages and business transactions may fail.',\n\t},\n\tCAA: {\n\t\timpact: 'Certificate issuance controls are weak, raising unauthorized issuance risk.',\n\t\tadverseConsequences: 'Domain impersonation and TLS trust incidents become more likely.',\n\t},\n\tMX: {\n\t\timpact: 'Mail routing reliability is reduced by MX configuration gaps or errors.',\n\t\tadverseConsequences: 'Important communications can be delayed, bounced, or lost.',\n\t},\n\tSUBDOMAIN_TAKEOVER: {\n\t\timpact: 'An orphaned delegated subdomain may be claimable by an attacker.',\n\t\tadverseConsequences: 'Users can be redirected to malicious content hosted under a trusted hostname.',\n\t},\n\tSUBDOMAILING: {\n\t\timpact: 'SPF include chain references a takeover-vulnerable domain, potentially allowing unauthorized email sending.',\n\t\tadverseConsequences: 'Attackers could send authenticated phishing emails from the trusted domain, bypassing email security controls.',\n\t},\n\tDANE_HTTPS: {\n\t\timpact: 'HTTPS certificate pinning via DANE is absent or misconfigured, leaving TLS trust dependent solely on the CA system.',\n\t\tadverseConsequences: 'A rogue or compromised CA can issue a fraudulent certificate, enabling undetected MITM attacks.',\n\t},\n\tSVCB_HTTPS: {\n\t\timpact: 'Modern transport capabilities (ALPN, ECH) cannot be advertised via DNS, reducing connection efficiency and privacy.',\n\t\tadverseConsequences: 'Clients require additional round-trips to negotiate protocols, and ECH-based privacy is unavailable.',\n\t},\n};\n\nexport const SEVERITY_FALLBACK_IMPACT: Record<string, ImpactNarrative> = {\n\tcritical: {\n\t\timpact: 'This is a high-likelihood weakness with immediate exploitation potential.',\n\t\tadverseConsequences: 'Compromise, disruption, or abuse can occur without prompt remediation.',\n\t},\n\thigh: {\n\t\timpact: 'This weakness materially increases attack surface and failure risk.',\n\t\tadverseConsequences: 'Business operations, user trust, and response workload can be negatively affected.',\n\t},\n\tmedium: {\n\t\timpact: 'This issue weakens defenses and compounds risk when paired with other gaps.',\n\t\tadverseConsequences: 'Over time it can degrade reliability, security assurance, and compliance posture.',\n\t},\n\twarning: {\n\t\timpact: 'This configuration is partially protective but leaves avoidable exposure.',\n\t\tadverseConsequences: 'If unresolved, incidents become harder to prevent or contain.',\n\t},\n\tfail: {\n\t\timpact: 'A required control is missing or not functioning as intended.',\n\t\tadverseConsequences: 'Security and availability incidents become more likely until it is corrected.',\n\t},\n\tlow: {\n\t\timpact: 'This is a minor weakness that still reduces resilience.',\n\t\tadverseConsequences: 'Operational friction and audit findings can increase over time.',\n\t},\n};\n\nexport const SPECIFIC_IMPACT_RULES: SpecificImpactRule[] = [\n\t{\n\t\tcheckType: 'DKIM',\n\t\ttitleIncludes: ['weak rsa key'],\n\t\timpact: 'Weak DKIM keys are easier to forge, reducing message authenticity assurance.',\n\t\tadverseConsequences: 'Attackers can impersonate trusted senders more easily, increasing fraud and phishing risk.',\n\t},\n\t{\n\t\tcheckType: 'SSL',\n\t\ttitleIncludes: ['no hsts header', 'no http to https redirect', 'mixed content'],\n\t\timpact: 'Users are exposed to insecure transport paths that permit interception or downgrade attacks.',\n\t\tadverseConsequences: 'Sensitive sessions and data can leak on hostile networks, weakening trust and compliance posture.',\n\t},\n\t{\n\t\tcheckType: 'DMARC',\n\t\ttitleIncludes: ['no aggregate reporting'],\n\t\timpact: 'Authentication failures and spoofing activity become harder to observe at scale.',\n\t\tadverseConsequences: 'Threats can persist longer without detection, increasing response time and abuse volume.',\n\t},\n\t{\n\t\tcheckType: 'MX',\n\t\ttitleIncludes: ['no mx records found', 'mx configuration error'],\n\t\timpact: 'Inbound email delivery becomes unreliable or fails for recipients on this domain.',\n\t\tadverseConsequences: 'Critical business and security communications may be delayed, bounced, or silently lost.',\n\t},\n\t{\n\t\tcheckType: 'NS',\n\t\ttitleIncludes: ['no soa record', 'nameserver', 'low nameserver diversity'],\n\t\timpact: 'DNS resilience and consistency are reduced, increasing partial or full resolution outage risk.',\n\t\tadverseConsequences: 'Availability incidents can affect websites, APIs, and transactional workflows.',\n\t},\n\t{\n\t\tcheckType: 'CAA',\n\t\ttitleIncludes: ['no caa records', 'issuewild', 'iodef'],\n\t\timpact: 'Certificate governance controls are weakened, especially for unauthorized or wildcard issuance.',\n\t\tadverseConsequences: 'TLS trust incidents and audit findings become more likely if certificate misuse occurs.',\n\t},\n\t{\n\t\tcheckType: 'SPF',\n\t\ttitleIncludes: ['permissive spf: +all', 'multiple spf records'],\n\t\tdetailIncludes: ['+all', 'multiple records'],\n\t\timpact: 'SPF policy becomes ineffective or ambiguous, allowing unauthorized senders to appear legitimate.',\n\t\tadverseConsequences: 'Spoofing, phishing, and deliverability failures can increase simultaneously.',\n\t},\n\t{\n\t\tcheckType: 'MTA_STS',\n\t\ttitleIncludes: ['no mta-sts', 'testing mode', 'tls-rpt'],\n\t\timpact: 'SMTP transport protections are not consistently enforced for inbound mail delivery.',\n\t\tadverseConsequences: 'Confidential email may traverse weaker paths, increasing confidentiality and regulatory risk.',\n\t},\n];","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Explain Finding tool.\n * Provides static explanations for DNS security findings.\n * No AI binding required - uses a built-in knowledge base.\n */\n\nimport type { OutputFormat } from '../handlers/tool-args';\nimport { sanitizeOutputText } from '../lib/output-sanitize';\n\nimport {\n\tCATEGORY_FALLBACK_IMPACT,\n\tCATEGORY_TO_CHECKTYPE,\n\tDEFAULT_EXPLANATION,\n\tEXPLANATIONS,\n\ttype ExplanationTemplate,\n\ttype ImpactNarrative,\n\tSEVERITY_FALLBACK_IMPACT,\n\tSPECIFIC_IMPACT_RULES,\n} from './explain-finding-data';\n\nexport interface ExplanationResult {\n\tcheckType: string;\n\tstatus: string;\n\tdetails?: string;\n\ttitle: string;\n\tseverity: string;\n\texplanation: string;\n\timpact?: string;\n\tadverseConsequences?: string;\n\trecommendation: string;\n\treferences: string[];\n}\n\ntype ExplanationEntry = ExplanationTemplate;\n\nfunction matchesRule(ruleValues: string[] | undefined, source: string): boolean {\n\tif (!ruleValues || ruleValues.length === 0) return true;\n\treturn ruleValues.some((value) => source.includes(value));\n}\n\nfunction resolveSpecificNarrative(params: {\n\tcheckType?: string;\n\ttitle?: string;\n\tdetail?: string;\n}): ImpactNarrative | undefined {\n\tconst checkType = params.checkType?.toUpperCase();\n\tconst title = params.title?.toLowerCase() ?? '';\n\tconst detail = params.detail?.toLowerCase() ?? '';\n\n\tfor (const rule of SPECIFIC_IMPACT_RULES) {\n\t\tif (rule.checkType && checkType && rule.checkType !== checkType) continue;\n\t\tif (!matchesRule(rule.titleIncludes, title)) continue;\n\t\tif (!matchesRule(rule.detailIncludes, detail)) continue;\n\t\treturn {\n\t\t\timpact: rule.impact,\n\t\t\tadverseConsequences: rule.adverseConsequences,\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction getNarrativeFromEntry(entry: ExplanationEntry | undefined): ImpactNarrative | undefined {\n\tif (!entry) return undefined;\n\tif (!entry.impact && !entry.adverseConsequences) return undefined;\n\treturn {\n\t\timpact: entry.impact,\n\t\tadverseConsequences: entry.adverseConsequences,\n\t};\n}\n\n/**\n * Resolve impact/adverse-consequence narrative for a finding context.\n * Uses explicit explanation entries first, then category, then severity fallback.\n */\nexport function resolveImpactNarrative(params: {\n\tcheckType?: string;\n\tcategory?: string;\n\tstatus?: string;\n\tseverity?: string;\n\ttitle?: string;\n\tdetail?: string;\n}): ImpactNarrative {\n\tconst normalizedCheckType = params.checkType?.toUpperCase();\n\tconst normalizedStatus = params.status?.toUpperCase();\n\tconst normalizedSeverity = params.severity?.toLowerCase();\n\tconst derivedCheckType = params.category ? CATEGORY_TO_CHECKTYPE[params.category.toLowerCase()] : undefined;\n\n\tif (normalizedCheckType && normalizedStatus) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${normalizedCheckType}_${normalizedStatus}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (normalizedCheckType && normalizedSeverity) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${normalizedCheckType}_${normalizedSeverity.toUpperCase()}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (derivedCheckType && normalizedStatus) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${derivedCheckType}_${normalizedStatus}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tif (derivedCheckType && normalizedSeverity) {\n\t\tconst narrative = getNarrativeFromEntry(EXPLANATIONS[`${derivedCheckType}_${normalizedSeverity.toUpperCase()}`]);\n\t\tif (narrative) return narrative;\n\t}\n\n\tconst specificNarrative = resolveSpecificNarrative({\n\t\tcheckType: normalizedCheckType ?? derivedCheckType,\n\t\ttitle: params.title,\n\t\tdetail: params.detail,\n\t});\n\tif (specificNarrative) return specificNarrative;\n\n\tif (normalizedCheckType && CATEGORY_FALLBACK_IMPACT[normalizedCheckType]) {\n\t\treturn CATEGORY_FALLBACK_IMPACT[normalizedCheckType];\n\t}\n\n\tif (derivedCheckType && CATEGORY_FALLBACK_IMPACT[derivedCheckType]) {\n\t\treturn CATEGORY_FALLBACK_IMPACT[derivedCheckType];\n\t}\n\n\tif (normalizedSeverity && SEVERITY_FALLBACK_IMPACT[normalizedSeverity]) {\n\t\treturn SEVERITY_FALLBACK_IMPACT[normalizedSeverity];\n\t}\n\n\treturn {};\n}\n\nexport function explainFinding(checkType: string, status: string, details?: string): ExplanationResult {\n\tconst normalizedType = checkType.toUpperCase();\n\tconst key = `${normalizedType}_${status.toUpperCase()}`;\n\n\t// 1. Try checkType_STATUS key\n\tlet entry: ExplanationTemplate | undefined = EXPLANATIONS[key];\n\n\t// 2. Fall back to default\n\tif (!entry) {\n\t\tentry = DEFAULT_EXPLANATION;\n\t}\n\n\tconst narrative = resolveImpactNarrative({ checkType: normalizedType, status, detail: details });\n\n\treturn {\n\t\tcheckType: normalizedType,\n\t\tstatus,\n\t\tdetails,\n\t\t...entry,\n\t\timpact: entry.impact ?? narrative.impact,\n\t\tadverseConsequences: entry.adverseConsequences ?? narrative.adverseConsequences,\n\t};\n}\n\nexport function formatExplanation(result: ExplanationResult, format: OutputFormat = 'full'): string {\n\tif (format === 'compact') {\n\t\tconst lines = [\n\t\t\t`${result.title} (${result.checkType} | ${result.status})`,\n\t\t\tsanitizeOutputText(result.explanation, 200),\n\t\t\t`Recommendation: ${sanitizeOutputText(result.recommendation, 200)}`,\n\t\t];\n\t\treturn lines.join('\\n');\n\t}\n\n\tconst lines = [`## ${result.title}`, `**Check Type:** ${result.checkType} | **Status:** ${result.status}`, ''];\n\n\tlines.push(`### What this means`, result.explanation, '');\n\n\tif (result.impact) {\n\t\tlines.push(`### Potential Impact`, result.impact, '');\n\t}\n\n\tif (result.adverseConsequences) {\n\t\tlines.push(`### Adverse Consequences`, result.adverseConsequences, '');\n\t}\n\n\tlines.push(`### Recommendation`, result.recommendation, '', `### References`, ...result.references.map((reference) => `- ${reference}`));\n\treturn lines.join('\\n');\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Category interaction scoring — post-scoring adjustments for correlated weaknesses.\n *\n * Applied after computeScanScore() as a separate penalty layer.\n * Does NOT modify categoryScores — only adjusts the overall score.\n * Existing compare_baseline CI/CD workflows continue to work identically.\n */\n\nimport type { CheckCategory, ScanScore } from './scoring-model';\nimport { scoreToGrade } from './scoring-engine';\nimport type { ScoringConfig } from './scoring-config';\n\n/** A condition that must be met for an interaction rule to fire. */\ninterface InteractionCondition {\n\tcategory: CheckCategory;\n\t/** Maximum category score for the condition to be true (score <= maxScore). */\n\tmaxScore?: number;\n\t/** Minimum category score for the condition to be true (score >= minScore). */\n\tminScore?: number;\n}\n\n/** An interaction rule that applies a penalty when all conditions are met. */\nexport interface InteractionRule {\n\t/** Unique identifier for the interaction. */\n\tid: string;\n\t/** All conditions must be satisfied for the penalty to apply. */\n\tconditions: InteractionCondition[];\n\t/** Additional points deducted from the overall score. */\n\toverallPenalty: number;\n\t/** Human-readable explanation of the interaction effect. */\n\tnarrative: string;\n}\n\n/** Result of applying interaction rules to a scan score. */\nexport interface InteractionEffect {\n\truleId: string;\n\tpenalty: number;\n\tnarrative: string;\n}\n\n/** Interaction rules — correlated weaknesses that amplify risk. */\nexport const INTERACTION_RULES: InteractionRule[] = [\n\t{\n\t\tid: 'weak_dkim_permissive_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'dkim', maxScore: 40 },\n\t\t\t{ category: 'dmarc', maxScore: 60 },\n\t\t],\n\t\toverallPenalty: 5,\n\t\tnarrative: 'Weak DKIM combined with permissive DMARC creates multiplicative spoofing risk — attackers can forge messages that pass relaxed alignment checks.',\n\t},\n\t{\n\t\tid: 'no_spf_no_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'spf', maxScore: 0 },\n\t\t\t{ category: 'dmarc', maxScore: 0 },\n\t\t],\n\t\toverallPenalty: 10,\n\t\tnarrative: 'Complete absence of both SPF and DMARC means any server can send as this domain with no detection mechanism.',\n\t},\n\t{\n\t\tid: 'weak_dnssec_enforcing_dmarc',\n\t\tconditions: [\n\t\t\t{ category: 'dmarc', minScore: 80 },\n\t\t\t{ category: 'dnssec', maxScore: 40 },\n\t\t],\n\t\toverallPenalty: 3,\n\t\tnarrative: 'Strong email authentication is in place but DNSSEC is weak or absent — DNS tampering could undermine authentication records.',\n\t},\n\t{\n\t\tid: 'no_spf_no_dkim',\n\t\tconditions: [\n\t\t\t{ category: 'spf', maxScore: 0 },\n\t\t\t{ category: 'dkim', maxScore: 0 },\n\t\t],\n\t\toverallPenalty: 5,\n\t\tnarrative: 'Neither SPF nor DKIM is configured — DMARC alignment cannot be satisfied through either mechanism, making enforcement ineffective even if DMARC is published.',\n\t},\n\t{\n\t\tid: 'weak_ssl_no_http_security',\n\t\tconditions: [\n\t\t\t{ category: 'ssl', maxScore: 40 },\n\t\t\t{ category: 'http_security', maxScore: 30 },\n\t\t],\n\t\toverallPenalty: 3,\n\t\tnarrative: 'Weak SSL/TLS combined with missing HTTP security headers exposes the domain to man-in-the-middle attacks and content injection.',\n\t},\n];\n\n/** Check if a single condition is satisfied by the category scores. */\nfunction conditionMet(condition: InteractionCondition, categoryScores: Record<string, number>): boolean {\n\tconst score = categoryScores[condition.category];\n\tif (score === undefined) return false;\n\n\tif (condition.maxScore !== undefined && score > condition.maxScore) return false;\n\tif (condition.minScore !== undefined && score < condition.minScore) return false;\n\n\treturn true;\n}\n\n/**\n * Apply interaction penalties to a scan score.\n *\n * This is a post-scoring adjustment — categoryScores remain unchanged,\n * only the overall score and grade are updated.\n *\n * @param score - The computed scan score from computeScanScore()\n * @param config - Optional scoring config for grade computation\n * @returns Updated score with interaction penalties applied, plus the list of triggered effects\n */\nexport function applyInteractionPenalties(\n\tscore: ScanScore,\n\tconfig?: ScoringConfig,\n): { adjustedScore: ScanScore; effects: InteractionEffect[] } {\n\tconst effects: InteractionEffect[] = [];\n\tlet totalPenalty = 0;\n\n\tfor (const rule of INTERACTION_RULES) {\n\t\tconst allMet = rule.conditions.every((c) => conditionMet(c, score.categoryScores));\n\t\tif (allMet) {\n\t\t\teffects.push({\n\t\t\t\truleId: rule.id,\n\t\t\t\tpenalty: rule.overallPenalty,\n\t\t\t\tnarrative: rule.narrative,\n\t\t\t});\n\t\t\ttotalPenalty += rule.overallPenalty;\n\t\t}\n\t}\n\n\tif (totalPenalty === 0) {\n\t\treturn { adjustedScore: score, effects };\n\t}\n\n\tconst adjustedOverall = Math.max(0, score.overall - totalPenalty);\n\tconst adjustedGrade = scoreToGrade(adjustedOverall, config);\n\n\t// Update summary if grade changed\n\tlet summary = score.summary;\n\tif (adjustedGrade !== score.grade) {\n\t\tsummary = summary.replace(`Grade: ${score.grade}`, `Grade: ${adjustedGrade}`);\n\t}\n\n\treturn {\n\t\tadjustedScore: {\n\t\t\t...score,\n\t\t\toverall: adjustedOverall,\n\t\t\tgrade: adjustedGrade,\n\t\t\tsummary,\n\t\t},\n\t\teffects,\n\t};\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Structured logging utility for Cloudflare Worker (MCP server)\n * Logs JSON objects with request, tool, result, and error metadata\n * Usage: logEvent({ ... })\n */\n\nexport type LogEvent = {\n\ttimestamp: string;\n\trequestId?: string;\n\tip?: string;\n\ttool?: string;\n\tdomain?: string;\n\tseverity?: 'info' | 'warn' | 'error';\n\tcategory?: string;\n\tresult?: string;\n\tdetails?: unknown;\n\terror?: string;\n\tdurationMs?: number;\n\tuserAgent?: string;\n};\n\nconst REDACTED = '[redacted]';\nconst MAX_LOG_STRING_LENGTH = 256;\nconst SENSITIVE_KEY_PATTERN = /(^ip$|authorization|mcp-session-id|session|token|api[-_]?key|secret|password|cookie|rawbody)/i;\n\nfunction isSensitiveKey(key: string): boolean {\n\treturn !/^has[A-Z]/.test(key) && SENSITIVE_KEY_PATTERN.test(key);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction sanitizeString(value: string): string {\n\t// Strip control characters (except tab) to prevent log injection via newlines/ANSI sequences\n\tconst stripped = value.replace(/[\\x00-\\x08\\x0a-\\x1f\\x7f]/g, ' ');\n\treturn stripped.length > MAX_LOG_STRING_LENGTH ? `${stripped.slice(0, MAX_LOG_STRING_LENGTH)}...` : stripped;\n}\n\nexport function sanitizeLogValue(value: unknown, key?: string): unknown {\n\tif (key && isSensitiveKey(key)) {\n\t\treturn REDACTED;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn sanitizeString(value);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item) => sanitizeLogValue(item));\n\t}\n\n\tif (isPlainObject(value)) {\n\t\tconst sanitized: Record<string, unknown> = {};\n\t\tfor (const [entryKey, entryValue] of Object.entries(value)) {\n\t\t\tsanitized[entryKey] = sanitizeLogValue(entryValue, entryKey);\n\t\t}\n\t\treturn sanitized;\n\t}\n\n\treturn value;\n}\n\nexport function sanitizeHeadersForLog(headers: Headers | Record<string, string>): Record<string, string> {\n\tconst sanitized: Record<string, string> = {};\n\tif (headers instanceof Headers) {\n\t\theaders.forEach((value, rawKey) => {\n\t\t\tconst key = rawKey.toLowerCase();\n\t\t\tsanitized[key] = isSensitiveKey(key) ? REDACTED : sanitizeString(value);\n\t\t});\n\t\treturn sanitized;\n\t}\n\n\tfor (const [rawKey, value] of Object.entries(headers)) {\n\t\tconst key = rawKey.toLowerCase();\n\t\tsanitized[key] = isSensitiveKey(key) ? REDACTED : sanitizeString(value);\n\t}\n\treturn sanitized;\n}\n\n/**\n * Emit a structured log event (console.log as JSON)\n */\nexport function logEvent(event: LogEvent): void {\n\tconst log = {\n\t\t...event,\n\t\ttimestamp: event.timestamp || new Date().toISOString(),\n\t\tdetails: sanitizeLogValue(event.details),\n\t\terror: typeof event.error === 'string' ? sanitizeString(event.error) : event.error,\n\t};\n\tconsole.log(JSON.stringify(log));\n}\n\n/**\n * Helper for error logging\n */\nexport function logError(error: Error | string, context?: Partial<LogEvent>): void {\n\tlogEvent({\n\t\ttimestamp: new Date().toISOString(),\n\t\tseverity: 'error',\n\t\terror: typeof error === 'string' ? error : error.message,\n\t\t...context,\n\t});\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { INFLIGHT_CLEANUP_MS } from './config';\nimport { logError } from './log';\n\n/**\n * TTL cache for DNS scan results.\n *\n * Uses Cloudflare KV for persistent caching when available,\n * with in-memory fallback when KV is not configured.\n *\n * Cloudflare Workers compatible - no Node.js APIs.\n */\n\ninterface CacheEntry<T> {\n\tvalue: T;\n\texpiresAt: number;\n}\n\ninterface CacheOptions {\n\t/** Time-to-live in milliseconds. Default: 5 minutes (300_000ms) */\n\tttlMs?: number;\n\t/** Maximum number of entries. Default: 1000 */\n\tmaxEntries?: number;\n}\n\nconst DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_TTL_SECONDS = 300; // 5 minutes in seconds (for KV expirationTtl)\nconst DEFAULT_MAX_ENTRIES = 1000;\n\nexport class TTLCache<T = unknown> {\n\tprivate readonly store = new Map<string, CacheEntry<T>>();\n\tprivate readonly ttlMs: number;\n\tprivate readonly maxEntries: number;\n\n\tconstructor(options: CacheOptions = {}) {\n\t\tthis.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;\n\t\tthis.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n\t}\n\n\t/**\n\t * Get a cached value by key. Returns undefined if not found or expired.\n\t */\n\tget(key: string): T | undefined {\n\t\tconst entry = this.store.get(key);\n\t\tif (!entry) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (Date.now() > entry.expiresAt) {\n\t\t\tthis.store.delete(key);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn entry.value;\n\t}\n\n\t/**\n\t * Set a value in the cache with optional custom TTL.\n\t */\n\tset(key: string, value: T, ttlMs?: number): void {\n\t\t// Evict expired entries if at capacity\n\t\tif (this.store.size >= this.maxEntries && !this.store.has(key)) {\n\t\t\tthis.evictExpired();\n\t\t}\n\t\t// If still at capacity after eviction, remove oldest entry\n\t\tif (this.store.size >= this.maxEntries && !this.store.has(key)) {\n\t\t\tconst firstKey = this.store.keys().next().value;\n\t\t\tif (firstKey !== undefined) {\n\t\t\t\tthis.store.delete(firstKey);\n\t\t\t}\n\t\t}\n\t\tthis.store.set(key, {\n\t\t\tvalue,\n\t\t\texpiresAt: Date.now() + (ttlMs ?? this.ttlMs),\n\t\t});\n\t}\n\n\t/**\n\t * Check if a key exists and is not expired.\n\t */\n\thas(key: string): boolean {\n\t\treturn this.get(key) !== undefined;\n\t}\n\n\t/**\n\t * Delete a specific key from the cache.\n\t */\n\tdelete(key: string): boolean {\n\t\treturn this.store.delete(key);\n\t}\n\n\t/**\n\t * Remove all entries from the cache.\n\t */\n\tclear(): void {\n\t\tthis.store.clear();\n\t}\n\n\t/**\n\t * Get the number of entries (including potentially expired ones).\n\t */\n\tget size(): number {\n\t\treturn this.store.size;\n\t}\n\n\t/**\n\t * Remove all expired entries from the cache.\n\t */\n\tevictExpired(): number {\n\t\tconst now = Date.now();\n\t\tlet evicted = 0;\n\t\tfor (const [key, entry] of this.store) {\n\t\t\tif (now > entry.expiresAt) {\n\t\t\t\tthis.store.delete(key);\n\t\t\t\tevicted++;\n\t\t\t}\n\t\t}\n\t\treturn evicted;\n\t}\n}\n\n/** In-flight promise map for cache stampede (thundering herd) protection */\nconst INFLIGHT = new Map<string, Promise<unknown>>();\n\n/** In-memory cache instance used as fallback when KV is unavailable */\nexport const IN_MEMORY_CACHE = new TTLCache<unknown>({\n\tttlMs: DEFAULT_TTL_MS,\n\tmaxEntries: DEFAULT_MAX_ENTRIES,\n});\n\n// ---------------------------------------------------------------------------\n// KV-backed cache functions\n// ---------------------------------------------------------------------------\n\n/**\n * Get a cached value by key.\n * Uses KV when available, falls back to in-memory.\n *\n * @param key - Cache key\n * @param kv - Optional KV namespace for persistent caching\n */\nexport async function cacheGet<T>(key: string, kv?: KVNamespace): Promise<T | undefined> {\n if (kv) {\n\t try {\n\t\t const val = await kv.get(key, 'json');\n\t\t return (val ?? undefined) as T | undefined; // KV.get('json') returns unknown; generic T is caller-enforced\n\t } catch {\n\t\t // KV error — log warning and fall through to in-memory\n\t\t logError('[cache] KV get failed, falling back to in-memory');\n\t }\n }\n return IN_MEMORY_CACHE.get(key) as T | undefined;\n}\n\n/**\n * Set a cached value with configurable TTL.\n * Uses KV when available, falls back to in-memory.\n *\n * @param key - Cache key\n * @param value - Value to cache (must be JSON-serializable for KV)\n * @param kv - Optional KV namespace for persistent caching\n * @param ttlSeconds - Cache TTL in seconds (default: 300 = 5 minutes)\n */\n/**\n * Set a cached value, deferring the KV write via ctx.waitUntil() to avoid blocking the response.\n * Falls back to synchronous cacheSet when no ExecutionContext is provided.\n */\nexport function cacheSetDeferred(key: string, value: unknown, ctx: ExecutionContext, kv?: KVNamespace, ttlSeconds?: number): void {\n\tctx.waitUntil(cacheSet(key, value, kv, ttlSeconds));\n}\n\nexport async function cacheSet(key: string, value: unknown, kv?: KVNamespace, ttlSeconds?: number): Promise<void> {\n const ttl = ttlSeconds ?? DEFAULT_TTL_SECONDS;\n if (kv) {\n\t try {\n\t\t await kv.put(key, JSON.stringify(value), { expirationTtl: ttl });\n\t\t return;\n\t } catch {\n\t\t // KV error — log warning and fall through to in-memory\n\t\t logError('[cache] KV put failed, falling back to in-memory');\n\t }\n }\n IN_MEMORY_CACHE.set(key, value, ttl * 1000);\n}\n\n/**\n * Run a function with cache-aside logic: returns cached value if available,\n * otherwise executes the function and caches the result.\n * Includes in-flight deduplication to prevent cache stampedes.\n *\n * @param key - Cache key\n * @param run - Async function to execute on cache miss\n * @param kv - Optional KV namespace for persistent caching\n * @param ttlSeconds - Cache TTL in seconds (default: 300 = 5 minutes)\n * @param skipCache - When true, bypass cache lookup and always execute the function (result is still cached)\n * @returns The cached or freshly computed result\n */\nexport async function runWithCache<T>(key: string, run: () => Promise<T>, kv?: KVNamespace, ttlSeconds?: number, skipCache?: boolean): Promise<T> {\n\tif (!skipCache) {\n\t\tconst cached = await cacheGet<T>(key, kv);\n\t\tif (cached !== undefined) return cached;\n\t}\n\n\tconst existing = INFLIGHT.get(key);\n\tif (existing) return existing as Promise<T>; // INFLIGHT map stores Promise<unknown>; keyed by same cache key ensures type match\n\n\tconst cleanup = setTimeout(() => INFLIGHT.delete(key), INFLIGHT_CLEANUP_MS);\n\tconst promise = run()\n\t\t.then(async (result) => {\n\t\t\tawait cacheSet(key, result, kv, ttlSeconds);\n\t\t\treturn result;\n\t\t})\n\t\t.finally(() => {\n\t\t\tclearTimeout(cleanup);\n\t\t\tINFLIGHT.delete(key);\n\t\t});\n\n\tINFLIGHT.set(key, promise);\n\treturn promise;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * HTTP security headers check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n * Post-augments with CDN provider detection from response headers.\n */\n\nimport { checkHTTPSecurity } from '@blackveil/dns-checks';\nimport type { CheckResult } from '../lib/scoring';\nimport { createFinding } from '../lib/scoring';\nimport { HTTPS_TIMEOUT_MS } from '../lib/config';\n\n/** Detect CDN provider from HTTP response headers. Returns provider name or null. */\nfunction detectCdnProvider(headers: Headers): string | null {\n\tif (headers.get('cf-ray') || headers.get('server')?.toLowerCase().includes('cloudflare')) {\n\t\treturn 'Cloudflare';\n\t}\n\tif (headers.get('x-vercel-id') || headers.get('x-vercel-cache')) {\n\t\treturn 'Vercel';\n\t}\n\tif (headers.get('x-amz-cf-id') || headers.get('via')?.includes('CloudFront')) {\n\t\treturn 'CloudFront';\n\t}\n\tconst servedBy = headers.get('x-served-by') ?? '';\n\tif (servedBy.includes('cache') || headers.get('via')?.toLowerCase().includes('varnish')) {\n\t\treturn 'Fastly';\n\t}\n\tif (headers.get('x-akamai-transformed') || headers.get('x-check-cacheable')) {\n\t\treturn 'Akamai';\n\t}\n\treturn null;\n}\n\n/**\n * Check HTTP security headers for a domain.\n * Fetches the HTTPS endpoint and analyzes browser security headers.\n * Detects CDN provider and adds an info finding when CDN headers are present.\n */\nexport async function checkHttpSecurity(domain: string): Promise<CheckResult> {\n\tlet capturedHeaders: Headers | null = null;\n\tconst capturingFetch: typeof fetch = async (input, init) => {\n\t\tconst response = await fetch(input, init);\n\t\tcapturedHeaders = response.headers;\n\t\treturn response;\n\t};\n\n\tconst result = await checkHTTPSecurity(domain, capturingFetch, { timeout: HTTPS_TIMEOUT_MS }) as CheckResult;\n\n\tif (!capturedHeaders) return result;\n\n\tconst cdnProvider = detectCdnProvider(capturedHeaders);\n\tif (!cdnProvider) return result;\n\n\t// Only annotate CDN when headers were actually analyzed.\n\t// If the check was blocked (WAF, connection refused, etc.) or timed out,\n\t// capturedHeaders may reflect the error response, not the security response.\n\tconst isUnanalyzable =\n\t\tresult.checkStatus === 'error' ||\n\t\tresult.checkStatus === 'timeout' ||\n\t\tresult.findings.some((f) => f.metadata?.missingControl === true);\n\tif (isUnanalyzable) return result;\n\n\tconst cdnFinding = createFinding(\n\t\t'http_security',\n\t\t`HTTP headers via ${cdnProvider} CDN`,\n\t\t'info',\n\t\t`HTTP security headers may be provided by ${cdnProvider} CDN rather than the origin server. CDN-applied headers do not reflect the origin server's security configuration.`,\n\t\t{ cdnProvider },\n\t);\n\n\treturn { ...result, findings: [...result.findings, cdnFinding] };\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DANE (DNS-Based Authentication of Named Entities) check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDANE } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DANE TLSA records for a domain's MX servers and HTTPS endpoint.\n */\nexport async function checkDane(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDANE(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * DANE-HTTPS check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkDANEHTTPS } from '@blackveil/dns-checks';\nimport { queryDns, queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check DANE TLSA records for a domain's HTTPS endpoint (_443._tcp.{domain}).\n */\nexport async function checkDaneHttps(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkDANEHTTPS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{\n\t\t\ttimeout: dnsOptions?.timeoutMs ?? 5000,\n\t\t\trawQueryDNS: async (d, type, dnssecFlag) => {\n\t\t\t\tconst resp = await queryDns(d, type as Parameters<typeof queryDns>[1], dnssecFlag ?? false, dnsOptions);\n\t\t\t\treturn { AD: resp.AD, Answer: resp.Answer };\n\t\t\t},\n\t\t},\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SVCB/HTTPS DNS record check tool (RFC 9460).\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSVCBHTTPS } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check HTTPS/SVCB records (RFC 9460) for a domain.\n */\nexport async function checkSvcbHttps(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSVCBHTTPS(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * SubdoMailing check tool.\n * Thin wrapper around @blackveil/dns-checks — delegates all logic to the shared package.\n */\n\nimport { checkSubdomailing as checkSubdomailingCore } from '@blackveil/dns-checks';\nimport { queryDnsRecords, queryTxtRecords } from '../lib/dns';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport type { CheckResult } from '../lib/scoring';\n\nfunction makeQueryDNS(dnsOptions?: QueryDnsOptions) {\n\treturn async (domain: string, type: string): Promise<string[]> => {\n\t\tif (type === 'TXT') {\n\t\t\treturn queryTxtRecords(domain, dnsOptions);\n\t\t}\n\t\treturn queryDnsRecords(domain, type as Parameters<typeof queryDnsRecords>[1], dnsOptions);\n\t};\n}\n\n/**\n * Check for SubdoMailing risk by analyzing SPF include chain for takeover-vulnerable domains.\n */\nexport async function checkSubdomailing(domain: string, dnsOptions?: QueryDnsOptions): Promise<CheckResult> {\n\treturn checkSubdomailingCore(\n\t\tdomain,\n\t\tmakeQueryDNS(dnsOptions),\n\t\t{ timeout: dnsOptions?.timeoutMs ?? 5000 },\n\t) as Promise<CheckResult>;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport { type CheckCategory, type CheckResult, type Finding, buildCheckResult, createFinding } from '../../lib/scoring';\nimport { queryTxtRecords } from '../../lib/dns';\nimport { detectProviderMatches, detectProviderMatchesBySelectors, loadProviderSignatures } from '../../lib/provider-signatures';\nimport { parseDmarcTags } from '../check-dmarc';\n\nexport interface ScanRuntimeOptions {\n\tproviderSignaturesUrl?: string;\n\tproviderSignaturesAllowedHosts?: string[];\n\tproviderSignaturesSha256?: string;\n\tprofile?: 'mail_enabled' | 'enterprise_mail' | 'non_mail' | 'web_only' | 'minimal' | 'auto';\n\tprofileAccumulator?: DurableObjectNamespace;\n\twaitUntil?: (promise: Promise<unknown>) => void;\n\tscoringConfig?: import('../../lib/scoring-config').ScoringConfig;\n\t/** Override cache TTL in seconds (default: 300). Clamped to [60, 3600]. */\n\tcacheTtlSeconds?: number;\n\t/** Custom secondary DoH resolver config (bv-dns). Threaded to scanDns but only active when skipSecondaryConfirmation is false. */\n\tsecondaryDoh?: import('../../lib/dns-types').SecondaryDohConfig;\n\t/** Bypass cache and run a fresh scan. Useful for troubleshooting after DNS changes. */\n\tforceRefresh?: boolean;\n}\n\nexport async function applyScanPostProcessing(\n\tdomain: string,\n\tcheckResults: CheckResult[],\n\truntimeOptions?: ScanRuntimeOptions,\n): Promise<CheckResult[]> {\n\tlet results = checkResults;\n\tconst mxResult = results.find((result) => result.category === 'mx');\n\tconst hasNoMx = mxResult ? mxResult.findings.some((finding: Finding) => finding.title === 'No MX records found') : false;\n\n\tif (hasNoMx) {\n\t\tconst apexCovers = await checkApexDmarcPolicy(domain);\n\t\tresults = adjustForNonMailDomain(results, apexCovers);\n\t\tresults = adjustBimiForNonMailDomain(results);\n\t} else if (mxResult) {\n\t\tresults = clarifyMtaStsForMailDomain(domain, results);\n\t}\n\n\t// Detect no-send SPF policy (v=spf1 -all with no authorizing mechanisms)\n\tconst spfResult = results.find((result) => result.category === 'spf');\n\tconst hasNoSendPolicy = spfResult?.findings.some((f: Finding) => f.metadata?.noSendPolicy === true) ?? false;\n\tif (hasNoSendPolicy && !hasNoMx) {\n\t\tresults = adjustForNoSendDomain(results);\n\t}\n\n\treturn addOutboundProviderInference(results, runtimeOptions);\n}\n\nfunction extractSpfSignalDomains(result: CheckResult | undefined): string[] {\n\tif (!result) return [];\n\n\tconst domains = new Set<string>();\n\tfor (const finding of result.findings) {\n\t\tconst metadata = finding.metadata;\n\t\tif (!metadata || typeof metadata !== 'object') continue;\n\n\t\tconst includeDomains = metadata.includeDomains;\n\t\tif (Array.isArray(includeDomains)) {\n\t\t\tfor (const domain of includeDomains) {\n\t\t\t\tif (typeof domain === 'string' && domain.trim().length > 0) {\n\t\t\t\t\tdomains.add(domain.trim().toLowerCase());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst redirectDomain = metadata.redirectDomain;\n\t\tif (typeof redirectDomain === 'string' && redirectDomain.trim().length > 0) {\n\t\t\tdomains.add(redirectDomain.trim().toLowerCase());\n\t\t}\n\t}\n\n\treturn Array.from(domains);\n}\n\nfunction extractDkimSignalSelectors(result: CheckResult | undefined): string[] {\n\tif (!result) return [];\n\n\tconst selectors = new Set<string>();\n\tfor (const finding of result.findings) {\n\t\tconst metadata = finding.metadata;\n\t\tif (!metadata || typeof metadata !== 'object') continue;\n\n\t\tconst selectorsFound = metadata.selectorsFound;\n\t\tif (!Array.isArray(selectorsFound)) continue;\n\n\t\tfor (const selector of selectorsFound) {\n\t\t\tif (typeof selector === 'string' && selector.trim().length > 0) {\n\t\t\t\tselectors.add(selector.trim().toLowerCase());\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(selectors);\n}\n\nfunction upsertCheckResult(results: CheckResult[], updated: CheckResult): CheckResult[] {\n\treturn results.map((result) => (result.category === updated.category ? updated : result));\n}\n\nasync function addOutboundProviderInference(results: CheckResult[], runtimeOptions?: ScanRuntimeOptions): Promise<CheckResult[]> {\n\tconst spfResult = results.find((result) => result.category === 'spf');\n\tconst dkimResult = results.find((result) => result.category === 'dkim');\n\n\tconst signalDomains = extractSpfSignalDomains(spfResult);\n\tconst dkimSelectors = extractDkimSignalSelectors(dkimResult);\n\tif (signalDomains.length === 0 && dkimSelectors.length === 0) return results;\n\n\tconst signatures = await loadProviderSignatures({\n\t\tsourceUrl: runtimeOptions?.providerSignaturesUrl,\n\t\tallowedHosts: runtimeOptions?.providerSignaturesAllowedHosts,\n\t\texpectedSha256: runtimeOptions?.providerSignaturesSha256,\n\t});\n\tconst signatureSet = signatures.outbound.length > 0 ? signatures.outbound : signatures.inbound;\n\tconst hostMatches = detectProviderMatches(signalDomains, signatureSet);\n\tconst selectorMatches = detectProviderMatchesBySelectors(dkimSelectors, signatureSet);\n\n\tconst mergedMatches = new Map<string, Set<string>>();\n\tfor (const match of [...hostMatches, ...selectorMatches]) {\n\t\tif (!mergedMatches.has(match.provider)) {\n\t\t\tmergedMatches.set(match.provider, new Set<string>());\n\t\t}\n\t\tfor (const evidence of match.matches) {\n\t\t\tmergedMatches.get(match.provider)?.add(evidence);\n\t\t}\n\t}\n\n\tconst outboundMatches = Array.from(mergedMatches.entries()).map(([provider, matches]) => ({\n\t\tprovider,\n\t\tmatches: Array.from(matches),\n\t}));\n\tif (outboundMatches.length === 0) return results;\n\n\tconst providerNames = outboundMatches.map((match) => match.provider).join(', ');\n\tconst evidence = outboundMatches.map((match) => `${match.provider}: ${match.matches.join(', ')}`).join('; ');\n\tconst signalBoost = signalDomains.length > 0 && dkimSelectors.length > 0 ? 0.05 : 0;\n\tconst baseConfidence = signatures.source === 'runtime' ? 0.85 : signatures.source === 'stale' ? 0.7 : 0.65;\n\tconst providerConfidence = Math.min(0.95, baseConfidence + signalBoost);\n\n\tconst spfBaseline = spfResult ?? buildCheckResult('spf', []);\n\tconst updatedSpf = buildCheckResult('spf', [\n\t\t...spfBaseline.findings,\n\t\tcreateFinding('spf', 'Outbound email provider inferred', 'info', `Outbound provider(s): ${providerNames}. Evidence: ${evidence}.`, {\n\t\t\tdetectionType: 'outbound',\n\t\t\tproviders: outboundMatches.map((match) => ({ name: match.provider, matches: match.matches })),\n\t\t\tsignalsUsed: {\n\t\t\t\tspfDomains: signalDomains,\n\t\t\t\tdkimSelectors,\n\t\t\t},\n\t\t\tproviderConfidence,\n\t\t\tsignatureSource: signatures.source,\n\t\t\tsignatureVersion: signatures.version,\n\t\t\tsignatureFetchedAt: signatures.fetchedAt,\n\t\t}),\n\t]);\n\n\treturn upsertCheckResult(results, updatedSpf);\n}\n\nfunction getParentDomain(domain: string): string | null {\n\tconst parts = domain.split('.');\n\tif (parts.length <= 2) return null;\n\treturn parts.slice(1).join('.');\n}\n\nasync function checkApexDmarcPolicy(domain: string): Promise<boolean> {\n\tconst parent = getParentDomain(domain);\n\tif (!parent) return false;\n\n\ttry {\n\t\tconst records = await queryTxtRecords(`_dmarc.${parent}`);\n\t\tconst dmarcRecord = records.find((record) => record.toLowerCase().startsWith('v=dmarc1'));\n\t\tif (!dmarcRecord) return false;\n\n\t\tconst tags = parseDmarcTags(dmarcRecord);\n\t\tconst effectivePolicy = tags.get('sp') || tags.get('p') || '';\n\t\treturn effectivePolicy === 'quarantine' || effectivePolicy === 'reject';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isMissingRecordFinding(finding: { title: string; detail: string }): boolean {\n\t// Match against title only (controlled by check modules, not DNS data) to avoid ReDoS on attacker-controlled detail strings\n\tconst title = finding.title.toLowerCase();\n\treturn (\n\t\ttitle.includes('missing') ||\n\t\ttitle.includes('not found') ||\n\t\ttitle.includes('no mta-sts') ||\n\t\ttitle.includes('no dkim') ||\n\t\t/^no\\s+\\S+\\s+record/.test(title)\n\t);\n}\n\nfunction clarifyMtaStsForMailDomain(domain: string, results: CheckResult[]): CheckResult[] {\n\treturn results.map((result) => {\n\t\tif (result.category !== 'mta_sts') return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif (finding.title === 'No MTA-STS or TLS-RPT records found') {\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tdetail: `Neither MTA-STS nor TLS-RPT records are present for ${domain}. Since this domain has MX records and accepts email, adding MTA-STS and TLS-RPT is recommended to protect inbound email in transit.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustForNonMailDomain(results: CheckResult[], apexDmarcCovers: boolean): CheckResult[] {\n\tconst emailCategories: CheckCategory[] = ['spf', 'dmarc', 'dkim', 'mta_sts', 'subdomailing'];\n\treturn results.map((result) => {\n\t\tif (!emailCategories.includes(result.category)) return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif ((finding.severity === 'critical' || finding.severity === 'high') && isMissingRecordFinding(finding)) {\n\t\t\t\tconst reason = apexDmarcCovers\n\t\t\t\t\t? 'expected — no MX records and parent domain DMARC policy covers subdomains'\n\t\t\t\t\t: 'expected — domain has no MX records';\n\t\t\t\treturn { ...finding, severity: 'info' as const, detail: `${finding.detail} (${reason})` };\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustBimiForNonMailDomain(results: CheckResult[]): CheckResult[] {\n\treturn results.map((result) => {\n\t\tif (result.category !== 'bimi') return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif (finding.title === 'No BIMI record found' && finding.detail.includes('eligible for BIMI')) {\n\t\t\t\tconst bimiDomain = finding.detail.match(/at (default\\._bimi\\.\\S+)/)?.[1] ?? `default._bimi.unknown`;\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tdetail: `No BIMI record found at ${bimiDomain}. This domain does not appear to send email, so BIMI is not applicable.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}\n\nfunction adjustForNoSendDomain(results: CheckResult[]): CheckResult[] {\n\tconst noSendCategories: CheckCategory[] = ['dkim', 'mta_sts', 'bimi'];\n\treturn results.map((result) => {\n\t\tif (!noSendCategories.includes(result.category)) return result;\n\t\tconst adjusted = result.findings.map((finding: Finding) => {\n\t\t\tif ((finding.severity === 'critical' || finding.severity === 'high') && isMissingRecordFinding(finding)) {\n\t\t\t\treturn {\n\t\t\t\t\t...finding,\n\t\t\t\t\tseverity: 'info' as const,\n\t\t\t\t\tdetail: `${finding.detail} (expected — domain SPF policy rejects all outbound mail)`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn finding;\n\t\t});\n\t\treturn buildCheckResult(result.category, adjusted);\n\t});\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * Email Security Maturity Staging.\n * Classifies a domain's email security posture into a maturity stage (0-4)\n * based on the results of individual DNS security checks.\n */\n\nimport type { CheckResult, Finding } from '../../lib/scoring';\n\nexport interface MaturityStage {\n\tstage: number;\n\tlabel: string;\n\tdescription: string;\n\tnextStep: string;\n}\n\n/**\n * Compute the email security maturity stage from scan check results.\n * Stages range from 0 (Unprotected) to 4 (Hardened).\n */\n/**\n * Cap the maturity stage based on the overall scan score.\n * Prevents a domain from being labeled \"Hardened\" or \"Enforcing\"\n * when the actual security score indicates significant issues.\n *\n * - Score < 50 (F grade): cap at Stage 2 maximum\n * - Score < 63 (D/D+ grade): cap at Stage 3 maximum\n * - Score >= 63: no cap applied\n *\n * Stages already at or below the cap are returned unchanged.\n */\nexport function capMaturityStage(maturity: MaturityStage, score: number): MaturityStage {\n\tif (score < 50 && maturity.stage > 2) {\n\t\treturn {\n\t\t\tstage: 2,\n\t\t\tlabel: 'Monitoring (score-capped)',\n\t\t\tdescription: 'Controls are present but the overall security score is too low for a higher maturity rating.',\n\t\t\tnextStep: 'Address critical and high-severity findings to improve the overall score before advancing maturity.',\n\t\t};\n\t}\n\n\tif (score < 63 && maturity.stage > 3) {\n\t\treturn {\n\t\t\tstage: 3,\n\t\t\tlabel: 'Enforcing (score-capped)',\n\t\t\tdescription: 'Controls are present but the overall security score is too low for the highest maturity rating.',\n\t\t\tnextStep: 'Resolve remaining findings to raise the score above the D grade range and achieve full hardening.',\n\t\t};\n\t}\n\n\treturn maturity;\n}\n\nexport function computeMaturityStage(checks: CheckResult[]): MaturityStage {\n\tconst byCategory = new Map(checks.map((c) => [c.category, c]));\n\n\tconst mxCheck = byCategory.get('mx');\n\tconst spfCheck = byCategory.get('spf');\n\tconst dmarcCheck = byCategory.get('dmarc');\n\tconst dkimCheck = byCategory.get('dkim');\n\tconst mtaStsCheck = byCategory.get('mta_sts');\n\tconst dnssecCheck = byCategory.get('dnssec');\n\tconst bimiCheck = byCategory.get('bimi');\n\n\t// Non-mail domains should not receive email maturity stages.\n\t// The numeric stage values here (0 = \"Unprotected\", 1 = \"DNS-Only\") intentionally\n\t// reuse the same numbers as the mail-domain scale. This is safe because `stage` is\n\t// only ever rendered as a display value alongside `label` — it is never used as a\n\t// numeric index or compared against mail-domain stages in any downstream logic.\n\tconst hasNoMx = mxCheck != null && mxCheck.findings.some((f: Finding) => f.title === 'No MX records found');\n\tif (hasNoMx) {\n\t\tconst hasDnssec = dnssecCheck?.passed ?? false;\n\t\treturn {\n\t\t\tstage: hasDnssec ? 1 : 0,\n\t\t\tlabel: hasDnssec ? 'DNS-Only' : 'Unprotected',\n\t\t\tdescription: hasDnssec\n\t\t\t\t? 'This domain does not accept email. DNS security (DNSSEC) is in place.'\n\t\t\t\t: 'This domain does not accept email and has no DNSSEC.',\n\t\t\tnextStep: hasDnssec ? '' : 'Enable DNSSEC to protect DNS resolution integrity.',\n\t\t};\n\t}\n\n\t// Determine SPF presence\n\tconst hasSpf = spfCheck != null && !spfCheck.findings.some((f: Finding) => /No SPF record/i.test(f.title));\n\n\t// Determine DMARC presence and policy\n\tconst hasDmarc = dmarcCheck != null && !dmarcCheck.findings.some((f: Finding) => /No DMARC record/i.test(f.title));\n\tconst dmarcPolicyNone = dmarcCheck?.findings.some((f: Finding) => /policy set to none/i.test(f.title)) ?? false;\n\tconst dmarcPolicyQuarantine = dmarcCheck?.findings.some((f: Finding) => /policy set to quarantine/i.test(f.title)) ?? false;\n\t// reject = no \"policy set to none\" and no \"policy set to quarantine\" and DMARC exists\n\tconst dmarcPolicyReject = hasDmarc && !dmarcPolicyNone && !dmarcPolicyQuarantine;\n\tconst hasRua = dmarcCheck != null && !dmarcCheck.findings.some((f: Finding) => /No aggregate reporting/i.test(f.title));\n\n\t// Determine MTA-STS, DNSSEC, BIMI\n\tconst hasMtaSts = mtaStsCheck?.passed ?? false;\n\tconst hasDnssec = dnssecCheck?.passed ?? false;\n\tconst hasBimi = bimiCheck?.findings.some((f: Finding) => /BIMI record configured/i.test(f.title)) ?? false;\n\n\t// DANE presence\n\tconst daneCheck = byCategory.get('dane');\n\tconst hasDane = daneCheck?.findings.some((f: Finding) => /DANE TLSA configured/i.test(f.title)) ?? false;\n\n\t// CAA presence (passed = CAA records found)\n\tconst caaCheck = byCategory.get('caa');\n\tconst hasCaa = caaCheck?.passed ?? false;\n\n\t// DKIM \"discovered\" = at least one selector physically found (not provider-implied)\n\t// Provider-implied findings have metadata.detectionMethod === 'provider-implied'\n\tconst hasDkimDiscovered =\n\t\tdkimCheck != null &&\n\t\t!dkimCheck.findings.some((f: Finding) => /No DKIM records found|DKIM selector not discovered/i.test(f.title)) &&\n\t\t!dkimCheck.findings.some((f: Finding) => f.metadata?.detectionMethod === 'provider-implied');\n\n\t// Stage 4 — Hardened: Stage 3 + at least 2 of (MTA-STS, DNSSEC, BIMI, DANE, CAA, DKIM-discovered)\n\t// DKIM is no longer required for Stage 3 — enforcement alone (SPF + DMARC p=quarantine/reject) qualifies\n\tconst isEnforcing = hasSpf && hasDmarc && (dmarcPolicyReject || dmarcPolicyQuarantine);\n\tconst hardeningCount = [hasMtaSts, hasDnssec, hasBimi, hasDane, hasCaa, hasDkimDiscovered].filter(Boolean).length;\n\n\tif (isEnforcing && hardeningCount >= 2) {\n\t\treturn {\n\t\t\tstage: 4,\n\t\t\tlabel: 'Hardened',\n\t\t\tdescription: 'Comprehensive email and DNS security posture with defense in depth.',\n\t\t\tnextStep: '',\n\t\t};\n\t}\n\n\t// Stage 3 — Enforcing: DMARC p=quarantine or p=reject, SPF exists, DKIM exists\n\tif (isEnforcing) {\n\t\treturn {\n\t\t\tstage: 3,\n\t\t\tlabel: 'Enforcing',\n\t\t\tdescription: 'Email authentication is actively enforcing — spoofed emails are blocked or quarantined.',\n\t\t\tnextStep: 'Add MTA-STS, DNSSEC, and BIMI to reach full hardening.',\n\t\t};\n\t}\n\n\t// Stage 2 — Monitoring: SPF + DMARC with p=none and rua= present\n\tif (hasSpf && hasDmarc && dmarcPolicyNone && hasRua) {\n\t\treturn {\n\t\t\tstage: 2,\n\t\t\tlabel: 'Monitoring',\n\t\t\tdescription: 'Email authentication is published and being monitored but not enforcing.',\n\t\t\tnextStep: 'After reviewing DMARC reports, move to p=quarantine and ensure DKIM is active.',\n\t\t};\n\t}\n\n\t// Stage 1 — Basic: SPF exists but DMARC is p=none or DMARC has no rua=\n\tif (hasSpf && hasDmarc) {\n\t\treturn {\n\t\t\tstage: 1,\n\t\t\tlabel: 'Basic',\n\t\t\tdescription: 'Basic email records exist but are not enforcing or monitoring.',\n\t\t\tnextStep: 'Add DMARC aggregate reporting (rua=) and monitor for 2-4 weeks before enforcing.',\n\t\t};\n\t}\n\n\t// Stage 0 — Unprotected\n\treturn {\n\t\tstage: 0,\n\t\tlabel: 'Unprotected',\n\t\tdescription: 'No email authentication — any server can send email as this domain.',\n\t\tnextStep: 'Publish SPF and DMARC records to begin protecting your domain.',\n\t};\n}\n","// SPDX-License-Identifier: BUSL-1.1\n\nimport type { ScanDomainResult } from '../scan-domain';\nimport type { Finding } from '../../lib/scoring';\nimport type { OutputFormat } from '../../handlers/tool-args';\nimport { sanitizeOutputText } from '../../lib/output-sanitize';\nimport { resolveImpactNarrative } from '../explain-finding';\n\n/** Structured scan result for machine-readable consumption (e.g., CI/CD actions). */\nexport interface StructuredScanResult {\n\tdomain: string;\n\tscore: number;\n\tgrade: string;\n\tpassed: boolean;\n\tmaturityStage: number | null;\n\tmaturityLabel: string | null;\n\tcategoryScores: Record<string, number>;\n\tfindingCounts: { critical: number; high: number; medium: number; low: number };\n\tscoringProfile: string;\n\tscoringSignals: string[];\n\tscoringNote: string | null;\n\tadaptiveWeightDeltas: Record<string, number> | null;\n\t/** Percentile rank within the scoring profile population (0–100). Null when insufficient benchmark data. */\n\tpercentileRank: number | null;\n\t/** Composite email spoofability score (0–100, higher = more spoofable). Null when not computed. */\n\tspoofabilityScore: number | null;\n\t/** Category interaction effects applied as post-scoring adjustments. */\n\tinteractionEffects: Array<{ ruleId: string; penalty: number; narrative: string }>;\n\t/** Execution status per check category. 'completed' = ran normally, 'timeout' = per-check timeout, 'error' = threw. */\n\tcheckStatuses: Record<string, 'completed' | 'timeout' | 'error'>;\n\t/** DNSSEC configuration source. 'domain_configured' = domain has own DNSKEY/DS; 'tld_inherited' = inherited from TLD registry. null = not yet available. */\n\tdnssecSource: 'domain_configured' | 'tld_inherited' | null;\n\t/** CDN provider detected from HTTP response headers. null when no CDN detected or check did not run. */\n\tcdnProvider: string | null;\n\t/** Email categories that scored 100 due to web-only/non-mail profile (no MX). Downstream consumers should treat these as N/A rather than perfect. */\n\tnotApplicableCategories: string[];\n\ttimestamp: string;\n\tcached: boolean;\n}\n\n/** Optional enrichment data for structured scan results. */\nexport interface ScanResultEnrichment {\n\tpercentileRank?: number | null;\n\tspoofabilityScore?: number | null;\n}\n\n/** Build a machine-readable structured result from a scan. */\nexport function buildStructuredScanResult(result: ScanDomainResult, enrichment?: ScanResultEnrichment): StructuredScanResult {\n\t// checkStatuses\n\tconst checkStatuses: Record<string, 'completed' | 'timeout' | 'error'> = {};\n\tfor (const check of result.checks) {\n\t\tcheckStatuses[check.category] = check.checkStatus ?? 'completed';\n\t}\n\n\t// dnssecSource\n\tconst dnssecCheck = result.checks.find((c) => c.category === 'dnssec');\n\tlet dnssecSource: 'domain_configured' | 'tld_inherited' | null = null;\n\tif (dnssecCheck) {\n\t\tfor (const f of dnssecCheck.findings) {\n\t\t\tconst src = f.metadata?.dnssecSource;\n\t\t\tif (src === 'domain_configured' || src === 'tld_inherited') {\n\t\t\t\tdnssecSource = src as 'domain_configured' | 'tld_inherited';\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (dnssecSource === null && dnssecCheck.passed && (checkStatuses['dnssec'] ?? 'completed') === 'completed') {\n\t\t\tdnssecSource = 'domain_configured';\n\t\t}\n\t}\n\n\t// cdnProvider\n\tconst httpCheck = result.checks.find((c) => c.category === 'http_security');\n\tlet cdnProvider: string | null = null;\n\tif (httpCheck) {\n\t\tfor (const f of httpCheck.findings) {\n\t\t\tconst cdn = f.metadata?.cdnProvider;\n\t\t\tif (typeof cdn === 'string') {\n\t\t\t\tcdnProvider = cdn;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// notApplicableCategories\n\tconst emailCategories = ['spf', 'dmarc', 'dkim', 'mta_sts'];\n\tconst isNonMailProfile = ['non_mail', 'web_only'].includes(result.context?.profile ?? '');\n\tconst notApplicableCategories: string[] = [];\n\tif (isNonMailProfile) {\n\t\tfor (const check of result.checks) {\n\t\t\tif (emailCategories.includes(check.category)) {\n\t\t\t\tconst allInfo = check.findings.length > 0 && check.findings.every((f: Finding) => f.severity === 'info');\n\t\t\t\tconst noFindings = check.findings.length === 0 && check.score === 100;\n\t\t\t\tif (allInfo || noFindings) {\n\t\t\t\t\tnotApplicableCategories.push(check.category);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdomain: result.domain,\n\t\tscore: result.score.overall,\n\t\tgrade: result.score.grade,\n\t\tpassed: result.score.overall >= 50,\n\t\tmaturityStage: result.maturity?.stage ?? null,\n\t\tmaturityLabel: result.maturity?.label ?? null,\n\t\tcategoryScores: result.score.categoryScores,\n\t\tfindingCounts: {\n\t\t\tcritical: result.score.findings.filter((f: Finding) => f.severity === 'critical').length,\n\t\t\thigh: result.score.findings.filter((f: Finding) => f.severity === 'high').length,\n\t\t\tmedium: result.score.findings.filter((f: Finding) => f.severity === 'medium').length,\n\t\t\tlow: result.score.findings.filter((f: Finding) => f.severity === 'low').length,\n\t\t},\n\t\tscoringProfile: result.context?.profile ?? 'mail_enabled',\n\t\tscoringSignals: (result.context?.signals ?? []).map((s: string) => s.replace(/[<>&\"']/g, '')),\n\t\tscoringNote: result.scoringNote ?? null,\n\t\tadaptiveWeightDeltas: result.adaptiveWeightDeltas ?? null,\n\t\tpercentileRank: enrichment?.percentileRank ?? null,\n\t\tspoofabilityScore: enrichment?.spoofabilityScore ?? null,\n\t\tinteractionEffects: (result.interactionEffects ?? []).map((e) => ({\n\t\t\truleId: e.ruleId,\n\t\t\tpenalty: e.penalty,\n\t\t\tnarrative: e.narrative,\n\t\t})),\n\t\tcheckStatuses,\n\t\tdnssecSource,\n\t\tcdnProvider,\n\t\tnotApplicableCategories,\n\t\ttimestamp: result.timestamp,\n\t\tcached: result.cached,\n\t};\n}\n\nexport function formatScanReport(result: ScanDomainResult, format: OutputFormat = 'full'): string {\n\tconst lines: string[] = [];\n\n\tlines.push(`DNS Security Scan: ${result.domain}`);\n\tlines.push(`${'='.repeat(40)}`);\n\tlines.push(`Overall Score: ${result.score.overall}/100 (${result.score.grade})`);\n\tlines.push(`${result.score.summary}`);\n\tlines.push('');\n\n\tif (result.maturity) {\n\t\tif (format === 'compact') {\n\t\t\tlines.push(`Maturity: Stage ${result.maturity.stage} — ${result.maturity.label}`);\n\t\t} else {\n\t\t\tlines.push(`Email Security Maturity: Stage ${result.maturity.stage} — ${result.maturity.label}`);\n\t\t\tlines.push(result.maturity.description);\n\t\t\tif (result.maturity.nextStep) {\n\t\t\t\tlines.push(`Next step: ${result.maturity.nextStep}`);\n\t\t\t}\n\t\t}\n\t\tlines.push('');\n\t}\n\n\tif (format === 'full') {\n\t\tif (result.context) {\n\t\t\tconst signalSummary = result.context.signals.length > 0 ? result.context.signals.join(', ') : 'default';\n\t\t\tlines.push(`Scoring Profile: ${result.context.profile} (${signalSummary})`);\n\t\t\tlines.push('');\n\t\t}\n\n\t\tif (result.scoringNote) {\n\t\t\tlines.push(result.scoringNote);\n\t\t\tlines.push('');\n\t\t}\n\t}\n\n\tconst isNonMailProfile = ['non_mail', 'web_only'].includes(result.context?.profile ?? '');\n\tconst naEmailCategories = new Set(['spf', 'dmarc', 'dkim', 'mta_sts']);\n\n\tlines.push('Category Scores:');\n\tlines.push('-'.repeat(30));\n\tfor (const [category, score] of Object.entries(result.score.categoryScores) as [string, number][]) {\n\t\tif (isNonMailProfile && naEmailCategories.has(category)) {\n\t\t\tconst check = result.checks?.find((c) => c.category === category);\n\t\t\tconst allInfo = check && check.findings.length > 0 && check.findings.every((f: Finding) => f.severity === 'info');\n\t\t\tconst noFindings = !check || (check.findings.length === 0 && score === 100);\n\t\t\tif (allInfo || noFindings) {\n\t\t\t\tlines.push(` ∅ ${category.toUpperCase().padEnd(10)} N/A (web-only, no MX records)`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tconst status = score >= 80 ? '✓' : score >= 50 ? '⚠' : '✗';\n\t\tlines.push(` ${status} ${category.toUpperCase().padEnd(10)} ${score}/100`);\n\t}\n\tlines.push('');\n\n\tconst nonInfoFindings = result.score.findings.filter((finding: Finding) => finding.severity !== 'info');\n\tif (nonInfoFindings.length > 0) {\n\t\tlines.push('Findings:');\n\t\tlines.push('-'.repeat(30));\n\t\tfor (const finding of nonInfoFindings) {\n\t\t\tif (format === 'compact') {\n\t\t\t\tconst isHighPriority = finding.severity === 'critical' || finding.severity === 'high';\n\t\t\t\tconst detailLimit = isHighPriority ? 4000 : 300;\n\t\t\t\tlines.push(` [${finding.severity.toUpperCase()}] ${sanitizeOutputText(finding.title, 120)} — ${sanitizeOutputText(finding.detail, detailLimit)}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlines.push(` [${finding.severity.toUpperCase()}] ${sanitizeOutputText(finding.title, 120)}`);\n\t\t\tlines.push(` ${sanitizeOutputText(finding.detail)}`);\n\t\t\tconst verificationStatus =\n\t\t\t\tfinding.category === 'subdomain_takeover' && finding.metadata?.verificationStatus\n\t\t\t\t\t? String(finding.metadata.verificationStatus)\n\t\t\t\t\t: undefined;\n\t\t\tif (verificationStatus) {\n\t\t\t\tlines.push(` Takeover Verification: ${sanitizeOutputText(verificationStatus, 80)}`);\n\t\t\t}\n\t\t\tconst confidence = finding.metadata?.confidence ? String(finding.metadata.confidence) : undefined;\n\t\t\tif (confidence) {\n\t\t\t\tlines.push(` Confidence: ${sanitizeOutputText(confidence, 80)}`);\n\t\t\t}\n\t\t\tconst narrative = resolveImpactNarrative({\n\t\t\t\tcategory: finding.category,\n\t\t\t\tseverity: finding.severity,\n\t\t\t\ttitle: finding.title,\n\t\t\t\tdetail: finding.detail,\n\t\t\t});\n\t\t\tif (narrative.impact) {\n\t\t\t\tlines.push(` Potential Impact: ${narrative.impact}`);\n\t\t\t}\n\t\t\tif (narrative.adverseConsequences) {\n\t\t\t\tlines.push(` Adverse Consequences: ${narrative.adverseConsequences}`);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlines.push('No security issues found.');\n\t}\n\n\tif (format === 'full' && result.interactionEffects && result.interactionEffects.length > 0) {\n\t\tlines.push('');\n\t\tlines.push('Interaction Effects:');\n\t\tlines.push('-'.repeat(30));\n\t\tfor (const effect of result.interactionEffects) {\n\t\t\tlines.push(` [-${effect.penalty}] ${effect.narrative}`);\n\t\t}\n\t}\n\n\tif (result.cached) {\n\t\tlines.push('');\n\t\tlines.push('(Results served from cache)');\n\t}\n\n\tlines.push('');\n\tlines.push(`Scan completed: ${result.timestamp}`);\n\treturn lines.join('\\n');\n}","// SPDX-License-Identifier: BUSL-1.1\n\n/**\n * scan-domain orchestrator tool.\n * Runs all DNS security checks in parallel via Promise.all\n * and computes an overall security score.\n *\n * Uses KV-backed cache with 5-minute TTL for scan results when available,\n * with in-memory fallback when KV is not configured.\n * Compatible with Cloudflare Workers runtime (no Node.js APIs).\n */\n\nimport {\n\ttype CheckCategory,\n\ttype CheckResult,\n\ttype DomainContext,\n\ttype DomainProfile,\n\ttype ScanScore,\n\tbuildCheckResult,\n\tcomputeScanScore,\n\tcreateFinding,\n\tdetectDomainContext,\n\tgetProfileWeights,\n} from '../lib/scoring';\nimport {\n\tadaptiveWeightsToContext,\n\tgenerateScoringNote,\n\ttype AdaptiveWeightsResponse,\n\ttype ScanTelemetry,\n} from '../lib/adaptive-weights';\nimport { applyInteractionPenalties, type InteractionEffect } from '../lib/category-interactions';\nimport { cacheGet, cacheSet, runWithCache } from '../lib/cache';\nimport type { QueryDnsOptions } from '../lib/dns-types';\nimport { checkSpf } from './check-spf';\nimport { checkDmarc } from './check-dmarc';\nimport { checkDkim, applyProviderDkimContext } from './check-dkim';\nimport { checkDnssec } from './check-dnssec';\nimport { checkSsl } from './check-ssl';\nimport { checkMtaSts } from './check-mta-sts';\nimport { checkNs } from './check-ns';\nimport { checkCaa } from './check-caa';\nimport { checkBimi } from './check-bimi';\nimport { checkTlsrpt } from './check-tlsrpt';\nimport { checkSubdomainTakeover } from './check-subdomain-takeover';\nimport { checkMx } from './check-mx';\nimport { checkHttpSecurity } from './check-http-security';\nimport { checkDane } from './check-dane';\nimport { checkDaneHttps } from './check-dane-https';\nimport { checkSvcbHttps } from './check-svcb-https';\nimport { checkSubdomailing } from './check-subdomailing';\nimport { applyScanPostProcessing } from './scan/post-processing';\nimport type { ScanRuntimeOptions } from './scan/post-processing';\nimport { capMaturityStage, computeMaturityStage } from './scan/maturity-staging';\nimport type { MaturityStage } from './scan/maturity-staging';\nexport { formatScanReport, buildStructuredScanResult } from './scan/format-report';\nexport type { StructuredScanResult, ScanResultEnrichment } from './scan/format-report';\nexport type { MaturityStage } from './scan/maturity-staging';\nexport type { ScanRuntimeOptions } from './scan/post-processing';\n\n/** Cache key prefix for scan and per-check results */\nconst CACHE_PREFIX = 'cache:';\n\n/** Maximum wall-clock time for a single check within scan_domain (ms). */\nconst PER_CHECK_TIMEOUT_MS = 8_000;\n\n/** Maximum wall-clock time for the entire scan_domain orchestration (ms). */\nconst SCAN_TIMEOUT_MS = 12_000;\n\n/** In-memory cache for adaptive weight responses from the ProfileAccumulator DO. */\nconst adaptiveWeightCache = new Map<string, { weights: AdaptiveWeightsResponse; expires: number }>();\n\n/** TTL for the in-memory adaptive weight cache (ms). */\nconst ADAPTIVE_CACHE_TTL_MS = 60_000;\n\n/** Maximum entries in the adaptive weight cache before eviction. */\nconst ADAPTIVE_CACHE_MAX_ENTRIES = 100;\n\n/** Timeout for fetching adaptive weights from the DO (ms). */\nconst ADAPTIVE_FETCH_TIMEOUT_MS = 200;\n\nexport interface ScanDomainResult {\n\tdomain: string;\n\tscore: ScanScore;\n\tchecks: CheckResult[];\n\tmaturity: MaturityStage;\n\tcontext: DomainContext;\n\tcached: boolean;\n\ttimestamp: string;\n\tscoringNote: string | null;\n\tadaptiveWeightDeltas: Record<string, number> | null;\n\t/** Category interaction effects applied as post-scoring adjustments. Empty when no interactions triggered. */\n\tinteractionEffects: InteractionEffect[];\n}\n\n/**\n * Run a full DNS security scan on a domain.\n * Executes all checks in parallel and computes an overall score.\n *\n * @param domain - The domain to scan (must already be validated and sanitized by the caller)\n * @param kv - Optional KV namespace for persistent scan result caching\n * @returns Full scan result with score, individual check results, and metadata\n */\nexport async function scanDomain(domain: string, kv?: KVNamespace, runtimeOptions?: ScanRuntimeOptions): Promise<ScanDomainResult> {\n\tconst explicitProfile = runtimeOptions?.profile;\n\tconst isExplicit = explicitProfile && explicitProfile !== 'auto';\n\tconst cacheKey = isExplicit\n\t\t? `${CACHE_PREFIX}${domain}:profile:${explicitProfile}`\n\t\t: `${CACHE_PREFIX}${domain}`;\n\n\t// Check cache first (skip when force_refresh is requested)\n\tif (!runtimeOptions?.forceRefresh) {\n\t\tconst cached = await cacheGet<ScanDomainResult>(cacheKey, kv);\n\t\tif (cached) {\n\t\t\treturn { ...cached, cached: true };\n\t\t}\n\t}\n\n\t// Run all checks in parallel with per-check timeouts, wrapped in an\n\t// overall scan timeout to guarantee a timely response.\n\t// Uses Promise.allSettled so that completed checks are preserved on timeout.\n\tconst ALL_CHECK_CATEGORIES: CheckCategory[] = [\n\t\t'spf', 'dmarc', 'dkim', 'dnssec', 'ssl', 'mta_sts', 'ns', 'caa', 'bimi', 'tlsrpt', 'subdomain_takeover', 'http_security', 'dane', 'mx', 'dane_https', 'svcb_https', 'subdomailing',\n\t];\n\n\t// Skip secondary DNS confirmation in scan context for speed — individual checks\n\t// still use secondary confirmation when called directly by users.\n\tconst scanDns: QueryDnsOptions = {\n\t\tskipSecondaryConfirmation: true,\n\t\tqueryCache: new Map(),\n\t\tsecondaryDoh: runtimeOptions?.secondaryDoh,\n\t};\n\n\tconst forceRefresh = runtimeOptions?.forceRefresh;\n\tconst cacheTtl = runtimeOptions?.cacheTtlSeconds;\n\n\tconst checkPromises = [\n\t\trunCachedCheck(domain, 'spf', () => safeCheck('spf', () => checkSpf(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dmarc', () => safeCheck('dmarc', () => checkDmarc(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dkim', () => safeCheck('dkim', () => checkDkim(domain, undefined, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dnssec', () => safeCheck('dnssec', () => checkDnssec(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'ssl', () => safeCheck('ssl', () => checkSsl(domain)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'mta_sts', () => safeCheck('mta_sts', () => checkMtaSts(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'ns', () => safeCheck('ns', () => checkNs(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'caa', () => safeCheck('caa', () => checkCaa(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'bimi', () => safeCheck('bimi', () => checkBimi(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'tlsrpt', () => safeCheck('tlsrpt', () => checkTlsrpt(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'subdomain_takeover', () => safeCheck('subdomain_takeover', () => checkSubdomainTakeover(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'http_security', () => safeCheck('http_security', () => checkHttpSecurity(domain)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dane', () => safeCheck('dane', () => checkDane(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'dane_https', () => safeCheck('dane_https', () => checkDaneHttps(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'svcb_https', () => safeCheck('svcb_https', () => checkSvcbHttps(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(domain, 'subdomailing', () => safeCheck('subdomailing', () => checkSubdomailing(domain, scanDns)), kv, cacheTtl, forceRefresh),\n\t\trunCachedCheck(\n\t\t\tdomain,\n\t\t\t'mx',\n\t\t\t() =>\n\t\t\t\tsafeCheck(\n\t\t\t\t\t'mx',\n\t\t\t\t\t() =>\n\t\t\t\t\t\tcheckMx(domain, {\n\t\t\t\t\t\t\tproviderSignaturesUrl: runtimeOptions?.providerSignaturesUrl,\n\t\t\t\t\t\t\tproviderSignaturesAllowedHosts: runtimeOptions?.providerSignaturesAllowedHosts,\n\t\t\t\t\t\t\tproviderSignaturesSha256: runtimeOptions?.providerSignaturesSha256,\n\t\t\t\t\t\t}, scanDns),\n\t\t\t\t),\n\t\t\tkv,\n\t\t\tcacheTtl,\n\t\t\tforceRefresh,\n\t\t),\n\t];\n\n\tlet timedOut = false;\n\tconst settled = await Promise.race([\n\t\tPromise.allSettled(checkPromises),\n\t\tnew Promise<PromiseSettledResult<CheckResult>[]>((resolve) =>\n\t\t\tsetTimeout(() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\t// Snapshot whatever has settled so far by racing each promise with an immediate rejection\n\t\t\t\tresolve(\n\t\t\t\t\tPromise.allSettled(\n\t\t\t\t\t\tcheckPromises.map((p) => Promise.race([p, new Promise<never>((_, reject) => reject(new Error('__check_pending__')))])),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}, SCAN_TIMEOUT_MS),\n\t\t),\n\t]);\n\n\tlet checkResults = settled\n\t\t.filter((r): r is PromiseFulfilledResult<CheckResult> => r.status === 'fulfilled')\n\t\t.map((r) => r.value);\n\n\t// Track categories with degraded status before post-processing strips checkStatus.\n\t// Post-processing calls buildCheckResult() which creates new objects without checkStatus,\n\t// so we must record these statuses separately and re-apply them after post-processing.\n\tconst degradedStatuses = new Map<CheckCategory, 'error' | 'timeout'>();\n\tfor (const r of checkResults) {\n\t\tif (r.checkStatus === 'error' || r.checkStatus === 'timeout') {\n\t\t\tdegradedStatuses.set(r.category, r.checkStatus);\n\t\t}\n\t}\n\n\t// For any checks that didn't complete, add a timeout finding\n\tif (timedOut) {\n\t\tconst completedCategories = new Set(checkResults.map((r) => r.category));\n\t\tfor (const category of ALL_CHECK_CATEGORIES) {\n\t\t\tif (!completedCategories.has(category)) {\n\t\t\t\tconst findings = [\n\t\t\t\t\tcreateFinding(\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\t`${category.toUpperCase()} check timed out`,\n\t\t\t\t\t\t'low',\n\t\t\t\t\t\t`Check did not complete within the ${SCAN_TIMEOUT_MS / 1000}s scan time limit. Try running this check individually.`,\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t\tconst result = buildCheckResult(category, findings);\n\t\t\t\tcheckResults.push({ ...result, score: 0, checkStatus: 'timeout' as const });\n\t\t\t\tdegradedStatuses.set(category, 'timeout');\n\t\t\t}\n\t\t}\n\t}\n\n\tlet result: ScanDomainResult;\n\ttry {\n\t\tcheckResults = await applyScanPostProcessing(domain, checkResults, runtimeOptions);\n\n\t\t// Re-apply score=0 and checkStatus for checks that errored or timed out.\n\t\t// Post-processing calls buildCheckResult() which creates new objects that lose checkStatus,\n\t\t// so we re-enforce the zero score and status using the degradedStatuses map recorded above.\n\t\tif (degradedStatuses.size > 0) {\n\t\t\tcheckResults = checkResults.map((r) => {\n\t\t\t\tconst status = degradedStatuses.get(r.category);\n\t\t\t\treturn status ? { ...r, score: 0, checkStatus: status } : r;\n\t\t\t});\n\t\t}\n\n\t\t// Detect domain context from check results\n\t\tlet domainContext = detectDomainContext(checkResults);\n\n\t\t// If an explicit profile was requested, override detection\n\t\tif (isExplicit) {\n\t\t\tdomainContext = {\n\t\t\t\tprofile: explicitProfile as DomainProfile,\n\t\t\t\tsignals: [...domainContext.signals, `explicit profile override: ${explicitProfile}`],\n\t\t\t\tweights: getProfileWeights(explicitProfile as DomainProfile, runtimeOptions?.scoringConfig),\n\t\t\t\tdetectedProvider: domainContext.detectedProvider,\n\t\t\t};\n\t\t}\n\n\t\t// Apply provider-informed DKIM adjustment: when a known DKIM-signing\n\t\t// provider is detected via MX, downgrade the \"not found\" finding since\n\t\t// the provider likely signs by default with a custom selector.\n\t\tif (domainContext.detectedProvider) {\n\t\t\tconst dkimIdx = checkResults.findIndex((r) => r.category === 'dkim');\n\t\t\tif (dkimIdx !== -1) {\n\t\t\t\tcheckResults[dkimIdx] = applyProviderDkimContext(checkResults[dkimIdx], domainContext.detectedProvider);\n\t\t\t}\n\t\t}\n\n\t\t// Phase 1: only pass context to scoring when an explicit profile is set.\n\t\t// For 'auto' (or unset), detection runs and is reported but scoring\n\t\t// uses the default weights (identical to pre-profile behavior).\n\t\tconst scoringContext = isExplicit ? domainContext : undefined;\n\n\t\t// Attempt to fetch adaptive weights from the ProfileAccumulator DO\n\t\tlet adaptiveResponse: AdaptiveWeightsResponse | null = null;\n\t\tif (runtimeOptions?.profileAccumulator) {\n\t\t\tadaptiveResponse = await fetchAdaptiveWeights(\n\t\t\t\truntimeOptions.profileAccumulator,\n\t\t\t\tdomainContext.profile,\n\t\t\t\tdomainContext.detectedProvider,\n\t\t\t);\n\t\t}\n\n\t\t// Add bound hits to signals if present\n\t\tif (adaptiveResponse?.boundHits.length) {\n\t\t\tdomainContext.signals.push(`adaptive bound hits: ${adaptiveResponse.boundHits.join(', ')}`);\n\t\t}\n\n\t\tlet score: ScanScore;\n\t\tlet scoringNote: string | null = null;\n\t\tlet adaptiveWeightDeltas: Record<string, number> | null = null;\n\n\t\tif (adaptiveResponse && adaptiveResponse.sampleCount > 0) {\n\t\t\tconst adaptiveWeights = adaptiveWeightsToContext(adaptiveResponse.weights, domainContext.profile);\n\t\t\tif (adaptiveWeights) {\n\t\t\t\t// Compute adaptive score\n\t\t\t\tconst adaptiveContext: DomainContext = { ...domainContext, weights: adaptiveWeights };\n\t\t\t\tconst adaptiveScore = computeScanScore(checkResults, adaptiveContext, runtimeOptions?.scoringConfig);\n\n\t\t\t\t// Compute static score for comparison\n\t\t\t\tconst staticContext: DomainContext = {\n\t\t\t\t\t...domainContext,\n\t\t\t\t\tweights: getProfileWeights(domainContext.profile, runtimeOptions?.scoringConfig),\n\t\t\t\t};\n\t\t\t\tconst staticScore = computeScanScore(checkResults, scoringContext ?? staticContext, runtimeOptions?.scoringConfig);\n\n\t\t\t\t// Compute per-category weight deltas\n\t\t\t\tconst staticWeights = getProfileWeights(domainContext.profile, runtimeOptions?.scoringConfig);\n\t\t\t\tconst deltas: Record<string, number> = {};\n\t\t\t\tfor (const cat of Object.keys(staticWeights) as CheckCategory[]) {\n\t\t\t\t\tdeltas[cat] = adaptiveWeights[cat].importance - staticWeights[cat].importance;\n\t\t\t\t}\n\n\t\t\t\tconst scoreDelta = adaptiveScore.overall - staticScore.overall;\n\t\t\t\tscoringNote = generateScoringNote(deltas, scoreDelta, domainContext.detectedProvider);\n\t\t\t\tadaptiveWeightDeltas = deltas;\n\t\t\t\t// Use the SAME scoring call as the non-adaptive path for determinism.\n\t\t\t\t// Both paths must produce identical results regardless of whether the\n\t\t\t\t// ProfileAccumulatorDO responds. The adaptive delta is reported in\n\t\t\t\t// scoringNote for analytics consumers.\n\t\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t\t} else {\n\t\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t\t}\n\t\t} else {\n\t\t\tscore = computeScanScore(checkResults, scoringContext, runtimeOptions?.scoringConfig);\n\t\t}\n\n\t\t// Apply category interaction penalties (post-scoring adjustment)\n\t\tconst { adjustedScore, effects: interactionEffects } = applyInteractionPenalties(score, runtimeOptions?.scoringConfig);\n\t\tscore = adjustedScore;\n\n\t\tconst rawMaturity = computeMaturityStage(checkResults);\n\t\tconst maturity = capMaturityStage(rawMaturity, score.overall);\n\n\t\tresult = {\n\t\t\tdomain,\n\t\t\tscore,\n\t\t\tchecks: checkResults,\n\t\t\tmaturity,\n\t\t\tcontext: domainContext,\n\t\t\tcached: false,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tscoringNote,\n\t\t\tadaptiveWeightDeltas,\n\t\t\tinteractionEffects,\n\t\t};\n\n\t\t// POST telemetry to DO (best-effort, non-blocking)\n\t\tif (runtimeOptions?.profileAccumulator) {\n\t\t\tconst telemetry: ScanTelemetry = {\n\t\t\t\tprofile: domainContext.profile,\n\t\t\t\tprovider: domainContext.detectedProvider,\n\t\t\t\tcategoryFindings: checkResults.map((r) => ({ category: r.category, score: r.score, passed: r.passed })),\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\toverallScore: score.overall,\n\t\t\t};\n\t\t\tconst telemetryPromise = (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst stub = runtimeOptions.profileAccumulator!.get(\n\t\t\t\t\t\truntimeOptions.profileAccumulator!.idFromName('global'),\n\t\t\t\t\t);\n\t\t\t\t\tawait stub.fetch(\n\t\t\t\t\t\tnew Request('https://do/ingest', {\n\t\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\t\t\t\tbody: JSON.stringify(telemetry),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t})();\n\t\t\tif (runtimeOptions.waitUntil) runtimeOptions.waitUntil(telemetryPromise);\n\t\t}\n\t} catch {\n\t\t// Post-processing or scoring failed — return whatever we have.\n\t\t// Re-apply degraded status overrides in case post-processing ran partially.\n\t\tif (degradedStatuses.size > 0) {\n\t\t\tcheckResults = checkResults.map((r) => {\n\t\t\t\tconst status = degradedStatuses.get(r.category);\n\t\t\t\treturn status ? { ...r, score: 0, checkStatus: status } : r;\n\t\t\t});\n\t\t}\n\t\tlet fallbackContext = detectDomainContext(checkResults);\n\t\tif (isExplicit) {\n\t\t\tfallbackContext = {\n\t\t\t\tprofile: explicitProfile as DomainProfile,\n\t\t\t\tsignals: [...fallbackContext.signals, `explicit profile override: ${explicitProfile}`],\n\t\t\t\tweights: getProfileWeights(explicitProfile as DomainProfile, runtimeOptions?.scoringConfig),\n\t\t\t\tdetectedProvider: fallbackContext.detectedProvider,\n\t\t\t};\n\t\t}\n\t\tconst fallbackScoringContext = isExplicit ? fallbackContext : undefined;\n\t\tconst score = computeScanScore(checkResults, fallbackScoringContext, runtimeOptions?.scoringConfig);\n\t\tconst rawMaturity = computeMaturityStage(checkResults);\n\t\tconst maturity = capMaturityStage(rawMaturity, score.overall);\n\t\tresult = {\n\t\t\tdomain,\n\t\t\tscore,\n\t\t\tchecks: checkResults,\n\t\t\tmaturity,\n\t\t\tcontext: fallbackContext,\n\t\t\tcached: false,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tscoringNote: null,\n\t\t\tadaptiveWeightDeltas: null,\n\t\t\tinteractionEffects: [],\n\t\t};\n\t}\n\n\t// Cache the result (use configurable TTL if provided)\n\t// Defer the write via waitUntil when available to avoid blocking the response.\n\tconst cachePromise = cacheSet(cacheKey, result, kv, runtimeOptions?.cacheTtlSeconds);\n\tif (runtimeOptions?.waitUntil) {\n\t\truntimeOptions.waitUntil(cachePromise);\n\t} else {\n\t\tawait cachePromise;\n\t}\n\n\treturn result;\n}\n\n/**\n * Fetch adaptive weights from the ProfileAccumulator DO with in-memory caching.\n * Returns null on failure or timeout (silently falls back to static weights).\n */\nasync function fetchAdaptiveWeights(\n\taccumulator: DurableObjectNamespace,\n\tprofile: string,\n\tprovider: string | null,\n): Promise<AdaptiveWeightsResponse | null> {\n\tconst cacheKey = `${profile}:${provider ?? ''}`;\n\tconst now = Date.now();\n\n\t// Check in-memory cache first\n\tconst cached = adaptiveWeightCache.get(cacheKey);\n\tif (cached && cached.expires > now) {\n\t\treturn cached.weights;\n\t}\n\n\ttry {\n\t\tconst stub = accumulator.get(accumulator.idFromName('global'));\n\t\tconst url = new URL('https://do/weights');\n\t\turl.searchParams.set('profile', profile);\n\t\tif (provider) url.searchParams.set('provider', provider);\n\n\t\tconst response = await Promise.race([\n\t\t\tstub.fetch(new Request(url.toString())),\n\t\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('adaptive weight fetch timeout')), ADAPTIVE_FETCH_TIMEOUT_MS)),\n\t\t]);\n\n\t\tif (!response.ok) return null;\n\n\t\tconst data = (await response.json()) as AdaptiveWeightsResponse;\n\t\tif (adaptiveWeightCache.size >= ADAPTIVE_CACHE_MAX_ENTRIES) {\n\t\t\tevictAdaptiveWeightCache();\n\t\t}\n\t\tadaptiveWeightCache.set(cacheKey, { weights: data, expires: now + ADAPTIVE_CACHE_TTL_MS });\n\t\treturn data;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Evict entries from the adaptive weight cache.\n * Removes expired entries first, then if still at capacity, evicts the entry with the oldest expiry time.\n */\nexport function evictAdaptiveWeightCache(): void {\n\tconst now = Date.now();\n\n\t// First pass: remove all expired entries\n\tfor (const [key, entry] of adaptiveWeightCache) {\n\t\tif (entry.expires <= now) {\n\t\t\tadaptiveWeightCache.delete(key);\n\t\t}\n\t}\n\n\t// If still at capacity after removing expired entries, evict the oldest by expiry\n\tif (adaptiveWeightCache.size >= ADAPTIVE_CACHE_MAX_ENTRIES) {\n\t\tlet oldestKey: string | null = null;\n\t\tlet oldestExpiry = Infinity;\n\t\tfor (const [key, entry] of adaptiveWeightCache) {\n\t\t\tif (entry.expires < oldestExpiry) {\n\t\t\t\toldestExpiry = entry.expires;\n\t\t\t\toldestKey = key;\n\t\t\t}\n\t\t}\n\t\tif (oldestKey !== null) {\n\t\t\tadaptiveWeightCache.delete(oldestKey);\n\t\t}\n\t}\n}\n\n/** Exposed for testing only — do not use in production code. */\nexport const _adaptiveWeightCacheForTest = adaptiveWeightCache;\n\nasync function runCachedCheck(\n\tdomain: string,\n\tcategory: CheckCategory,\n\trun: () => Promise<CheckResult>,\n\tkv?: KVNamespace,\n\tttlSeconds?: number,\n\tskipCache?: boolean,\n): Promise<CheckResult> {\n\treturn runWithCache(`${CACHE_PREFIX}${domain}:check:${category}`, run, kv, ttlSeconds, skipCache);\n}\n\n/**\n * Run a single check with error handling and a per-check timeout.\n * If a check fails or exceeds the timeout, returns a failed CheckResult\n * with an error/timeout finding instead of throwing, so other checks\n * can still complete.\n */\nasync function safeCheck(category: CheckCategory, fn: () => Promise<CheckResult>): Promise<CheckResult> {\n\ttry {\n\t\tconst result = await Promise.race([\n\t\t\tfn(),\n\t\t\tnew Promise<never>((_, reject) => setTimeout(() => reject(new Error('Check timed out')), PER_CHECK_TIMEOUT_MS)),\n\t\t]);\n\t\treturn result;\n\t} catch (err) {\n\t\tconst rawMessage = err instanceof Error ? err.message : 'Check failed';\n\t\tconst SAFE_PREFIXES = ['DNS query', 'Check timed out', 'Check failed', 'Connection', 'timeout'];\n\t\tconst safeMessage = SAFE_PREFIXES.some((p) => rawMessage.startsWith(p)) ? rawMessage : 'Check failed';\n\t\tconst findings = [createFinding(category, `${category.toUpperCase()} check error`, 'high', `Check failed: ${safeMessage}`)];\n\t\tconst result = buildCheckResult(category, findings);\n\t\treturn { ...result, score: 0, checkStatus: 'error' as const };\n\t}\n}\n\n"]}
|