/**
 * Which eval sub-runs a pipeline configuration requires, and whether every one
 * of them was satisfied by a remote-cache hit.
 *
 * The post-scoring enrichment steps (gap-analysis, compute-attribution) may
 * skip benignly when grader judgments are absent because ALL required runs came
 * from the remote cache — a cache hit restores `score-summary.json` but never
 * writes `grader-judgments.json`. They must NOT skip when at least one required
 * run was evaluated fresh this pipeline: a fresh run that scored tests yet
 * persisted no judgments is a degraded outcome that has to fail loud.
 *
 * Mirrors the required-run derivation in `calculate-scores-step` so the
 * "all required runs cached" judgement is defined in exactly one place.
 */
import { LiteracyVariant } from "../pipeline/normalize-mode.js";
/**
 * The eval sub-runs a configuration requires, keyed by the same strings
 * `RunEvalStep` records in `state.remoteCacheHits` (`"baseline"`, `"agentic"`,
 * or the bare mode name for non-literacy modes).
 */
export function requiredEvalRuns(config) {
    if (config.mode === "literacy") {
        const variant = config.variant ?? LiteracyVariant.STANDARD;
        return variant === LiteracyVariant.FULL
            ? [LiteracyVariant.STANDARD, LiteracyVariant.AGENTIC]
            : [variant];
    }
    return [config.mode];
}
/**
 * True only when every eval sub-run the configuration requires was satisfied by
 * a remote-cache hit. A cache hit on a subset of required runs (e.g. agentic
 * cached, baseline fresh) returns false — the fresh run's outputs are still the
 * pipeline's responsibility.
 */
export function allRequiredEvalRunsCached(config, state) {
    const hits = state?.remoteCacheHits;
    if (!hits || hits.size === 0)
        return false;
    return requiredEvalRuns(config).every((run) => hits.has(run));
}
