/**
 * assessment/witness — the answer layer's committed witness rows: two verdicts
 * the Route decider computes that were EVENTS only until the answer layer
 * (honesty layer 4) needed them on the record.
 *
 * Pattern: Map. Three row types, their builders and their well-formedness
 *          check — the one owner of the `grounded`, `steps-unfinished` and
 *          `script-shown` row kinds.
 *          `findings/types.ts` · `FindingsRow` imports the types; the rows
 *          are filed through the one writer (`findings/ledger.ts` ·
 *          `recordFindings`) by the Route decider, and ONLY while the answer
 *          layer is armed (`stages/route.ts` · `judgeEvidence`,
 *          `judgeUnfinishedSteps`).
 * Role:    core/ layer leaf of the answer layer. Static on purpose: the
 *          checkpoint door (`core/runCheckpoint.ts` · `validateCheckpoint`,
 *          a synchronous door) asks `witnessRowIsWellFormed`, so this module
 *          imports nothing but the script labels (`../scripts/label.ts`, a
 *          leaf) and stays small.
 * Emits:   N/A. A witness row emits nothing of its own — the verdict's event
 *          (`agentfootprint.agent.evidence_checked`,
 *          `agentfootprint.skill.steps_unfinished`) already fired, beside the
 *          row, from the same stage.
 *
 * ## Why a row, when the event already says it
 *
 * The answer's standing is folded from COMMITTED rows only
 * (`assessment/assess.ts` · `assessAnswer`), never from events, so the running
 * agent and every later reader fold the same bytes. A verdict that exists only
 * as an event cannot be folded: the gate's clean pass could not say "the names
 * and numbers check ran", and an answer given before its declared steps
 * finished could not say so at all. Each row is the verdict, not a copy of the
 * event: names, enums and counts — never a value from the answer, a quote, or
 * a step's note.
 *
 * ## Always stamped with the turn
 *
 * The ledger crosses turns on a continued conversation and `iteration`
 * restarts at 1 every run, so a witness row always carries `turn`
 * (`AgentState.turnNumber`): the fold reads this turn's witness rows only.
 */
import type { ScriptBlockVerdict, ScriptLabel, UnmatchedReason } from '../scripts/types.js';
/** The evidence gate's posture — the `.namesAndNumbersFromEvidence()` vocabulary. */
export type WitnessPosture = 'assist' | 'guard' | 'rails';
/**
 * The evidence gate's CLEAN verdict on the answer (`action: 'grounded'` on
 * `agentfootprint.agent.evidence_checked`): every name and number the answer
 * states was found in a tool result, or was exempt. Filed by the Route decider
 * on the turn's answer while the answer layer is armed. A flagged or refused
 * verdict needs no witness row — `AgentState.unsupportedValues` is already
 * committed.
 *
 * The fold reads it as the names-and-numbers check having RUN on this answer —
 * never as support: finding a value in a tool result is a membership pass, and
 * a membership pass never makes an answer "known".
 */
export interface GroundedRow {
    readonly kind: 'grounded';
    /** `AgentState.turnNumber` when the row was filed — the conversation turn. */
    readonly turn: number;
    /** The iteration whose answer the gate judged. */
    readonly iteration: number;
    /** The posture in force. */
    readonly posture: WitnessPosture;
    /** How many distinct values the answer had to ground, exempt ones included. */
    readonly candidates: number;
    /** How many of `candidates` the gate looked up in the tool results (the rest were exempt). */
    readonly lookedUp: number;
    /** Set when the grounded answer was the one revision the gate asked for. */
    readonly afterRevision?: true;
}
/** One declared step the answer came before — its position and its tool, never its note. */
export interface UnfinishedStep {
    readonly index: number;
    readonly tool: string;
}
/**
 * The answer came before the active skill's declared steps finished
 * (`agentfootprint.skill.steps_unfinished` with `action: 'accepted'` — the one
 * teaching nudge was already spent — or `'cut-short'` — a limit forced the
 * answer). Filed by the Route decider while the answer layer is armed, and
 * only for the answer that STANDS: the step judge runs before the evidence
 * gate, so a stop it accepted on a draft the gate then sends back files no row
 * (the event still fires) — the revision is judged again, and at most one row
 * per answer reaches the ledger. The `'nudged'` verdict needs no row: the turn
 * went on.
 */
export interface StepsUnfinishedRow {
    readonly kind: 'steps-unfinished';
    /** `AgentState.turnNumber` when the row was filed — the conversation turn. */
    readonly turn: number;
    /** The iteration whose answer the step judge read. */
    readonly iteration: number;
    /** The skill whose procedure was in progress. */
    readonly skillId: string;
    /** The declared steps not reached, in order — position and tool only. */
    readonly remaining: readonly UnfinishedStep[];
    /** How many steps the procedure declares. */
    readonly total: number;
    readonly action: 'accepted' | 'cut-short';
}
/**
 * One fenced block the answer SHOWED, and the script match's verdict on it
 * (`.namesAndNumbersFromEvidence({ code: 'match' })`, `scripts/match.ts`) —
 * filed by the Route decider while the answer layer is armed, one row per
 * block read, and only for the answer that STANDS (a draft sent back for
 * revision files none). Names, enums and counts — never the code.
 *
 * The fold reads `label: 'unmatched'` as the reason `script-unmatched` (a
 * script shown in the answer matches no submission of this turn on the
 * record), and every row as the `script-match` check having reached a
 * verdict. A matched block fires nothing and supports nothing.
 */
export interface ScriptShownRow {
    readonly kind: 'script-shown';
    /** `AgentState.turnNumber` when the row was filed — the conversation turn. */
    readonly turn: number;
    /** The iteration whose answer the match read. */
    readonly iteration: number;
    /** 1-based position among the answer's fenced blocks that were read. */
    readonly block: number;
    /** The matched call's label, or `'unmatched'`. */
    readonly label: ScriptLabel | 'unmatched';
    /** On `'unmatched'`: why. */
    readonly reason?: UnmatchedReason;
    /** On a match: the call it equals, and the name the model called. */
    readonly toolCallId?: string;
    readonly tool?: string;
    /** On a match: the call's dispatch within the turn (`ScriptRow.dispatch`) — its identity. */
    readonly dispatch?: number;
    /** On a match: exactly the runner's exit code, when it supplied one. */
    readonly exitCode?: number;
}
/** Either witness row. */
export type AnswerWitnessRow = GroundedRow | StepsUnfinishedRow | ScriptShownRow;
/** The script match's verdicts as rows — one per block read, ids and labels only. */
export declare function scriptShownRowsFrom(blocks: readonly ScriptBlockVerdict[], at: {
    readonly turn: number;
    readonly iteration: number;
}): ScriptShownRow[];
/** The gate's clean verdict as a row — built from the event's own counts. */
export declare function groundedRowFrom(verdict: {
    readonly turn: number;
    readonly iteration: number;
    readonly posture: WitnessPosture;
    readonly candidates: number;
    readonly lookedUp: number;
    readonly afterRevision: boolean;
}): GroundedRow;
/** The step judge's accepted or cut-short verdict as a row — each step's position and tool only. */
export declare function stepsUnfinishedRowFrom(verdict: {
    readonly turn: number;
    readonly iteration: number;
    readonly skillId: string;
    readonly remaining: readonly {
        readonly index: number;
        readonly tool: string;
    }[];
    readonly total: number;
    readonly action: 'accepted' | 'cut-short';
}): StepsUnfinishedRow;
/**
 * Whether a value read from a stored checkpoint is a witness row this library
 * could have written: the kind, a numeric `turn` and `iteration`, and every
 * other field in its own shape. The checkpoint door's two arms
 * (`core/runCheckpoint.ts`). An older runtime refuses a checkpoint that
 * carries either kind.
 */
export declare function witnessRowIsWellFormed(r: Readonly<Record<string, unknown>>): boolean;
