/**
 * ontology/score — did an answer name the declared gap, and where the need
 * would be met? Scored off the record, by declared strings, with no judge.
 *
 * Pattern: pure functions over the served spec and one turn's own facts
 *          (the answer text, the tool names called, the library's own
 *          unsupported-values verdict). No model, no clock, no I/O.
 * Role:    Lens, for a BENCH. It is the measuring stick the design page
 *          promised (docs/design/2026-09-ontology.md § Measured): the first
 *          number for "the answer names the source" was a regex over prose;
 *          this is the rule that replaces it, so every wording change is
 *          measured the same way. Exported on the `agentfootprint/ontology`
 *          door because the map's consumer runs the bench on ITS host with
 *          ITS questions, and the rules must be the library's, not re-derived
 *          there.
 * Emits:   N/A.
 *
 * THE LAW OF THE SCORE
 *   A check matches DECLARED STRINGS ONLY — a term's or a source's id and
 *   aliases, a tool's name — whole-word, case-insensitive, an `_` in an
 *   id standing for a space or a hyphen, a plural `s` allowed. Nothing fuzzier. So an answer that
 *   says "UCS Manager" when the source's id is `influx_ucs` and no alias says
 *   "UCS Manager" scores NO, and that is the point: the declaration must
 *   carry the words people use, because those are the words the model
 *   reads too. The scorer never decides an answer is good; it counts what
 *   the answer names.
 *
 * THE EXPECTATION IS THE BENCH AUTHOR'S, DECLARED BEFORE THE RUN
 *   `expected.gap` names the term or source the question turns on — the
 *   `_findings.expect` precedent: declared before the call, judged after. A
 *   gap that names nothing the spec declares is refused, naming it: a bench
 *   whose oracle lies must fail loudly, as a map naming an unregistered tool
 *   does at build.
 */
import type { OntologySpec } from './types.js';
/** What a bench question declares about itself, before the run. */
export interface AbsenceExpectation {
    /**
     * The declared gap the answer should name: a term id or a source id of
     * the served map. Absent when the question expects DATA, not a gap — then
     * only the counts are read and the two naming checks are `undefined`.
     */
    readonly gap?: string;
}
/** One turn's own facts, read off the record by the caller. */
export interface AbsenceTurn {
    /** The final answer, as returned. */
    readonly answer: string;
    /** The tool names the model called this turn, in order. */
    readonly toolCalls: readonly string[];
    /**
     * The library's own verdict on values the answer stated that no tool
     * result carried (`AgentState.unsupportedValues.values.length`), when the
     * evidence gate was armed and the record carries it. Absent otherwise.
     */
    readonly unsupportedValues?: number;
}
/** The score of one turn — every field a count, a yes/no, or the strings that matched. */
export interface AbsenceScore {
    /** The expected gap, as declared. */
    readonly gap: string | undefined;
    /** What the spec says the gap is. `'none'` when no gap was expected. */
    readonly gapKind: 'term' | 'source' | 'none';
    /** The answer contains the gap's id or one of its declared aliases. `undefined` when no gap was expected. */
    readonly namedGap: boolean | undefined;
    /**
     * The answer contains a declared neighbour of the gap — a source that holds
     * the term, a tool that reads it, a term one relation away; for a source,
     * a term it holds or a tool that reads through it. `undefined` when no gap
     * was expected or the spec declares no neighbour for it.
     */
    readonly namedWhere: boolean | undefined;
    /** The neighbours the answer named, by declared id — the evidence for `namedWhere`. */
    readonly where: readonly string[];
    /** The neighbours the spec declares for the gap — what `namedWhere` was checked against. */
    readonly neighbours: readonly string[];
    /** Tool calls this turn. */
    readonly toolCalls: number;
    /** The library's unsupported-values count, as handed in; `undefined` when the record carried none. */
    readonly unsupportedValues: number | undefined;
    /**
     * The words of the map the answer used on the person — `ontology` and its
     * forms, `map` and `maps`: the header's own vocabulary the ask says to keep
     * from the person. A wording metric, reported as the words found.
     */
    readonly mapWords: readonly string[];
}
/** The tally over many turns — `k` of `n` per check, counts summed. */
export interface AbsenceSummary {
    readonly turns: number;
    readonly namedGap: {
        readonly k: number;
        readonly n: number;
    };
    readonly namedWhere: {
        readonly k: number;
        readonly n: number;
    };
    readonly citedMap: {
        readonly k: number;
        readonly n: number;
    };
    readonly toolCalls: number;
    /** Summed over the turns whose record carried a verdict; `undefined` when none did. */
    readonly unsupportedValues: number | undefined;
}
/**
 * Score one turn against the served map and the bench's expectation.
 * Throws when `expected.gap` names nothing the spec declares.
 */
export declare function scoreAbsence(spec: OntologySpec, turn: AbsenceTurn, expected?: AbsenceExpectation): AbsenceScore;
/** The tally: `k` of `n` per yes/no check over the turns that had one; counts summed. */
export declare function summarizeAbsence(scores: readonly AbsenceScore[]): AbsenceSummary;
