import type { Datum } from "../charts/shared/datumTypes";
import type { ChartCapability } from "./chartCapabilityTypes";
import type { IntentId } from "./intents";
/**
 * One canonical fixture in a scorecard run. Pair canonical data with the
 * intents/components a human expert would expect to win on it. Use null
 * `expected` when the fixture is a stress-test that should produce no
 * fitting chart at all (e.g. flat single-column data, broken GeoJSON).
 */
export interface ScorecardFixture {
    name: string;
    /** Free-text shape description, used in scorecard output for context. */
    shape?: string;
    data: ReadonlyArray<Datum>;
    /** Optional non-tabular payload (network/hierarchy/GeoJSON). */
    rawInput?: unknown;
    /** Intent to rank by. If omitted, scored without intent (mean-of-all). */
    intent?: IntentId;
    /** Components the human expert would pick. Empty = "anything fits". */
    expected?: ReadonlyArray<string>;
    /** True if the fixture should produce zero fitting suggestions. Mutually exclusive with `expected`. */
    expectsNoFit?: boolean;
}
export interface PerCapabilityScore {
    component: string;
    family: ChartCapability["family"];
    /** Number of fixtures where this capability fit. */
    fitsOn: number;
    /** Number of fixtures where this capability was rejected. */
    rejectedOn: number;
    /** Number of fixtures where this capability appeared in the top-3 ranked suggestions. */
    inTopThreeOn: number;
    /** Number of fixtures where this capability was the #1 ranked suggestion. */
    topPickOn: number;
    /** Fixtures where the human expert picked this chart AND it was in top-3 ranking. */
    expertAgreementCount: number;
    /** Mean composite score across fixtures where it fit. */
    averageScore: number;
    /** Fraction of suggestions that included at least one caveat. */
    caveatCoverage: number;
    /** Fraction of suggestions that picked a non-base variant. */
    variantUtilization: number;
}
export interface PerFixtureScore {
    fixture: string;
    shape?: string;
    intent?: IntentId;
    expected?: ReadonlyArray<string>;
    topPick?: {
        component: string;
        variantKey?: string;
        score: number;
    };
    topThree: ReadonlyArray<{
        component: string;
        variantKey?: string;
        score: number;
    }>;
    fittingCount: number;
    rejectedCount: number;
    /** True if the top-3 ranking contained at least one expected component (when expected is provided). */
    expertAgreement: boolean | null;
    /** True if the #1 ranked suggestion was an expected component — the strict
     *  form of agreement. Reported alongside the lenient top-3 form so the
     *  scorecard can't flatter itself with close-second behavior. */
    topPickAgreement: boolean | null;
    /** Did the engine honor `expectsNoFit`? */
    noFitHonored: boolean | null;
}
export interface ScorecardReport {
    perCapability: PerCapabilityScore[];
    perFixture: PerFixtureScore[];
    summary: {
        fixtureCount: number;
        capabilityCount: number;
        /** Fraction of expectation-bearing fixtures where the engine agreed with the expert. */
        expertAgreementRate: number;
        /** Strict agreement: fraction of expectation-bearing fixtures where the
         *  engine's #1 pick was an expert pick. Always reported next to the
         *  lenient top-3 rate — the gap between the two is the honest measure of
         *  how often the engine is merely "not completely wrong." */
        top1AgreementRate: number;
        /** Average caveat coverage across all suggestions. */
        overallCaveatCoverage: number;
        /** Average variant utilization across all suggestions. */
        overallVariantUtilization: number;
    };
}
/**
 * Run the scorecard. Pure — does no I/O — so it can be called from CI scripts,
 * vizmart UIs, or test suites.
 */
export declare function runQualityScorecard(fixtures: ReadonlyArray<ScorecardFixture>, capabilities?: ReadonlyArray<ChartCapability>): ScorecardReport;
