/**
 * Assertion resolution for literacy tasks.
 *
 * Handles rubric template resolution, doc-coverage auto-generation,
 * and baseline assertion filtering.
 */
import { resolveTemplatedAssertion } from "../../rubric-resolution.js";
// ---------------------------------------------------------------------------
// Assertion resolution
// ---------------------------------------------------------------------------
export function resolveAssertions(task, options, warnings, canonicalReference) {
    const assertions = [];
    for (const a of task.assertions ?? []) {
        if (a.type === "llm-rubric" && "template" in a) {
            const resolved = resolveTemplatedAssertion(a, options?.rubricConfig, options?.graderProvider, warnings, canonicalReference, options?.preflightContext);
            if (resolved)
                assertions.push(resolved);
        }
        else {
            assertions.push({
                type: a.type,
                ...("value" in a ? { value: a.value } : {}),
                ...(typeof a.weight === "number"
                    ? { weight: a.weight }
                    : {}),
                ...(a.type === "llm-rubric" && options?.graderProvider
                    ? { provider: options.graderProvider }
                    : {}),
            });
        }
    }
    // Doc-coverage auto-generation
    if (task.docCoverage) {
        const docCoverageAssertion = buildDocCoverageAssertion(options?.rubricConfig, options?.graderProvider, canonicalReference);
        if (docCoverageAssertion)
            assertions.push(docCoverageAssertion);
    }
    return assertions;
}
// ---------------------------------------------------------------------------
// Doc-coverage assertion
// ---------------------------------------------------------------------------
function buildDocCoverageAssertion(rubricConfig, graderProvider, canonicalReference) {
    if (!rubricConfig?.templates["doc-coverage"])
        return null;
    const template = rubricConfig.templates["doc-coverage"];
    const scaleText = template.scale.map((s) => `- ${s}`).join("\n");
    // W0273 — use the centralized wire-shape footer so the grader emission
    // parses against GraderEmittedJudgmentSchema. The pre-W0273 short
    // {score, reason} footer caused 100% parse failures starting 2026-05-11.
    const rubricValue = `${template.header}\n${scaleText}\n\n` + `${rubricConfig.footer}`;
    // doc-coverage benefits from the same authoritative reference — the grader
    // needs the doc content to judge whether the candidate actually used what
    // was documented.
    const rubricPrompt = canonicalReference
        ? buildDocCoverageRubricPrompt(rubricValue, canonicalReference)
        : undefined;
    return {
        type: "llm-rubric",
        value: rubricValue,
        ...(rubricPrompt ? { rubricPrompt } : {}),
        ...(graderProvider ? { provider: graderProvider } : {}),
        ...(template.dimension
            ? { metadata: { dimension: template.dimension, maxScore: 100 } }
            : {}),
    };
}
function buildDocCoverageRubricPrompt(rubric, reference) {
    return [
        "You are grading documentation coverage of a candidate response.",
        "",
        "AUTHORITATIVE REFERENCE — this is what the candidate had access to.",
        "Score how well the candidate used what was documented here. Do not",
        "penalize the candidate for missing information that is absent from",
        "the reference.",
        "",
        "--- BEGIN REFERENCE ---",
        reference,
        "--- END REFERENCE ---",
        "",
        "RUBRIC:",
        rubric,
        "",
        "CANDIDATE RESPONSE:",
        "{{output}}",
    ].join("\n");
}
// ---------------------------------------------------------------------------
// Baseline assertion filtering
// ---------------------------------------------------------------------------
/**
 * Build baseline assertions matching the legacy expand-tasks behavior.
 *
 * - "full": all assertions carried over
 * - "abbreviated": only first llm-rubric with shortened prompt
 * - "none": no assertions
 *
 * `rubricConfig` supplies the W0273 wire-shape footer for the abbreviated
 * mode's synthetic rubric. Without it the abbreviated emission would fail
 * `GraderEmittedJudgmentSchema.safeParse` (missing failureMode,
 * subJudgments, docCitations, confidence).
 */
export function buildBaselineAssertions(goldAssertions, rubricMode, rubricConfig) {
    const mode = rubricMode ?? "full";
    if (mode === "none")
        return [];
    if (mode === "full")
        return [...goldAssertions];
    // Abbreviated: keep first llm-rubric as summary, skip rest
    const abbreviated = [];
    let foundFirst = false;
    for (const a of goldAssertions) {
        if (a.type === "llm-rubric") {
            if (!foundFirst) {
                foundFirst = true;
                const footer = rubricConfig?.footer ??
                    'Return ONLY a JSON object: {"score": <number>, "reason": "<explanation>"}';
                abbreviated.push({
                    type: "llm-rubric",
                    value: "Score task completion from 0 to 100 (same criteria as above).\n" +
                        footer,
                    ...(a.provider ? { provider: a.provider } : {}),
                });
            }
        }
    }
    return abbreviated;
}
