/**
 * @stable
 *
 * Eval scorecard — the persistent (persona × profile) score timeline.
 *
 * Every benchmark run folds into per-cell entries; a cell is
 * `(scenarioId, profileHash)` and its timeline carries one entry per commit.
 * The scorecard answers the question a single run cannot: did THIS change
 * regress persona P on profile F, even while the aggregate improved?
 *
 * Storage is an append-only JSONL log — one line per (cell, commit). Appends
 * never read-modify-write, so concurrent campaign runs cannot clobber each
 * other; `loadScorecard` folds the log into the queryable `Scorecard`, and a
 * malformed line never breaks the read. `diffScorecard` compares the latest
 * entry of each cell against its predecessor with Cohen's d + Welch's t-test.
 */
import type { AgentProfile } from './agent-profile';
import type { RunRecord } from './run-record';
/** One commit's measurement of one (scenario, profile) cell. */
export interface ScorecardEntry {
    commitSha: string;
    /** ISO timestamp the entry was recorded. */
    timestamp: string;
    /** Per-seed (or per-rep) scores for this cell at this commit. */
    scores: number[];
    /** Median of `scores` — the cell's headline score for the commit. */
    composite: number;
    /** Per-dimension means, when the runs carried a judge breakdown. */
    perDimension?: Record<string, number>;
    /** RunRecord ids folded into this entry — provenance. */
    runIds: string[];
}
/** A (scenario, profile) cell and its commit-ordered score timeline. */
export interface ScorecardCell {
    scenarioId: string;
    profileHash: string;
    /** Model id — denormalised from the profile for readable filtering. */
    model: string;
    timeline: ScorecardEntry[];
}
/** The folded scorecard: every cell, plus the profile definitions by hash. */
export interface Scorecard {
    cells: ScorecardCell[];
    /** Profile definitions seen — keeps the scorecard self-describing. */
    profiles: Record<string, AgentProfile>;
}
/** One append-only log line — a single cell's entry for a single commit. */
export interface ScorecardLogLine {
    scenarioId: string;
    profileHash: string;
    model: string;
    profile: AgentProfile;
    entry: ScorecardEntry;
}
export interface RecordRunsOptions {
    /** The profile that produced these runs — keys the cell. */
    profile: AgentProfile;
    commitSha: string;
    /** Defaults to `new Date().toISOString()`. */
    timestamp?: string;
}
/**
 * Fold a benchmark's `RunRecord[]` into per-cell scorecard log lines — one
 * line per scenario the runs cover. All runs are attributed to the single
 * `profile` in `opts` (the harness ran them under it); the cell key is
 * `(scenarioId, agentProfileHash(profile))`.
 */
export declare function recordRuns(runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[];
/** Append cell entries to the JSONL scorecard log. Creates the file/dir. */
export declare function appendScorecard(logPath: string, lines: ScorecardLogLine[]): void;
/** Record runs and append them to the log in one call. Returns the lines. */
export declare function recordRunsToScorecard(logPath: string, runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[];
/**
 * Fold the JSONL log into a queryable `Scorecard`. A missing file yields an
 * empty scorecard; a malformed line is skipped — a corrupt append never
 * breaks the read. Each cell's timeline is sorted chronologically.
 */
export declare function loadScorecard(logPath: string): Scorecard;
export type CellVerdict = 'improved' | 'regressed' | 'flat' | 'new';
export interface ScorecardCellDiff {
    scenarioId: string;
    profileHash: string;
    model: string;
    verdict: CellVerdict;
    /** Composite of the latest entry. */
    current: number;
    /** Composite of the comparison entry — `null` when `verdict === 'new'`. */
    baseline: number | null;
    /** `current − baseline` — `null` when new. */
    delta: number | null;
    /** Cohen's d of current vs baseline samples — `null` when new or n < 2. */
    cohensD: number | null;
    /** Welch's t-test p-value — `null` when new or n < 2. */
    pValue: number | null;
    currentCommit: string;
    baselineCommit: string | null;
}
export interface ScorecardDiff {
    cells: ScorecardCellDiff[];
    summary: {
        improved: number;
        regressed: number;
        flat: number;
        new: number;
    };
}
export interface DiffScorecardOptions {
    /** Compare each cell against this commit instead of its immediate predecessor. */
    baselineCommit?: string;
    /** |Cohen's d| at/above which a move counts as real. Default 0.5. */
    minEffect?: number;
    /** p-value at/below which a move is significant. Default 0.05. */
    maxP?: number;
    /**
     * |delta| at/above which a move counts when statistics are unavailable
     * (a cell with fewer than 2 samples on either side). Default 0.05.
     */
    minDelta?: number;
}
/**
 * Compare the latest entry of every cell against its predecessor (or against
 * `baselineCommit`) and classify the move. A move is `improved`/`regressed`
 * only when it clears both the effect-size and significance gates; otherwise
 * `flat`. Cells with no prior entry are `new`.
 */
export declare function diffScorecard(scorecard: Scorecard, opts?: DiffScorecardOptions): ScorecardDiff;
/**
 * Render a scorecard diff as a human-readable report — the block a feature
 * PR prints. Regressions are listed first; flat cells are summarised, not
 * enumerated.
 */
export declare function formatScorecardDiff(diff: ScorecardDiff): string;
//# sourceMappingURL=scorecard.d.ts.map