UNPKG

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
/** * 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;