/**
 * Full cross-trace diff — align two trajectories step-by-step, report
 * per-step score deltas, attribute a variant's total outcome lead to
 * specific turns.
 *
 * 0.5 shipped `firstDivergenceView` (finds the first differing step).
 * This does the heavier work: full alignment via LCS, per-step
 * contribution to score delta using PRM verdicts when available,
 * fallback to structural heuristics (latency, token count, tool
 * outcome) otherwise.
 */
import type { TraceStore } from './trace/store';
import { type TrajectoryStep } from './trajectory';
export type AlignmentOp = {
    op: 'match';
    a: TrajectoryStep;
    b: TrajectoryStep;
} | {
    op: 'insert';
    b: TrajectoryStep;
} | {
    op: 'delete';
    a: TrajectoryStep;
} | {
    op: 'replace';
    a: TrajectoryStep;
    b: TrajectoryStep;
};
export interface StepAttribution {
    op: AlignmentOp;
    /** Difference in PRM score (or null when not scored by a matching judge). */
    prmDelta: number | null;
    /** Difference in latency (endedAt - startedAt). */
    latencyDeltaMs: number | null;
    /** Difference in token count (LLM spans). */
    tokenDelta: number | null;
    /** Reason this step is / isn't considered a contributor to the outcome delta. */
    note: string;
}
export interface CrossTraceDiff {
    runA: string;
    runB: string;
    alignment: AlignmentOp[];
    attributions: StepAttribution[];
    /** Total score delta (B - A). */
    totalScoreDelta: number | null;
    /** Sum of PRM deltas across matched/replaced steps. Close to
     *  `totalScoreDelta` when PRM covers the trajectory; gap indicates
     *  unmodeled variance. */
    prmDeltaSum: number;
}
export interface CrossTraceDiffOptions {
    stepEquals?: (a: TrajectoryStep, b: TrajectoryStep) => boolean;
}
export declare function crossTraceDiff(store: TraceStore, runA: string, runB: string, options?: CrossTraceDiffOptions): Promise<CrossTraceDiff>;
//# sourceMappingURL=cross-trace-diff.d.ts.map