/**
 * runbook/verdicts — the OPTIONAL verdict/rowset projection.
 *
 * Pattern: pure selection + rendering over the run's final state, plus one
 *          tiny recorder that harvests decide() evidence for generated
 *          meanings. Selected by `resultKind: 'verdict/*'`; a runbook of any
 *          other kind never sees this module.
 * Role:    core/runbook.
 * Emits:   N/A.
 *
 * THE ONE-NUMBER LAW: the rendered table and the structured `verdicts` list
 * show the SAME rows under the SAME cap. A rendered table beside a longer
 * structured list is an invitation that gets accepted — rows come back
 * retyped with subtly wrong identifiers.
 *
 * TWO SURFACES, TWO LAWS: a rowset does not always reach its reader through
 * the model's prose. Where it does, the table ships pre-rendered and the model
 * is told to output it verbatim (`VERDICT_RENDER_NOTE`); where the HOST draws
 * the rowset itself, no table ships and the model is told the opposite
 * (`PANEL_RENDER_NOTE`). The bridge cannot tell which client it is in, so the
 * caller says — `presentation` on the options bag.
 *
 * GENERATED MEANINGS, never hand-restated: `verdict_meanings` is composed
 * from (a) the named decider's declared branches in the chart's own structure
 * (branch description, falling back to branch name), overlaid by (b) the rule
 * LABELS this run's decide() evidence carried — the rule speaking for itself —
 * and (c) the DEFAULT branch's declared label, carried by the same evidence.
 * A decider inside a dynamically generated fan-out branch is invisible to (a)
 * by construction (the branch chart does not exist at build time); (b) still
 * covers every verdict an executed rule produced.
 *
 * (c) exists because the default branch is chosen by NO rule — it fires
 * exactly when every rule failed, so it appears in no `rules[]` entry and (b)
 * can never name it. In a generated fan-out branch, where (a) is blind too, it
 * was the one verdict the rowset could show and the meanings map could not
 * explain. `decide(scope, rules, { branch, label })` (footprintjs ≥ 9.16.1) puts
 * that label on the decision evidence, so it arrives here the way every other
 * label does: harvested from the run, never declared at this boundary. There is
 * deliberately no caller-supplied meanings map — a map a caller can write is a
 * map that can describe rules that never ran.
 */
import type { CombinedRecorder } from 'footprintjs';
import type { FlowChart } from 'footprintjs';
import type { VerdictRow } from './types.js';
/** Default cap on `verdicts` rows and the rendered table. */
export declare const DEFAULT_MAX_ROWS = 50;
/** The render law when PROSE is the rowset's only surface (`presentation:
 *  'prose'`, the default) — stated to the model beside the table. */
export declare const VERDICT_RENDER_NOTE: string;
/**
 * The render law when the HOST renders the rowset (`presentation: 'panel'`) —
 * stated to the model INSTEAD of a table, because there is none to ship.
 *
 * Same failure, opposite instruction. A rowset the reader can already see does
 * not need retyping into prose; retyping it is how an identifier arrives
 * subtly wrong beside a correct one on screen.
 */
export declare const PANEL_RENDER_NOTE: string;
/** The reserved verdict word for "no classification was reached" — rows
 *  carrying it are counted into the coverage ledger as not-checked ground
 *  (the three-outcome honesty: reached, reached-and-clear, DECLINED). */
export declare const DECLINED_VERDICT = "declined";
/** Read the rowset off the final state's `verdicts` key — an array of bags
 *  each carrying a string `verdict`. Anything else reads as "no rowset". */
export declare function verdictRowsOf(state: Readonly<Record<string, unknown>>): VerdictRow[];
/**
 * Render the shown rows as one markdown table. Columns are the FIRST row's
 * own keys in declaration order — the chart writes its rows, so the chart
 * owns the column vocabulary; the bridge only renders it.
 */
export declare function renderVerdictTable(rows: readonly VerdictRow[]): string;
/** The two spellings of the configured decider, once the static walk has
 *  (maybe) resolved it — flow events report the decider by name. */
export interface DeciderIdentity {
    readonly spellings: ReadonlySet<string>;
    /** branch → declared meaning, from the chart's own structure. */
    readonly declared: ReadonlyMap<string, string>;
}
/**
 * Find the named decider in the chart's static structure (root graph plus
 * statically declared subflows) and read its branches. Loop-ref stubs are
 * skipped FIRST — they deliberately violate node-id uniqueness.
 */
export declare function resolveDecider(chart: FlowChart, decider: string): DeciderIdentity;
/** The evidence harvest: rule labels observed in this run, branch → label. */
export interface MeaningsHarvest {
    readonly recorder: CombinedRecorder;
    readonly observed: ReadonlyMap<string, string>;
}
/**
 * A tiny flow recorder capturing the named decider's decide() evidence as it
 * fires — collected DURING the traversal, never reconstructed after. Rule
 * labels are harvested for every rule the evidence lists (matched or not):
 * a rule that was evaluated has spoken its label, whichever branch won. The
 * DEFAULT branch's label rides the same evidence and is harvested with them.
 *
 * A decider inside a subflow (including a generated fan-out branch) reports
 * itself PATH-PREFIXED (`per-subject~0/Protection posture`), so the match is
 * on the LAST `/`-segment — the same last-delimiter reading every upstream
 * parser of these paths uses, which is what keeps the generated-branch
 * marker opaque here.
 */
export declare function meaningsRecorder(identity: DeciderIdentity): MeaningsHarvest;
/** Compose the final meanings: declared branches first, the labels this run
 *  observed (rule labels, and the default branch's own) winning where both
 *  speak — the declaration made beside the rules is the sharper sentence.
 *  Undefined when neither source produced anything — absent, never `{}`. */
export declare function composeMeanings(identity: DeciderIdentity, observed: ReadonlyMap<string, string>): Record<string, string> | undefined;
