/**
 * no-issues card — deterministic guard against sycophantic "all is well" reports.
 *
 * Only fires when ALL areas in the report scored at or above
 * `NO_ISSUES_THRESHOLD`. The threshold is calibrated to keep the firing rate
 * ≤30% per AI-SPEC §1b failure-mode #7 (sycophantic no-issues).
 *
 * Pure computation, no LLM call. Uses `report.summary.scores` — each
 * `FeatureScore.totalScore` is the composite (0–100 scale).
 *
 * Schema is in the D0045 trust-boundary scan root; `satisfies` clause is
 * mandatory (cards/ is a SCAN_ROOT in check-trust-boundary-satisfies.ts).
 *
 * @see .planning/phases/05-diagnosis-engine-cli-llm-cards/05-AI-SPEC.md §1b failure-mode #7
 */
import { z } from "zod";
// ---------------------------------------------------------------------------
// Threshold constant (calibration)
// ---------------------------------------------------------------------------
/**
 * Threshold above which a Report area is considered "no issues" per the
 * team's action threshold (AI-SPEC §1b failure-mode #7). Tuned against
 * the fixture set in no-issues.test.ts to keep firing rate ≤30%.
 *
 * At 85, only reports where every area scores ≥85 trigger this card.
 * On the 10-report fixture spanning 0–99, only reports at [90,92],
 * [95,97], [98,99] qualify — a 3/10 = 30% firing rate (right at the cap).
 */
export const NO_ISSUES_THRESHOLD = 85;
// ---------------------------------------------------------------------------
// Body schema (D0045 trust boundary — satisfies required)
// ---------------------------------------------------------------------------
export const NoIssuesBodySchema = z.object({
    summary: z.string().min(1).max(500),
    thresholdScore: z.number(),
});
// ---------------------------------------------------------------------------
// Generator
// ---------------------------------------------------------------------------
export const generateNoIssues = async (report) => {
    const scores = report.summary.scores;
    if (!scores || scores.length === 0) {
        return {
            status: "missing",
            cardType: "no-issues",
            reason: "report has no areas",
        };
    }
    const allAboveThreshold = scores.every((s) => s.totalScore >= NO_ISSUES_THRESHOLD);
    if (!allAboveThreshold) {
        return {
            status: "missing",
            cardType: "no-issues",
            reason: "at least one area scored below threshold",
        };
    }
    const summary = `All ${scores.length} areas scored ≥${NO_ISSUES_THRESHOLD} — no action required.`;
    const body = NoIssuesBodySchema.parse({
        summary,
        thresholdScore: NO_ISSUES_THRESHOLD,
    });
    return {
        status: "ready",
        cardType: "no-issues",
        body,
        meta: {
            cardVersion: "no-issues@0.1.0",
            generatedAt: new Date().toISOString(),
        },
    };
};
