/**
 * Per-sample quality diagnostics.
 *
 * Why this exists
 * ---------------
 * `report-diagnostics.ts` answers "what's wrong with the report overall" —
 * aggregate-level insights about assertions and variant comparisons. This
 * module answers a complementary question: "which specific samples in my
 * eval-samples set are problematic and should be fixed before I trust any
 * conclusion drawn on this report?"
 *
 * Senior-engineer pain point: 100 eval-samples typically have 20-40 that
 * (a) all variants get the same score on (no discriminative power), or
 * (b) are near-duplicates of another sample (data redundancy inflating N), or
 * (c) have ambiguous rubric (judge gives wildly different scores on repeats), or
 * (d) are cost / latency outliers (one sample spikes the budget by itself), or
 * (e) fail across the board (likely broken sample, not a model deficiency).
 *
 * Persisted on the report so studio can surface these to users iterating
 * the SAMPLE SET (alongside iterating the SKILL).
 *
 * Output shape: a flat list of issues, each tagged with severity and the
 * minimal evidence needed to act ("here are the matching prompts"). Issues are
 * sorted by severity then by sample_id so the report is stable across runs.
 */
import type { Report, Sample } from '../types/index.js';
export type SampleIssueKind = 'flat_scores' | 'all_pass' | 'all_fail' | 'near_duplicate' | 'ambiguous_rubric' | 'cost_outlier' | 'latency_outlier' | 'error_prone' | 'rubric_clarity_low' | 'capability_thin';
export interface SampleIssue {
    sample_id: string;
    severity: 'error' | 'warning' | 'info';
    kind: SampleIssueKind;
    /** Minimal evidence to make the issue actionable. */
    evidence: Record<string, unknown>;
}
export interface SampleDiagnosticReport {
    /** All issues sorted by (severity desc, sample_id asc). */
    issues: SampleIssue[];
    /** 0-100 quality score for the sample set as a whole. Lower = more issues. */
    healthScore: number;
    /** Sample IDs grouped by issue kind for quick consumption. */
    byKind: Partial<Record<SampleIssueKind, string[]>>;
    /** Quick-glance counters. */
    totals: {
        samples: number;
        flagged: number;
        errors: number;
        warnings: number;
        infos: number;
    };
}
export interface DiagnoseOptions {
    /** Minimum ROUGE-1 between two prompts to flag near-duplicate. Default 0.7. */
    duplicateRouge?: number;
    /** Judge stddev threshold (across judgeRepeat samples) to flag ambiguous. Default 1.0. */
    ambiguousStddev?: number;
    /** Cost outlier multiplier vs median. Default 3 (≥ 3× median is flagged). */
    costOutlierK?: number;
    /** Latency outlier multiplier vs median. Default 3. */
    latencyOutlierK?: number;
    /** Score-spread threshold below which a sample is "flat". Default 0.5. */
    flatThreshold?: number;
    /**
     * Original Sample objects, used for near-duplicate detection. When omitted
     * (Report alone) the duplicate check is skipped — Report doesn't carry
     * prompts, only score/cost/latency. The CLI handler reads samples via
     * report.meta.request.samplesPath and passes them in.
     */
    samples?: Sample[];
}
export declare function diagnoseSamples(report: Report, options?: DiagnoseOptions): SampleDiagnosticReport;
/** case-insensitive + dash/camel/underscore normalize:
 *  `api-selection`, `apiSelection`, `API_Selection` 都归到 `apiselection`。
 *  让 capability_thin / capabilityCoverage 不受拼写风格差异影响。 */
export declare function normalizeCapability(raw: string): string;
type DiagnosticLang = 'zh' | 'en';
export declare function formatSampleIssue(issue: SampleIssue, lang?: DiagnosticLang): string;
/**
 * Plain-text formatter for sample-quality diagnostics output.
 */
export declare function formatSampleDiagnostics(diag: SampleDiagnosticReport, options?: {
    topN?: number;
    lang?: DiagnosticLang;
}): string;
export {};
//# sourceMappingURL=sample-diagnostics.d.ts.map