/**
 * Percentile ratchet over perf metric records.
 *
 * `summarizeRecords` folds flat records into per-scenario p50/p90 stats;
 * `gatePerf` compares a current summary against a committed baseline and
 * trips on regressions beyond tolerance. Percentiles use nearest-rank on
 * sorted values. Null / non-numeric metric values are excluded from the
 * stat (n reflects only real samples); a field with zero samples is
 * omitted entirely — no fake zeros.
 */
export interface PerfStat {
    p50: number;
    p90: number;
    n: number;
}
export interface PerfBaseline {
    version: 1;
    /** key → metric field → stat. */
    scenarios: Record<string, Record<string, PerfStat>>;
}
export interface PerfRegression {
    scenarioKey: string;
    field: string;
    baseline: PerfStat;
    current: PerfStat;
    /** percent over baseline p50 / p90, whichever tripped. */
    overBy: {
        p50Pct: number;
        p90Pct: number;
    };
}
export interface PerfGateResult {
    succeeded: boolean;
    regressions: PerfRegression[];
    /** Negative overBy: strictly better than baseline on both percentiles. */
    improvements: PerfRegression[];
    /** In baseline but absent (or under-sampled, n < minSamples) in current. */
    missingScenarios: string[];
    /** In records but absent from baseline. */
    newScenarios: string[];
}
export declare function summarizeRecords(records: ReadonlyArray<Record<string, unknown>>, keyOf: (record: Record<string, unknown>) => string | null, metricFields: ReadonlyArray<string>): PerfBaseline;
export declare function gatePerf(current: PerfBaseline, baseline: PerfBaseline, options?: {
    tolerancePct?: number;
    minSamples?: number;
}): PerfGateResult;
//# sourceMappingURL=ratchet.d.ts.map