/**
 * src/skill-loop/ab-runner.ts
 *
 * A/B test runner with failure budgets for SkillCandidates.
 *
 * Invariants:
 *   - Max 3 candidates simultaneously (4th is rejected).
 *   - Traffic fraction cap: 10% per candidate.
 *   - Rollback triggered when a candidate's mean score drops >5% vs incumbent.
 *   - Winner declared when: p < 0.05 AND delta >= 10% AND no rollback triggered.
 *
 * Statistical significance uses the same Welch approach as evaluator.ts.
 *
 * @module skill-loop/ab-runner
 */
import type { SkillCandidate } from "./candidate.js";
export interface ABConfig {
    /** Maximum concurrent candidates. Hard cap: 3. */
    maxCandidates: number;
    /** Traffic fraction routed to each candidate. Hard cap: 0.10. */
    trafficPct: number;
    /** Rollback threshold: if candidate mean drops by this fraction vs incumbent. */
    rollbackThresholdPct: number;
}
export interface ABSlot {
    candidateId: string;
    trafficFraction: number;
    outcomes: number[];
    rollbackTriggered: boolean;
}
export declare class ABRunner {
    private readonly config;
    private readonly slots;
    private readonly candidates;
    private readonly incumbentOutcomes;
    constructor(config: ABConfig);
    /**
     * Register a new candidate for A/B testing.
     *
     * @returns true if added, false if maxCandidates already reached.
     */
    addCandidate(candidate: SkillCandidate): boolean;
    /**
     * Record an outcome score for a candidate or the incumbent.
     *
     * @param candidateId - Candidate ID or "incumbent".
     * @param score       - Outcome score [0, 1].
     */
    recordOutcome(candidateId: string | "incumbent", score: number): void;
    /**
     * Returns true if the candidate's mean score has dropped >rollbackThresholdPct
     * vs the incumbent mean.
     */
    shouldRollback(candidateId: string): boolean;
    /**
     * Return the winning candidate if statistical significance is established.
     *
     * Winner criteria:
     *   - p < 0.05 (Welch's t-test vs incumbent)
     *   - delta >= 10% vs incumbent mean
     *   - rollback NOT triggered
     *
     * Returns null if no candidate meets all criteria.
     */
    getWinner(): SkillCandidate | null;
}
//# sourceMappingURL=ab-runner.d.ts.map