export declare const DOMAIN_RECORD_TTL_SECONDS: number; export declare const SCHEMA_VERSION = 5; export declare const TIER_STATS_WINDOW_MS: number; export type TierName = "tier1_firecrawl" | "tier2_crawl4ai" | "tier3_rawfetch" | "tier4_wayback" | "github"; export type PreferredStrategy = "llms_full_txt" | "tier1" | "tier2" | "tier3"; export interface TierStat { attempts: number; ok: number; fail: number; last_fail_reason?: string; window_start_ms: number; } export interface DomainCapabilities { llms_full_txt?: { present: boolean; size_bytes?: number; last_checked: string; }; robots_txt?: { present: boolean; fetched: string; allows_us: boolean; }; json_ld_article?: { sampled: number; present: number; last_sampled_at: string; }; og_title?: { sampled: number; present: number; last_sampled_at: string; }; metadata_fetch?: { attempts: number; ok: number; fail: number; last_checked: string; }; seen_in_search?: { count: number; last_seen_at: string; }; } export interface DomainRecord { schema_version: number; domain: string; first_seen: string; last_fetch: string; capabilities: DomainCapabilities; tier_stats_30d: { tier1: TierStat; tier2: TierStat; tier3: TierStat; tier4: TierStat; github: TierStat; }; preferred_strategy?: PreferredStrategy; notes?: string; } /** * A TierStat as of `now`, with an elapsed window reported as empty. * * `tier_stats_30d` was never a 30-day window on read. The reset in * `recordTierAttempt` fires only on the *next write for that domain*, so a * domain fetched once and never revisited kept reporting those numbers until * the 90-day record TTL — grep.app's 0/10 was 26 days stale and still topping * the failing-domains list. Applying the cutoff at read time makes the window * mean what its name says regardless of write cadence. * * Every consumer must go through this: `routing.ts` thresholds on these counts * to skip tiers and `domain-stats.ts` reports them, and the two disagreeing * would be worse than either being wrong on its own. `window_start_ms` is * preserved so the "resets in ~Nd" hint still renders (as 0d, correctly). */ export declare function currentWindowStat(stat: TierStat | undefined, now?: number): TierStat; export declare function normalizeHostname(input: string): string | null; export declare function domainKey(hostname: string): string; /** * Parse a raw domain-db value, returning the record only if it is valid JSON * on the current schema. Stale-schema and malformed records return null — the * same staleness gate `getDomainRecord` applies, extracted so the bounded * enumeration in domain-stats.ts uses an identical contract. */ export declare function parseDomainRecord(raw: string | null): DomainRecord | null; export declare function getDomainRecord(hostnameOrUrl: string): Promise; export declare function recordTierAttempt(url: string, tier: TierName, outcome: "hit" | "miss" | "error", failReason?: string): Promise; export declare function recordLlmsFullProbe(url: string, present: boolean, sizeBytes?: number): Promise; export declare function recordRobotsProbe(url: string, present: boolean, allowsUs: boolean): Promise; export declare function recordPostExtractSample(url: string, signals: { jsonLdPresent: boolean; ogTitlePresent: boolean; }): Promise; export declare function recordMetadataFetchAttempt(url: string, ok: boolean): Promise; /** * Record that a domain appeared in search results. Cheap, best-effort — no * fetch is performed, this just marks the domain as "seen" so dump-domain * can distinguish it from a domain that's never shown up at all. */ export declare function recordSearchAppearance(url: string): Promise; /** * Whether JSON-LD post-extraction should be skipped for this domain. Returns * true once we've sampled at least 5 pages and found no JSON-LD Article * schema in any of them. */ export declare function shouldSkipJsonLdPostExtract(url: string): Promise;