/**
 * findings/ledger — where the model's standings become record.
 *
 * Pattern: one writer for one committed key (the twin of
 *          `core/agent/middleware/ledger.ts · recordDecisions`).
 * Role:    core/ layer leaf. The dispatch loop and the route decider build
 *          rows with `basisRowFrom` / `standingRowsFrom`; `recordFindings` is
 *          the ONLY thing that writes `AgentState.findingsLedger` and emits
 *          the matching events, so the two call sites cannot record the same
 *          declaration two different ways. `foldLedger` is the read: the
 *          current standing per result and the conflicts among what is
 *          stood on, recomputed from the rows every time.
 * Emits:   `agentfootprint.findings.declared` (one per basis row),
 *          `agentfootprint.findings.standing` (one per standing row),
 *          since 9.104.0 `agentfootprint.findings.judged` /
 *          `agentfootprint.findings.judge_failed` (one per judgment /
 *          judgment-error row, filed by `judge.ts`), and since 9.110.0
 *          `agentfootprint.findings.contingent` (one per contingent row,
 *          filed by the two moments `contingent.ts` serves: the route
 *          decider's answer and the dispatch loop's call) — identities,
 *          enums and numbers only. Assertion values, `settles`, `line`, the
 *          judged state, the contingent VALUE and — on an
 *          `unsettled-by-absence` row — a TOOL's own words (its envelope's
 *          `notChecked`, `cannotCover` and `tryInstead`) live in the
 *          committed key under whatever redaction the run configured; an
 *          event stream fans out to sinks we do not control. That row
 *          (9.113.0, filed by the same two moments through
 *          `unsettled.ts · withUnsettledRows`) emits nothing of its own, as
 *          a conflict row emits nothing of its own.
 *          Observe-only negative prose rows emit
 *          `agentfootprint.findings.negative_claim`: bounded locations,
 *          checker codes and native references, never the prose or values.
 *
 * ## Append only, last wins, conflicts are a fold
 *
 * A row is never replaced. A second standing on the same result is a second
 * row and the fold takes the LAST — the earlier one is quotable history, and
 * two rows that disagree are NOT a conflict (the algebra sees assertions,
 * never standings). A conflict row is written ONCE per key, at the write
 * whose stood-on readings first disagreed, from `conflictsOf`'s output and
 * never by hand; a later `ruled-out` retires a witness in the FOLD without
 * touching the row, so `foldLedger(...).conflicts` is the current set and the
 * conflict rows are the history of when each was first seen.
 *
 * ## Why the writer emits by literal
 *
 * The event names are the registry's `EVENT_NAMES.findings.declared` and
 * `.standing`; `typedEmit` binds the literal to `AgentfootprintEventMap`, so
 * a drift between this file and the registry is a compile error, exactly as
 * `recordDecisions` spells `agentfootprint.middleware.decision`.
 */
import { type FindingsRequest } from './admission.js';
import { type Conflict } from '../../../integrity/assertion/conflicts.js';
import { type Assertion } from '../../../integrity/assertion/types.js';
import { type BasisRow, type ConflictRow, type DeclaredOn, type FindingsDeclaration, type FindingsLedger, type FindingsRow, type JudgmentRow, type StandingRow, type UnsettledByAbsenceRow } from './types.js';
/** The scope surface this file needs. Structurally a `TypedScope<AgentState>`. */
export interface FindingsScope {
    findingsLedger?: FindingsLedger;
    $emit(name: string, payload?: unknown): void;
}
/**
 * One result a standing may name: an entry of the previous batch as
 * `AgentState.toolResults` holds it, or a served `role: 'tool'` message read
 * as one (`offer.ts · knownResults`). `toolName` is absent only for a served
 * message that carries none — never invented.
 */
export interface PreviousResult {
    readonly toolName?: string;
    readonly result: string;
    readonly toolCallId: string;
}
/** What `foldLedger` answers about a ledger. */
export interface LedgerFold {
    /** The LAST standing row per result id — the MODEL's current reading of each. */
    readonly standingOf: ReadonlyMap<string, StandingRow>;
    /**
     * The LAST judgment row per result id — the JUDGE's reading (9.104.0), a
     * second source kept apart: nothing here folds it into `standingOf`, and
     * `serve.ts` reads `standingOf` alone (policy A — the model's own standing
     * is what is served; docs/design/2026-09-findings-ledger.md § Judge).
     */
    readonly judgments: ReadonlyMap<string, JudgmentRow>;
    /** The assertions of the current `fact` rows, in fold order. */
    readonly asserted: readonly Assertion[];
    /** `conflictsOf(asserted)` — the current conflict set, not the rows' history. */
    readonly conflicts: readonly Conflict[];
    /** Whether any result has a standing at all. */
    readonly hasStanding: boolean;
    /**
     * The ruled-out standings that rest on an absence (9.113.0): the LAST
     * `unsettled-by-absence` row per result, kept only while that result's
     * CURRENT standing (`standingOf`) is still `ruled-out` — a later `fact`,
     * `open` or `noise` moved the model's word, and a row beside the earlier
     * word describes a standing that no longer stands. In the order each
     * result first got a row. The piece's `unsettled by absence` section reads
     * this and nothing else (`serve.ts · findingsLedgerPiece`).
     */
    readonly unsettled: ReadonlyMap<string, UnsettledByAbsenceRow>;
}
/**
 * Fold a ledger to its current reading. Pure; safe on a spread of the
 * committed key (a TypedScope array read is a live proxy view — spread it
 * into a plain array before calling anything here).
 */
export declare function foldLedger(rows: readonly FindingsRow[]): LedgerFold;
/**
 * The turn stamp (honesty layers, adopted Q6): while an honesty layer is
 * armed, every row the one writer files carries the conversation turn it was
 * filed in. Absent → rows are filed exactly as they always were.
 */
export interface TurnStamp {
    readonly turn: number;
}
/** What `appendRows` answers: the merged ledger and what the merge filed on its own. */
export interface AppendedRows {
    /** The ledger to commit — `prev`, the new rows, then any new conflict rows. */
    readonly ledger: FindingsRow[];
    /** The conflict rows this merge filed (a key whose readings first disagreed here). */
    readonly newConflicts: readonly ConflictRow[];
    /** The judge's current reading per result, for the standing event's `agrees`. */
    readonly judgments: ReadonlyMap<string, JudgmentRow>;
}
/**
 * THE PURE HALF of the one writer: merge `rows` onto `prev`, plus a conflict
 * row for every key that first disagreed at this merge. No scope, no event —
 * so a subflow's output mapper can merge rows its own stages already emitted
 * for (the inputs layer, `honesty/mounts.ts`) with the same fold the in-stage
 * callers use. Rows other than `fact` standings never enter `conflictsOf`, so
 * a merge of argument rows files no conflict.
 *
 * @example
 * ```ts
 * const { ledger } = appendRows(scope.findingsLedger ?? [], rows);
 * ```
 */
export declare function appendRows(prev: readonly FindingsRow[], rows: readonly FindingsRow[], stamp?: TurnStamp): AppendedRows;
/**
 * Append rows to the run's findings ledger, file a conflict row for every
 * key that first disagreed at this write, and emit one event per basis or
 * standing row. No-op on an empty list, so an armed agent whose model
 * declared nothing never writes the key — its commit log is the one it
 * always had. Callers pass basis and standing rows — each standing followed
 * by the `unsettled-by-absence` row the rule files beside it, when it files
 * one (`unsettled.ts · withUnsettledRows`); conflict rows are this function's
 * to write. Both halves of the one writer: `appendRows` (the merge) and
 * `emitRow` (the events). `stamp` is the honesty layers' turn stamp — passed
 * only while a layer is armed.
 */
export declare function recordFindings(scope: FindingsScope, rows: readonly FindingsRow[], stamp?: TurnStamp): void;
/**
 * THE EMIT HALF of the one writer: one event per row (identities, enums,
 * counts — never a value). Exported for the inputs layer's Record stage,
 * which emits inside its subflow and leaves the merge to the mount's output
 * mapper (`appendRows`).
 */
export declare function emitRow(scope: FindingsScope, row: FindingsRow, newConflicts?: readonly ConflictRow[], judgments?: ReadonlyMap<string, JudgmentRow>): void;
/**
 * One standing row per `previous[]` entry of a declaration. Identity comes
 * from `known` by `toolCallId` — the results the run can identify, which the
 * two call sites (the dispatch loop, the route decider) build with
 * `offer.ts · knownResults`: the served history's tool messages plus the
 * previous batch, the SAME history the offer was read from, so every id the
 * offer listed resolves. An id `known` does not hold is filed with
 * `unknownId: true` and no `toolName` — never resolved by position or by
 * name. Assertions follow the stratum rule: `fact` → asserted,
 * `open` / `ruled-out` → quoted, `noise` → none; the provenance is
 * `tool:<toolCallId>`, or `artifact:<ref>` when the result was placed;
 * `epoch` is never set.
 */
export declare function standingRowsFrom(known: readonly PreviousResult[], declaration: FindingsDeclaration, declaredOn: DeclaredOn, iteration: number, request?: {
    readonly witness: FindingsRequest | undefined;
}): StandingRow[];
/**
 * The basis row for one tool call. The declaration must carry a `basis` —
 * the dispatch loop files a row only when the model declared one, and a
 * caller that reaches here without one has broken that contract, which is
 * reported loudly rather than defaulted (never infer a basis).
 */
export declare function basisRowFrom(tc: {
    readonly id: string;
    readonly name: string;
}, declaration: FindingsDeclaration, iteration: number, malformed?: number): BasisRow;
