agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
59 lines (58 loc) • 3.36 kB
TypeScript
/**
* reasons — the closed table of why an answer does not stand.
*
* Pattern: one frozen table, the ONE owner of each reason's layer, class and
* the committed row it is read from. `assess.ts` fires reasons in
* this table's order; a reader renders them from it.
* Role: core/ layer leaf, pure data.
*
* THE CLASS. `ask` is a reason the person can settle by answering a question
* the run already put to them — the turn ENDED in a pause waiting on a
* person's reply (a typed input, a question, a consent gate). Every other
* reason is `not-sure`: the library cannot ask at the answer (the call that
* could have used an answer has already run, and the library never replaces
* the model's reply with a question), so an absence renders "not sure — what
* was searched", never "ask".
*
* THE SOURCE. What each reason rests on is declared here too, once: `calls`
* when its rows are about specific tool calls (a result, a coverage row, an
* argument or period row, a conflict between readings); `answer` when its row
* is a verdict on the answer itself (a value no result carried, a claim in it,
* the app's checks on its bytes); `run` when it is about how the run went (a
* pause still waiting, a limit, unfinished steps, a check that could not reach
* a verdict). The fold never decides it per run, so "the run" is never an
* empty list of calls in disguise.
*
* WHAT IS NOT HERE, AND WHY. A reason is read from a COMMITTED row, never from
* an event, so the running agent and a later reader fold the same bytes. Two
* verdicts the honesty design names are events only in this version and so
* cannot be read yet: the `.claims()` dispositions (`claim-contradicted`, and
* the `checked-pass` rows that would SUPPORT "known"), and the integrity
* dispositions (`integrity.disposition`). The step that needs each one adds
* one committed row, and the reason joins this table in the same change — as
* the answer layer (honesty layer 4) did for two: the evidence gate's clean
* pass (a `grounded` witness row, read as the names-and-numbers check having
* run — never as a reason, never as support) and an answer given before its
* declared steps finished (`steps-unfinished`, below). Both rows are filed only
* while the answer layer is armed (`assessment/witness.ts`).
*/
import type { AssessmentReason, AssessmentReasonSource, HonestyLayer } from './types.js';
export interface ReasonEntry {
readonly reason: AssessmentReason;
/** Absent: the reason belongs to every layer. */
readonly layer?: HonestyLayer;
readonly class: 'ask' | 'not-sure';
/**
* What the reason rests on, DECLARED here once — never inferred per run
* (`types.ts` · `AssessmentReasonSource`): `calls` (the calls its rows name,
* read by `sources.ts` · `reasonSourceOf`), `answer` (the answer itself) or
* `run` (the run as a whole).
*/
readonly source: AssessmentReasonSource['kind'];
/** The committed row it is read from — for the README table and a reviewer, never parsed. */
readonly reads: string;
}
/** Every reason, in the order the fold reports them: the ask first, then by layer. */
export declare const REASONS: readonly ReasonEntry[];
/** The table entry for one reason. */
export declare function reasonEntry(reason: AssessmentReason): ReasonEntry;