/**
 * @sanity/ailf-core — Report-validity detector (D0059)
 *
 * The detection brain for the report trustworthiness model. A pure, versioned,
 * I/O-free rules engine that computes both trustworthiness axes for a report —
 * intent (`classification`, D0037) and data health (`validity`) — with a
 * confidence tier so it never mislabels ambiguous data.
 *
 * Reused unchanged by the eval write path (`W-stamp-validity-write-path`,
 * stamps every new report) and the one-shot backfill
 * (`W-backfill-report-validity`, labels the historical store).
 *
 * **Confidence tiers (D0059 §2):**
 *
 *   - **Tier 1 — auto.** High-confidence, unambiguous rules. Intent:
 *     `scheduled + github-actions → official`; `testing-ground` team /
 *     `env-override` source / generated-id executor → `test`/`experimental`;
 *     de-drift `ad-hoc → adhoc`. Validity: `degraded → "degraded"`; an
 *     otherwise-`ok` report whose `errorSummary` trips the shared error
 *     condition (a fully-errored task, or error-rate ≥ threshold) →
 *     `"suspect"` (eval failure observability, B2 — `degraded` outranks it).
 *   - **Tier 2 — review list.** Anything resting on shape-sensitive content
 *     signals (empty `testResults`, `testCount` mismatch) is *emitted to a
 *     review list rather than guessed* — 34%/66% of the historical store hits
 *     these and is dominated by report-shape evolution (GCS-externalized
 *     per-test data, per-model granularity), NOT defects. The engine never
 *     auto-flags them invalid; a human confirms in batch and the verdict is
 *     written `method:"manual"`.
 *
 * A `method:"manual"` verdict is authoritative — re-running the detector never
 * overwrites it.
 *
 * @see docs/decisions/D0059-report-validity-axis-and-trustworthiness-gate.md
 * @see docs/design-docs/report-trustworthiness-model.md
 */
import { type RunClassification, type RunExecutor, type RunOwner, type RunTrigger } from "../../ailf-shared/index.d.ts";
import type { ErrorSummary, ReportDegradation, ReportValidity } from "../types/index.js";
/**
 * Detector ruleset version. Bump on any rule or threshold recalibration so a
 * later re-assessment is a comparable, auditable re-run (D0059 §2). Stamped
 * onto every `validity` verdict the engine produces.
 */
export declare const REPORT_VALIDITY_RULESET_VERSION = "1.1.0";
/**
 * The minimal report projection the detector reads.
 *
 * Authored as a raw-tolerant *consumer view* (not `Pick<Report, …>`) on
 * purpose: the engine runs at the raw-document boundary during the backfill,
 * where legacy drift like `ad-hoc` still exists and `provenance.classification`
 * is therefore typed `string`, not `RunClassification`. A fully-typed `Report`
 * is structurally assignable to this shape, so the write path can pass one
 * directly. Only the seven fields the rules actually consult appear here.
 */
export interface ReportValidityInput {
    provenance: {
        /** Raw classification — may carry legacy drift (`ad-hoc`); normalized here. */
        classification?: string;
        trigger: RunTrigger;
        executor: RunExecutor;
        owner: RunOwner;
        source: {
            name: string;
        };
    };
    summary: {
        /** Per-feature scores; only `testCount` is read (summed across features). */
        scores?: readonly {
            testCount?: number;
        }[];
        /** Per-test×model results; only the length is read. */
        testResults?: readonly unknown[];
        /** Low-scoring grader judgments; only the length is read. */
        lowScoringJudgments?: readonly unknown[];
        /**
         * Typed error signal (eval failure observability, B1). Drives the Tier-1
         * `suspect` rule via the shared {@link errorSummaryTrips} predicate. Absent
         * on pre-B1 reports — treated as "no error data" (never trips).
         */
        errorSummary?: ErrorSummary;
    };
    /** Legacy degradation marker (D0059 subsumes it into `validity.status`). */
    degraded?: ReportDegradation;
    /** Existing verdict — a `method:"manual"` value is preserved on re-run. */
    validity?: ReportValidity;
}
/**
 * Why a report was routed to Tier-2 human review instead of being
 * auto-decided. Each corresponds to a shape-sensitive signal the engine
 * deliberately refuses to interpret automatically (D0059 §caveat).
 */
export type ReportValidityReviewReason = "empty-test-results" | "test-count-mismatch";
/** A single Tier-2 review-list entry. */
export interface ReportValidityReviewFlag {
    reason: ReportValidityReviewReason;
    /** Human-readable explanation for the batch-review UI / backfill report. */
    detail: string;
}
/**
 * The detector's verdict for one report.
 *
 * `classification` is **optional**: present only when the engine has a
 * positive opinion (a Tier-1 intent rule fired, or de-drift changed the
 * value). It is `undefined` when the existing classification is already
 * canonical and no rule applies — so callers patch idempotently and a re-run
 * never clobbers an already-correct or human-corrected value.
 */
export interface ReportValidityAssessment {
    classification?: RunClassification;
    validity: ReportValidity;
    reviewFlags: ReportValidityReviewFlag[];
}
export interface AssessReportValidityOptions {
    /**
     * ISO 8601 UTC timestamp stamped onto the verdict's `assessedAt`. Injected
     * by the caller so the engine stays pure and deterministic (no clock read).
     */
    assessedAt: string;
}
/**
 * Assess a report's trustworthiness — its intent (`classification`) and data
 * health (`validity`) — plus any Tier-2 signals that need human review.
 *
 * Pure and deterministic: same input + `assessedAt` → identical output.
 */
export declare function assessReportValidity(report: ReportValidityInput, options: AssessReportValidityOptions): ReportValidityAssessment;
