agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
70 lines (69 loc) • 3.58 kB
TypeScript
/**
* runbook/coverage — the spine's ledger: inner folds + chart-declared
* entries + the bridge's own, and the sentence naming the rules.
*
* Pattern: pure fold over three sources, reusing the coverage primitives'
* own recognizer and merge — no second grammar.
* Role: core/runbook.
* Emits: N/A.
*
* The three sources, in the order they land:
* 1. INNER LEDGERS — every recorded inner call's result is read by the
* same `readCoverageResult` funnel the dispatch loop uses, and its
* three lists fold upward. An inner tool's honesty is carried, never
* re-authored.
* 2. THE CHART'S OWN — the procedure states run-specific coverage by
* writing a `coverage` state key (`{ checked?, not_checked?,
* cannot_cover? }`, items as `{what, why?}` bags or bare strings).
* This is the app's vocabulary (which counters mean "not assessed" is
* the chart's to know); the ENVELOPE is the bridge's.
* 3. THE BRIDGE'S OWN — one `checked` entry naming the procedure, its
* recorded step count and the rule set it ran under; and, for a
* verdict-shaped runbook, a `not_checked` entry counting DECLINED rows
* (the three-outcome honesty: a row that reached no classification is
* ground the answer does not cover).
*/
import type { CoverageItem } from '../../semantics/coverage/types.js';
import type { InnerCallRecord } from './dispatch.js';
import type { RunbookRules } from './types.js';
/** The three lists, mid-fold. */
export interface LedgerLists {
readonly checked: readonly CoverageItem[];
readonly notChecked: readonly CoverageItem[];
readonly cannotCover: readonly CoverageItem[];
}
/** Fold every recorded inner call's declared coverage upward. */
export declare function foldInnerCoverage(records: readonly InnerCallRecord[]): LedgerLists;
/** The chart-declared lists, read off the final state's `coverage` key.
* Accepts both spellings of the two-word keys (state is often snake_case,
* the declaration camelCase) — one reader, no drift. */
export declare function chartCoverageOf(state: Readonly<Record<string, unknown>>): LedgerLists;
/** What the composed ledger needs to know about this run. */
export interface LedgerFacts {
readonly chartName: string;
readonly stepsExecuted: number;
readonly rules?: RunbookRules;
/** Rowset facts — present only for a verdict-shaped runbook. */
readonly rowsTotal?: number;
readonly declinedRows?: number;
}
/** The composed `af_coverage` value: three merged lists + the static law
* note + this run's own sentence. */
export interface ComposedLedger {
readonly checked?: readonly CoverageItem[];
readonly not_checked?: readonly CoverageItem[];
readonly cannot_cover?: readonly CoverageItem[];
readonly note: string;
readonly sentence: string;
}
/** Compose the whole ledger. Inner folds land first, chart-declared second,
* the bridge's own last — provenance order, so a reader meets the sources
* before the summary. */
export declare function composeLedger(inner: LedgerLists, chart: LedgerLists, facts: LedgerFacts): ComposedLedger;
/**
* The carried provenance stamp: the FIRST inner result that declared an
* `af_provenance` (on its unwrapped payload, or at its top level — both are
* read, in that order). A derived answer is still an answer, and a source's
* confession (`source: 'LOCAL SEED'`) must survive composition.
*/
export declare function carriedProvenanceOf(records: readonly InnerCallRecord[]): Record<string, unknown> | undefined;