/**
 * results/subflow — the four stages of the results layer's subflow
 * (`sf-results`): Declare → Verify → Record → Resolve (honesty layer 3).
 *
 * Pattern: thin stage bodies over three pure steps (`planPeriods`,
 *          `checkPeriods`, `periodRowsOf`). Each stage reads what the one
 *          before it staged on the subflow's own (isolated) scope and stages
 *          its own output; the mount's output mapping (`honesty/mounts.ts` ·
 *          `mountResultsLayer`) merges the rows into the ONE ledger in one
 *          write.
 * Role:    core/ layer, the results layer. Loaded through `import()` by the
 *          mount's stage wrappers — never on a plain agent's graph. Its rules
 *          stay with their data: the period's shape, its rule set and the
 *          verdict are `coverage/period.ts`'s; the ledger's merge and emit
 *          halves are `findings/ledger.ts`'s, handed in as `deps`.
 * Emits:   `agentfootprint.findings.period` — one per row, from the Record
 *          stage, through the ledger's emit half (`deps.emitRows`).
 *
 * ## Where it runs, and what it reads
 *
 * At the LOOP HEAD — ToolCalls' `loopTo` lands on it — so it runs right after
 * every batch and before the next model call, and before any window strategy
 * folds the batch away. It reads the batch ToolCalls just ran (`toolResults`,
 * which still holds it at the loop head: identities only, never a result's
 * bytes) and the periods those calls' results declared (their committed
 * `coverageDeclared` rows of the batch's iteration).
 *
 * ## Each batch once — told apart by its iteration, never by a call id
 *
 * The schema re-ask, the step nudge, the evidence recheck and the wrap-up run
 * no tool and loop back here with the batch still in place. The layer tells
 * the first visit from those by the iteration that DISPATCHED the batch,
 * which ToolCalls stamps beside it (`AgentState.toolResultsIteration`, under
 * the arm): ToolCalls advances the iteration by one and loops straight here,
 * and every other way back advances it again — so the batch is new exactly
 * when the loop head's iteration is the stamp plus one, and the mount hands
 * the batch only then (`honesty/mounts.ts` · `batchToJudge`). A
 * call id cannot say it: a provider's synthetic counter restarts with each
 * provider instance (a resumed leg repeats the ids of the leg that failed,
 * whose rows the conversation checkpoint carries), and nothing stops a
 * provider reusing an id across batches of one run. If that invariant ever
 * broke, a batch would be judged twice — an over-report, never a hidden one.
 * On the first iteration there is no batch, and every stage finds nothing to
 * do.
 *
 * ## One verdict per call
 *
 * A call gets a row when its result declared a period, or its tool declares a
 * `ToolPeriod` (the inputs layer's declaration: which argument sets the
 * period). The verdict is `coverage/period.ts` · `periodVerdict` over the
 * declared period — the LEAST held, when the result declared more than one
 * (`leastHeld`) — or `undeclared` when the tool declares a period argument and
 * this result said nothing about what its read covered: declared silence,
 * recorded as silence. The row names the `ToolPeriod`'s argument, the join
 * key to the inputs layer's row for the same call.
 */
import type { TypedScope } from 'footprintjs';
import { type DeclaredPeriod, type HeldSpan, type PeriodRow } from '../../../semantics/coverage/period.js';
import { type PeriodCheckInput, type PeriodTimeCheck } from '../../../time/check.js';
import type { PeriodFacts, PeriodForm } from '../../../time/convert.js';
/** One call of the batch ToolCalls just ran — identities only. */
export interface RanCall {
    readonly toolCallId: string;
    readonly toolName: string;
}
/** One period a call's result declared, read off its committed coverage row. */
export interface CallPeriod {
    readonly toolCallId: string;
    readonly period: DeclaredPeriod;
}
/** A call the layer will judge: the periods its result declared, and the argument its tool's `ToolPeriod` names. */
export interface PlannedPeriod {
    readonly toolCallId: string;
    readonly toolName: string;
    /** Every period the call's result declared — empty when it declared none. */
    readonly declared: readonly DeclaredPeriod[];
    /** The argument the tool's `ToolPeriod` names — absent when it declares none. */
    readonly argument?: string;
    /** Under `.time()` (step T8): what the time layer's result checks read besides the declared periods. */
    readonly time?: Omit<PeriodCheckInput, 'declared'>;
}
/** A judged call — the verdict and, under `.time()`, the time layer's checks that hold. */
export interface CheckedPeriod {
    readonly toolCallId: string;
    readonly toolName: string;
    readonly verdict: PeriodRow['verdict'];
    readonly argument?: string;
    readonly time?: PeriodTimeCheck;
    /** Under `.time()`: the source's held span, when it holds none or only part of the asked time. */
    readonly held?: HeldSpan;
}
/**
 * One call's time-layer record, handed by the mount under `.time()` only
 * (step T8): its `call-window` row's fields the check reads and its `call`
 * row's `drift` — read off the ledger, never recomputed.
 */
export interface CallTime {
    readonly toolCallId: string;
    readonly window?: PeriodCheckInput['window'];
    readonly drift?: PeriodCheckInput['drift'];
}
/** A tool's declared period facts, by tool name — the inputs layer's declaration, read (step T8). */
export type PeriodFactsOf = (toolName: string) => PeriodFacts | undefined;
/** A tool's declared period forms, by tool name — whether a call sent a look-back (§ 7.4, step T8). */
export type PeriodFormsOf = (toolName: string) => readonly PeriodForm[] | undefined;
/**
 * The argument a tool's `ToolPeriod` names, by tool name — read off the
 * implementation the shared dispatch resolver says answered the name
 * (`stages/toolResolver.ts`), so the layer judges the tool that ran. At the
 * loop head the tools slot has not recomposed yet, so the resolver still
 * answers for the epoch that dispatched the batch.
 */
export type PeriodArgumentOf = (toolName: string) => string | undefined;
/** The subflow's own state — inputs frozen by the mount, then one key per stage. */
export interface ResultsLayerState {
    /** The batch to judge — empty on a visit with none (the first iteration, or a re-entry). */
    readonly calls: readonly RanCall[];
    /** The periods the batch's results declared — handed only when there are some. */
    readonly periods?: readonly CallPeriod[];
    /** The iteration that dispatched the batch (`honesty/mounts.ts` · `batchToJudge`) — handed only with a batch. */
    readonly batchIteration?: number;
    /** The conversation turn — handed only with a batch. */
    readonly turnNumber?: number;
    /** Under `.time()` (step T8): the batch's calls' time rows — handed only when the turn has a clock. */
    readonly times?: readonly CallTime[];
    /** Under `.time()`: the turn's clock `now` — handed with `times`. */
    readonly now?: string;
    periodPlan?: readonly PlannedPeriod[];
    periodChecks?: readonly CheckedPeriod[];
    periodRows?: readonly PeriodRow[];
}
/** What the stages are handed from outside the folder — closures, never scope. */
export interface ResultsLayerDeps {
    readonly periodArgumentOf: PeriodArgumentOf;
    /** The tool's declared period facts (`retention`, `granularity`) — read only for a call with time rows. */
    readonly periodFactsOf?: PeriodFactsOf;
    /** The tool's declared period forms — read only for a call with time rows. */
    readonly periodFormsOf?: PeriodFormsOf;
    /** The ledger's emit half — one `findings.period` event per row. */
    readonly emitRows: (scope: TypedScope<ResultsLayerState>, rows: readonly PeriodRow[]) => void;
}
/**
 * DECLARE, pure: the calls to judge, in batch order — each call whose result
 * declared a period or whose tool declares a `ToolPeriod`. A call id met twice
 * in ONE batch is judged once, over every period declared under it (the least
 * held wins, so merging can only over-report).
 */
export declare function planPeriods(calls: readonly RanCall[], periods: readonly CallPeriod[], periodArgumentOf: PeriodArgumentOf, time?: {
    readonly times: readonly CallTime[];
    readonly now: string;
    readonly periodFactsOf?: PeriodFactsOf;
    readonly periodFormsOf?: PeriodFormsOf;
}): PlannedPeriod[];
/**
 * Under `.time()` (take 3): the held span of the declared period a `not-held` / `partly-held` verdict
 * came from — the first declared period whose own verdict is the call's —
 * or `undefined` for any other verdict. Fresh plain data.
 *
 * Here, in the results layer that files it, and not in `coverage/period.ts`:
 * this file loads through `import()` under the arm, so a plain agent never
 * carries it (the docs site's demo budget).
 *
 * @example
 * ```ts
 * heldSpanOf([{ queried: { from: '2026-09-30T13:00:00Z', to: '2026-09-30T18:59:50Z' },
 *               held: { from: '2026-10-01T16:22:44Z', to: '2026-10-01T17:02:44Z' } }], 'not-held');
 * // { queried: { from: '2026-09-30T13:00:00Z', … }, held: { from: '2026-10-01T16:22:44Z', … } }
 * ```
 */
export declare function heldSpanOf(declared: readonly DeclaredPeriod[], verdict: PeriodRow['verdict']): HeldSpan | undefined;
/**
 * VERIFY, pure: one verdict per planned call — the least held of its declared
 * periods, or `undeclared` when it declared none (its tool declares a
 * `ToolPeriod`, or it would not be planned).
 */
export declare function checkPeriods(plan: readonly PlannedPeriod[]): CheckedPeriod[];
/** RECORD, pure: one `period` row per judged call, stamped with the turn and the batch's iteration. */
export declare function periodRowsOf(checked: readonly CheckedPeriod[], stamp: {
    readonly turn: number;
    readonly iteration: number;
}): PeriodRow[];
/**
 * DECLARE — which calls of the batch just run are the layer's: a declared
 * period, or a tool that declares a `ToolPeriod`. Stages `periodPlan`
 * (identities, the declared periods, the argument name).
 */
export declare function declareResultsStage(scope: TypedScope<ResultsLayerState>, deps: ResultsLayerDeps): void;
/** VERIFY — the verdict on each planned call's period. Stages `periodChecks` (identities and a word). */
export declare function verifyResultsStage(scope: TypedScope<ResultsLayerState>): void;
/**
 * RECORD — one `period` row per judged call, stamped with the conversation
 * turn and the batch's iteration; one event per row, fired HERE (inside the
 * subflow). Stages `periodRows`; the mount's output mapping merges them into
 * the ledger in ONE write.
 */
export declare function recordResultsStage(scope: TypedScope<ResultsLayerState>, deps: ResultsLayerDeps): void;
/**
 * RESOLVE — FLAG, the one verb a result that has already run admits (the
 * layer contract's clause 4: an ask and an assumption need a call that has
 * not run yet, a refusal one that can still be stopped). The rows Record filed
 * ARE the flags: the answer's standing folds them, and the mount's output
 * mapping returns them. So in this version the stage decides nothing and
 * writes nothing — it is the seat the later reading checks and outcome rows
 * (honesty step 8) resolve in.
 */
export declare function resolveResultsStage(): void;
