/**
 * trustworthiness.ts — The single trust gate for reports (D0059).
 *
 * `includeInDefaultTrends` is the one definition of "show this report by
 * default." Every surface (dashboard analytics, Studio presets, the BigQuery
 * `reports.sql` view) references this predicate so the gate cannot drift
 * between consumers.
 *
 * Two orthogonal axes decide inclusion:
 *
 *  - **Validity (data health, D0059)** — the *primary* gate. A report is
 *    included only when its `validity.status` is `ok` OR validity is absent
 *    (pre-stamp reads are trusted until backfilled — the rollout is additive
 *    and nullable). Any non-`ok` status (`degraded` / `incomplete` /
 *    `suspect`) excludes the report regardless of intent.
 *  - **Intent (run classification, D0037)** — a *secondary* exclusion. The
 *    explicit `test` and `experimental` classifications are dropped;
 *    `adhoc` / `official` / `external` (and a missing classification) are kept.
 *    `adhoc` is intentionally included — it holds real production one-offs;
 *    the validity gate, not the intent gate, removes the bad ones inside it.
 *
 * We model a slim subset of the core `Report` shape (the two read axes) rather
 * than importing `Report` / `ReportValidity` from `@sanity/ailf-core`: this
 * package is the dependency-graph leaf and imports nothing from core. A full
 * core `Report` is structurally assignable to {@link TrustGateReport}.
 *
 * The predicate is total — it never throws — and is kept trivially
 * translatable to the two query-language forms it is materialized as on the
 * other surfaces (`W-studio-bigquery-validity`): the GROQ filter behind the
 * Studio "Trustworthy" preset ({@link INCLUDE_IN_DEFAULT_TRENDS_GROQ}) and the
 * SQL boolean in the BigQuery `reports.sql` view
 * ({@link INCLUDE_IN_DEFAULT_TRENDS_SQL}). Those constants live here, beside the
 * function, so the one gate cannot drift between consumers; a cross-check test
 * asserts all three forms agree across the full truth table.
 *
 * Note the SQL form is NULL-safe on *both* axes: a bare
 * `classification NOT IN ('test','experimental')` would evaluate to `NULL`
 * (not `TRUE`) for an unclassified row under SQL three-valued logic, silently
 * excluding pre-taxonomy reports the TS predicate keeps — hence the explicit
 * `classification IS NULL OR …`.
 *
 * @see docs/decisions/D0059-report-validity-axis-and-trustworthiness-gate.md
 * @see docs/design-docs/report-trustworthiness-model.md — §Decision/3
 */
/**
 * Whether a report should appear in default trend views.
 *
 * Validity is the primary gate; intent is a secondary exclusion. See the
 * module header for the full rationale and the equivalent SQL.
 *
 * @returns `true` when the report is trustworthy enough to show by default.
 */
export function includeInDefaultTrends(report) {
    const status = report.validity?.status;
    // Primary gate: trustworthy when explicitly `ok` or not yet assessed.
    const validityOk = status == null || status === "ok";
    const classification = report.provenance?.classification;
    // Secondary exclusion: drop explicit test/experimental intent only.
    const intentIncluded = classification !== "test" && classification !== "experimental";
    return validityOk && intentIncluded;
}
/**
 * GROQ form of {@link includeInDefaultTrends}, as a boolean expression over an
 * `ailf.report` document. Drop it into a Studio structure filter with the
 * document-type guard, e.g.
 * `` `_type == "ailf.report" && ${INCLUDE_IN_DEFAULT_TRENDS_GROQ}` ``.
 *
 * GROQ's `in` returns `false` (not `null`) for an absent left operand, so an
 * unclassified report passes the intent clause without an explicit
 * `defined(...)` guard — matching the TS predicate's "missing ⇒ kept" rule.
 * `defined(validity.status)` makes the absent-validity case trusted.
 */
export const INCLUDE_IN_DEFAULT_TRENDS_GROQ = '(!defined(validity.status) || validity.status == "ok") && !(provenance.classification in ["test", "experimental"])';
/**
 * SQL form of {@link includeInDefaultTrends}, as a boolean expression over the
 * flattened `ailf.reports` BigQuery row (columns `validity_status`,
 * `classification`). Materialized verbatim as the `include_in_default_trends`
 * column in `packages/eval/config/bigquery/views/reports.sql`; an eval test
 * asserts the view embeds this exact string.
 *
 * Both axes are NULL-safe so the column matches the TS predicate row-for-row:
 * `classification NOT IN (...)` alone is `NULL` for an unclassified row under
 * SQL three-valued logic, which a `WHERE`/boolean context treats as `FALSE` —
 * silently dropping pre-taxonomy reports the TS predicate keeps.
 */
export const INCLUDE_IN_DEFAULT_TRENDS_SQL = "(validity_status IS NULL OR validity_status = 'ok') AND (classification IS NULL OR classification NOT IN ('test', 'experimental'))";
