/**
 * # blotter/model-registry — the MODEL_KNOWLEDGE_CUTOFF fence + the pinned month-boundary rule (kestrel-m9i.23)
 *
 * The declared `envelope.training_cutoff` (a57.14) is the basis for **model-relative holdback**: a tape
 * date is "post-cutoff" (holdback-eligible, ranking) iff it falls after the model's knowledge cutoff. A
 * DECLARED cutoff is only trustworthy if it AGREES with the platform model registry — so this module is the
 * ONE place that holds all three pieces of that verification, co-located so the boundary logic is never
 * duplicated (SYSTEM-PROFILE.md line 41; the [PLANNED kestrel-m9i.23] item resolved here):
 *
 *   1. {@link MODEL_KNOWLEDGE_CUTOFF} — the fence: model id → knowledge-cutoff month (`YYYY-MM`). The local
 *      MIRROR of the platform `fence.ts` registry (attestation-side, ATT — this repo verifies against a
 *      pinned copy; it never mutates the platform fence). Keyed by the model id, closed by construction: an
 *      id with no entry is UNKNOWN (fail-closed), never an open default.
 *   2. {@link isPostCutoff} — the SOLE month-boundary rule: a tape date is post-cutoff IFF *strictly after
 *      the last day of the declared cutoff month*. Declared `2025-10` gates through `2025-10-31` inclusive;
 *      `2025-11-01` is the first post-cutoff day. This is the only place the boundary is computed — the
 *      post-cutoff *classification* (kestrel-m9i.25) consumes this function, never a second copy of the rule.
 *   3. {@link checkTrainingCutoff} — the fail-closed lookup + declared-vs-registry cross-check. Returns the
 *      registry cutoff when the declared value is consistent, else a typed {@link TrainingCutoffReason}
 *      (unknown model id | declared-vs-registry mismatch) NAMING the disagreement — never a silent default,
 *      never a silent correction of the declared value. The a57.14 projector ({@link ./project.ts}) renders
 *      the reason's `detail` onto `certification.reasons` and fails the Blotter closed to PROVISIONAL.
 *
 * PURE and DETERMINISTIC (RUNTIME §0): every export is a function of its arguments (the model id, the
 * declared cutoff, the tape date) — no wall clock, no RNG, no I/O. The `TrainingCutoffReason` type lives in
 * the built-in-free bus leaf (`../bus/types.ts`, `import type` only) so this module pulls no Bun/node
 * built-in into the light type graph (kestrel-exx: no bus BARREL import on a light-reachable path).
 */
import type { TrainingCutoffReason } from "../bus/types.ts";
/**
 * The **model knowledge-cutoff fence** (kestrel-m9i.23): model id → knowledge-cutoff month (`YYYY-MM`). The
 * local mirror of the platform `fence.ts` `MODEL_KNOWLEDGE_CUTOFF` registry — a declared `training_cutoff`
 * is cross-checked against the entry for its model id. Keyed by the model id; an id absent here is UNKNOWN
 * and fails closed (never treated as post- or pre-cutoff). The entries are the model ids the graded fixtures
 * declare; a new registered model is added HERE (one definition, no drift), matching the platform fence.
 */
export declare const MODEL_KNOWLEDGE_CUTOFF: Readonly<Record<string, string>>;
/**
 * DELIBERATELY-UNREGISTERED models — KNOWN to the roster/lanes but kept OUT of {@link MODEL_KNOWLEDGE_CUTOFF}
 * because their training-knowledge cutoff is UNPUBLISHED. Absence from the fence above is the fail-closed
 * marker (an id with no cutoff entry is UNKNOWN ⇒ {@link checkTrainingCutoff} returns `unknown-model-id`, so
 * the row can never certify as post-cutoff). This constant makes that omission EXPLICIT and greppable — the
 * difference between "we forgot" and "we know, and it is deliberately fail-closed until the model card
 * publishes the cutoff". Register the real `YYYY-MM` by MOVING the id INTO the map above the moment it is
 * published; do NOT guess a cutoff (a guessed cutoff would gate contamination on a fiction). The value here
 * is the HUMAN REASON, never a cutoff month — nothing reads it as a boundary.
 *
 * kestrel-2ojt (owner directive 2026-07-17): Kimi K3 (`kimi-k3` / gateway `moonshotai/kimi-k3`) shipped
 * 2026-07-16; weights + model card land 2026-07-27; Moonshot has published NO training cutoff. Until it
 * does, K3 is fail-closed here and CANNOT enter the post-cutoff corpus window. A brand-new model's RECENT
 * cutoff also SHRINKS its post-cutoff window (less untrained tape to grade over) — flag for the corpus
 * program. The platform mirror `apps/api/src/bench/fence.ts` (DAY granularity, `YYYY-MM-DD`) needs the same
 * deliberate omission; that is a platform-side follow-up, not editable from this OSS repo.
 */
export declare const CUTOFF_UNKNOWN_PENDING: Readonly<Record<string, string>>;
/**
 * The typed outcome of the fail-closed cross-check: the registry cutoff month when the declared value is
 * consistent (`ok: true`), else a typed {@link TrainingCutoffReason} (`ok: false`) — a discriminated result,
 * never a silent default and never a silent correction of the declared value.
 */
export type TrainingCutoffCheck = {
    readonly ok: true;
    readonly cutoffMonth: string;
} | {
    readonly ok: false;
    readonly reason: TrainingCutoffReason;
};
/**
 * The SOLE month-boundary rule (kestrel-m9i.23): a tape date is **post-cutoff IFF strictly after the last
 * day of the declared cutoff month**. For zero-padded ISO tokens that is exactly the tape date's own
 * `YYYY-MM` being lexicographically greater than the cutoff's `YYYY-MM`: any day WITHIN the cutoff month —
 * including its last day — shares the month key and is NOT after it, and the first day of the following month
 * is the first strictly-greater key (the year-wrap is handled by the fixed-width comparison, so a `2025-12`
 * cutoff gates through `2025-12-31` and `2026-01-01` is post-cutoff). Declared `2025-03` ⇒ `2025-03-31` is
 * NOT post-cutoff, `2025-04-01` IS. Pure and deterministic — no wall clock (RUNTIME §0). This is the ONLY
 * place the boundary is computed; consumers (post-cutoff classification, kestrel-m9i.25) call it, never fork it.
 *
 * @param cutoffMonth the declared cutoff month (`YYYY-MM`)
 * @param tapeDate    the tape/session date (`YYYY-MM-DD`)
 */
export declare function isPostCutoff(cutoffMonth: string, tapeDate: string): boolean;
/**
 * The fail-closed lookup + declared-vs-registry cross-check (kestrel-m9i.23), keyed by the model id. An
 * attestation-side VERIFICATION (ATT), never a rewrite:
 *
 *   - the model id has NO registry entry ⇒ `unknown-model-id`: the declared cutoff cannot be verified, so the
 *     row cannot certify as post-cutoff (NOT silently treated as post- or pre-cutoff);
 *   - the model id is registered but the declared cutoff DISAGREES with the registry's ⇒
 *     `declared-registry-mismatch`: the declared value is RECORDED verbatim (never rewritten to the
 *     registry's), with both cutoffs named;
 *   - otherwise the declared cutoff matches the registry ⇒ `ok`, carrying the registry cutoff month.
 *
 * Pure and deterministic — a function of the model id + the declared cutoff alone (no wall clock, no RNG).
 */
export declare function checkTrainingCutoff(input: {
    model: string;
    declaredCutoff: string;
}): TrainingCutoffCheck;
/**
 * A cutoff whose value is **vendor-published** (a spec claim in {@link MODEL_KNOWLEDGE_CUTOFF}) or
 * **empirically-bounded** — MEASURED by the Knowledge-Horizon Eval (kestrel-cf62): a conservative upper
 * bound derived from dated-headline discrimination accuracy vs the 50% chance anchor. The empirical kind
 * gives the fail-closed `unknown-model-id` path a remedy: probe the model, register the measured bound.
 *
 * Rule 10 (declared): the empirical bound is a MECHANICAL MEASUREMENT — no capability is attributed.
 */
export type CutoffSource = {
    readonly kind: "vendor-published";
    readonly cutoffMonth: string;
} | {
    readonly kind: "empirically-bounded";
    readonly cutoffMonth: string;
    /** The exact probe run id — VERSION-PINNING: a bound binds to the model id+version it was measured on. */
    readonly probeRunId: string;
    /** The PROVIDER-RESPONSE-reported model id the probe run recorded (kestrel-cf62, PR #300 F4):
     * the pin's other half — registration refuses when this disagrees with the registry key, so a
     * bound measured on one model version can never be filed under another id. */
    readonly reportedModelId: string;
    /** Path/handle of the fitted-curve artifact kept for audit. */
    readonly curveArtifact: string;
    /** The declared conservative safety margin (months) ADDED to the latest above-chance bin
     * (over-fence headroom — leak-safety requires cutoff ≥ true horizon, PR #300 F1). */
    readonly margin: number;
};
/**
 * The empirically-bounded registry (kestrel-cf62): model id → measured cutoff source. Populated by a
 * probe run via {@link registerEmpiricalBound}; consulted alongside the vendor-published fence. Keyed by
 * the EXACT model id the probe reported (version-pinning). Starts empty — a bound exists only once measured.
 */
export declare const EMPIRICAL_CUTOFF_BOUNDS: Record<string, Extract<CutoffSource, {
    kind: "empirically-bounded";
}>>;
/** The version-pinning gate outcome (kestrel-cf62): a validated bound, or a typed refusal NAMING the defect. */
export type EmpiricalBoundCheck = {
    readonly ok: true;
    readonly source: Extract<CutoffSource, {
        kind: "empirically-bounded";
    }>;
} | {
    readonly ok: false;
    readonly detail: string;
};
/**
 * The VERSION-PINNING gate (kestrel-cf62, PR #300 F4): an `empirically-bounded` source is only
 * acceptable if it carries a non-empty `probeRunId` AND a non-empty `reportedModelId` that AGREES
 * with the model id being registered AND a non-empty `curveArtifact` AND a non-negative margin AND a
 * well-formed `YYYY-MM` cutoff. An unpinned bound (no run id / no artifact) or a MISMATCHED pin (the
 * probe's provider-reported model id is not the id being filed) is REFUSED — a registry entry must
 * always trace to the exact probe AND the exact model version that produced it. Pure and
 * deterministic.
 *
 * @param model the registry key the bound is being validated FOR (the requested seat id)
 */
export declare function validateEmpiricalBound(model: string, source: Extract<CutoffSource, {
    kind: "empirically-bounded";
}>): EmpiricalBoundCheck;
/**
 * Register a measured bound for a model id (the remedy the unknown-model-id path names). Passes the
 * version-pinning gate first — an unpinned bound is never registered. Returns the check so callers can
 * surface the refusal. Keyed by the exact reported model id.
 */
export declare function registerEmpiricalBound(model: string, source: Extract<CutoffSource, {
    kind: "empirically-bounded";
}>): EmpiricalBoundCheck;
/**
 * Resolve a model id's cutoff from EITHER source: the vendor-published fence takes precedence (it is the
 * attested spec), else a validated empirical bound if one has been measured. Returns null when neither
 * exists — still fail-closed, but now the caller knows to run the probe.
 */
export declare function resolveCutoffSource(model: string): CutoffSource | null;
//# sourceMappingURL=model-registry.d.ts.map