{"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../../src/core/web-research/confidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA0BtE,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,CACZ,iBAAiB,EACjB,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,WAAW,GAAG,kBAAkB,GAAG,eAAe,CACxG,CAAC;CACF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAqB/E;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,GAAG,MAAM,CAWvE;AAED,yFAAyF;AACzF,eAAO,MAAM,kCAAkC,OAAO,CAAC","sourcesContent":["import type { SourceConfidence, WebEvidenceRecord } from \"./types.js\";\n\n/**\n * Derives a machine-readable source confidence from structured source\n * properties. Confidence is never an arbitrary model label: it falls out of\n * whether a page was successfully and securely fetched, whether it exposes\n * dates/authority signals, and whether it can support exact claims.\n *\n * Policy (search snippets are discovery-only):\n * - A fetched page may reach `high` only when securely fetched and dated.\n * - An unfetched source (search snippet only) can never exceed `low`.\n * - A successful fetch alone is not enough to be `high` (a wiki is not high\n *   merely because it loaded).\n */\n\nconst AUTHORITY_DOMAINS = [/\\.(gov|edu)$/, /^docs\\./, /^developer\\./, /^learn\\./, /github\\.com$/];\n\nfunction domainAuthority(url: string): boolean {\n\ttry {\n\t\tconst { hostname } = new URL(url);\n\t\treturn AUTHORITY_DOMAINS.some((re) => re.test(hostname));\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport interface ConfidenceInput {\n\tfetched: boolean;\n\trecord?: Pick<\n\t\tWebEvidenceRecord,\n\t\t\"publishedAt\" | \"author\" | \"title\" | \"canonicalUrl\" | \"truncated\" | \"relevantPassages\" | \"contentSha256\"\n\t>;\n}\n\nexport function deriveSourceConfidence(input: ConfidenceInput): SourceConfidence {\n\tif (!input.fetched || !input.record) {\n\t\t// Unfetched: search snippet only. Never high confidence.\n\t\treturn \"low\";\n\t}\n\tconst record = input.record;\n\tlet score = 0;\n\tif (record.publishedAt) score += 3;\n\tif (record.author) score += 2;\n\tif (domainAuthority(record.canonicalUrl)) score += 2;\n\tif (record.title && record.title.length > 4) score += 1;\n\tif (record.relevantPassages && record.relevantPassages.length > 0) score += 1;\n\tif (record.truncated) score -= 2;\n\t// \"High\" requires an authority signal (official/authoritative domain or a\n\t// named author) AND a publication date. A community wiki that merely loaded\n\t// successfully is never high, even if it carries a date.\n\tconst hasAuthoritySignal = domainAuthority(record.canonicalUrl) || Boolean(record.author);\n\tif (hasAuthoritySignal && record.publishedAt && score >= 5) return \"high\";\n\tif (score >= 3 && hasAuthoritySignal) return \"medium\";\n\tif (score >= 3) return \"low\";\n\treturn \"low\";\n}\n\nexport function describeConfidence(confidence: SourceConfidence): string {\n\tswitch (confidence) {\n\t\tcase \"high\":\n\t\t\treturn \"securely fetched, dated/authoritative, supports exact claims\";\n\t\tcase \"medium\":\n\t\t\treturn \"securely fetched but lacks dating or authority signals; supports general claims\";\n\t\tcase \"low\":\n\t\t\treturn \"discovery-only or unfetched; cannot independently support exact numbers\";\n\t\tcase \"unverified\":\n\t\t\treturn \"no addressable evidence\";\n\t}\n}\n\n/** A search snippet may be used only for discovery; it cannot establish exact claims. */\nexport const SEARCH_SNIPPETS_ARE_DISCOVERY_ONLY = true;\n"]}