export type AuthorityTier = "primary" | "reputable" | "unknown" | "low"; export interface AuthorityScore { tier: AuthorityTier; /** 0..1, monotonic with tier — usable directly as a ranking weight. */ score: number; reason: string; } /** * Score a source URL's trustworthiness from its domain alone. Pure and cheap; * order matters — an explicit denylist hit wins over any boost. */ export declare function scoreAuthority(url: string): AuthorityScore; export interface SourceTrustSummary { /** Aggregate trust read across the kept sources, orthogonal to citation support. */ label: "high" | "mixed" | "low"; counts: { primary: number; reputable: number; unknown: number; low: number; total: number; }; } /** * Summarize domain authority across the kept source URLs into one trust label, * for the output's source-trust signal (#111 P2). Deliberately coarse and * explainable: * "high" — no low-trust sources AND at least half are primary/reputable. * "low" — at least half the sources are known content farms. * "mixed" — everything in between (all-unrecognized, or a farm or two). * Distinct from citation support: a fully-cited answer can still be "low" trust * when every source it cites is a content farm. */ export declare function summarizeSourceTrust(urls: string[]): SourceTrustSummary; export type SourceAuthorityMode = "prefer" | "strict" | "off"; export interface RelevanceTiebreak { terms: readonly string[]; textOf: (item: T) => string; } /** * #148 — how many of `terms` appear in `text`, on the same index-walk token * normalization as the keyword ladder (#86) and relevance window (#145). * Distinct-term count, not occurrence count: repeating one keyword shouldn't * outrank matching three different ones. Pure; exported for tests. */ export declare function relevanceOverlap(text: string, terms: readonly string[]): number; /** * Order this round's candidate sources for the limited fetch slots by domain * authority, so authoritative/primary sources win the slots ahead of whatever * search happened to rank first. Pure; consumed by the keep-stage in agent.ts. * * "prefer" (default): stable-sort by authority descending. Nothing is * dropped — only the order changes, and search order is preserved within a * tier (Array.prototype.sort is stable, ES2019+). * "strict": additionally drop `low`-tier (known content-farm) candidates — * UNLESS every candidate this round is low, in which case keep them. That * min-keep floor means a niche or recency topic that only surfaces farms * still gets sources rather than nothing. * "off": identity — search order untouched (relevance is ignored too — off * is the measurement baseline and stays a strict no-op). * * #148: when `relevance` is provided, candidates that tie on authority are * ordered by topical overlap with the question/round terms, so a uniform-tier * pool still discriminates by WHAT answers the question. Authority stays the * primary key — relevance never promotes a lower tier above a higher one — * and equal-overlap ties keep search order (stable sort), so pools where the * tiers already discriminate behave exactly as before. */ export declare function rankByAuthority(items: T[], urlOf: (item: T) => string, mode: SourceAuthorityMode, relevance?: RelevanceTiebreak): T[]; /** * #148 — approximate registrable domain of a URL, for the per-host slot cap: * en.wikipedia.org and de.wikipedia.org must count as ONE host or the cap is * trivially evaded by language editions. Falls back to the raw input when the * URL won't parse (such candidates just bucket together). */ export declare function registrableDomainOf(url: string): string; /** * #148 — pick up to `slots` items from an already-ranked list, keeping at * most `cap` per registrable domain UNLESS there is headroom: when honoring * the cap would leave slots unfilled, the best capped-out items fill them * (encyclopedic context is worth a slot or two, rarely four — but four * wikipedia results are still better than three sources and an empty slot). * Preserves the input's ranking order in the output. Pure. */ export declare function selectWithHostCap(items: T[], urlOf: (item: T) => string, slots: number, cap?: number): T[]; //# sourceMappingURL=source-authority.d.ts.map