import { Logger } from "../shared/logger.js"; export interface BaselineEntry { /** Stable identifier derived by `fingerprintFinding`. */ fingerprint: string; /** Human-readable note (optional) for why this finding was accepted. */ note?: string; /** ISO date when added to the baseline. */ addedAt: string; } export interface BaselineFile { version: number; envName: string; createdAt: string; /** Map of audit-name (e.g. "broken-links") → list of accepted findings. */ ignored: Record; } export interface BaselineHandle { envName: string; filePath: string; /** Returns true if the audit+finding is in the ignore list. */ isIgnored(audit: string, finding: unknown): boolean; /** Add a finding to the ignore list. No-op if already present. */ add(audit: string, finding: unknown, note?: string): void; /** Remove a finding from the ignore list. */ remove(audit: string, fingerprint: string): void; /** Persist to disk. Safe to call multiple times. */ flush(): Promise; /** Snapshot of current state for reporting. */ snapshot(): BaselineFile; } /** * Compute a stable fingerprint for a finding row. Each audit's * row shape gets its own identity rule. Falls back to a JSON hash * for audit names we don't know about (future-audit-tolerant). * * Why per-audit rules: an audit may carry transient fields (e.g. * `daysSinceUpdate` on stale-content changes every run). The * fingerprint MUST exclude those, otherwise baselines never match * and the ignore-list is useless. */ export declare const fingerprintFinding: (audit: string, finding: unknown) => string; export interface OpenBaselineOptions { envName: string; configDir: string; logger?: Logger; } export declare const openBaseline: (options: OpenBaselineOptions) => BaselineHandle; /** * Filter an audit's results to only NEW findings (not in baseline). * Returns a tuple of [kept, ignored] so the report can show both * counts in its summary. */ export declare const splitByBaseline: (audit: string, findings: T[], baseline: BaselineHandle) => { kept: T[]; ignored: T[]; };