/**
 * BaselineDiffer — pure functions that compute `BaselineDiffArtifact`
 * and `RegressionGateResult` from a baseline plus a candidate
 * (another baseline or a per-trace metric summary).
 *
 * Plan 50 M1 scope (this file):
 * - `computeBaselineDiff(base, candidate, opts?)` — per-metric deltas
 *   with explicit `unsupportedReason` for the missing-data paths
 *   Codex round 1 P1#4 enumerated (missing on candidate, both
 *   unsupported, sample below threshold, divide-by-zero).
 * - `evaluateRegressionGate(baselineId, diff, rules, opts?)` — apply
 *   threshold rules to a diff. Skipped gates carry `skipReason` and
 *   omit `diff` per the §4.1 contract.
 *
 * Out of scope:
 * - GitHub / IM integration (§4.1 explicitly says "CI dry-run mode,
 *   no GitHub" for M1).
 * - MCP tool registration — `lookup_baseline` / `compare_to_baseline`
 *   land in M2.
 *
 * @module baselineDiffer
 */
import { type BaselineMetric, type BaselineRecord, type BaselineDiffArtifact, type RegressionGateResult } from '../types/sparkContracts';
/** Trace-side counterpart to BaselineRecord: just the metrics, plus an
 * id pointer so the differ can record which trace was compared. The
 * caller (skill or pre-aggregated source) owns metric extraction; the
 * differ stays trace-agnostic. */
export interface TraceMetricSummary {
    kind: 'trace';
    traceId: string;
    metrics: BaselineMetric[];
}
export type DiffCandidate = BaselineRecord | TraceMetricSummary;
export interface DiffOptions {
    /** Below this absolute fractional delta the severity stays 'none'. */
    noneThresholdPct?: number;
    /** Above this fractional delta the severity becomes 'warning'. */
    warningThresholdPct?: number;
    /** Above this fractional delta the severity becomes 'regression'. */
    regressionThresholdPct?: number;
    /** Both sides need at least this many samples; below → unsupported. */
    minSampleCount?: number;
    /**
     * If true, a metric missing on the base is reported as 'unsupported'
     * with a clear reason; if false the metric is silently skipped.
     * Defaults to true so missing data stays visible.
     */
    reportMissingOnBase?: boolean;
}
/**
 * Compute the diff between `base` and `candidate`. The diff covers
 * every metricId present on either side; missing-data paths are
 * surfaced as `severity: 'unsupported'` with a concrete reason rather
 * than silently skipped or zero-filled.
 */
export declare function computeBaselineDiff(base: BaselineRecord, candidate: DiffCandidate, opts?: DiffOptions): BaselineDiffArtifact;
/** Threshold rule for the regression gate. Applied per metric. */
export interface RegressionRule {
    metricId: string;
    /** Maximum allowed absolute fractional delta. 0.10 == 10%. */
    threshold: number;
    /** When true the gate fails if `deltaPct > threshold` (default).
     * When false (e.g. for "must-decrease" metrics) the gate fails
     * when `deltaPct < -threshold`. */
    expectIncrease?: boolean;
}
export interface GateOptions {
    /** Stable id surfaced on the result. Required for audit. */
    gateId: string;
    /** Skip the gate with this reason instead of evaluating rules. */
    skipReason?: string;
}
/**
 * Apply threshold rules to a precomputed diff. Returns a
 * `RegressionGateResult` whose `status` is `'skipped'` when
 * `opts.skipReason` is set (the diff is intentionally omitted in that
 * case, per the §4.1 contract).
 *
 * `'fail'` when any rule's threshold is breached. `'flaky'` when no
 * rule is breached but at least one delta is `'unsupported'` —
 * surfaces the gate's lack of confidence rather than passing silently.
 * `'pass'` otherwise.
 */
export declare function evaluateRegressionGate(baselineId: string, diff: BaselineDiffArtifact, rules: RegressionRule[], opts: GateOptions): RegressionGateResult;
//# sourceMappingURL=baselineDiffer.d.ts.map