UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

76 lines (75 loc) • 4.44 kB
/** * The agent's own answer checks as rows of an answer-validation report * (`AnswerValidationOptions.agentChecks`). * * Pattern: pure adapters, one verdict in, `AnswerCheck` rows out. * Role: the one place the library's own checks speak the report's * vocabulary. `claimChecksOf` judges the candidate this validation * delivers through the claim seam's own selection * (`integrity/unsupported-claim/check.ts` · `compareClaim`) and its * delivery verdict (`integrity/unsupported-claim/delivered.ts` · * `judgeDeliveredClaim`), so a row can never accuse where the * detector does not. `evidenceCheckOf` reads the evidence gate's * verdict on that same candidate — asked of it through an * `EvidenceJudge`, never the verdict on the model's draft, which an * output transform may have changed. * * One law above all, from the standing fold (`core/agent/assessment/assess.ts`): * an agent row can WITHHOLD an answer and never VERIFY one. No row here is * ever `checked-pass` (`validate.ts` refuses one), so only the app's own * checks can make a report `passed`, which the fold reads as "known": * - The gate's clean verdict is a membership pass: `not-applicable`. * - A claim that agrees with the settled fact is `not-applicable` too. The * contract is unscoped — rows for `(entity, field)` from any tool, with no * scope or age check — so agreement verifies nothing. A contradiction * still fails the row. * - A reading can only withhold (`delivered.ts`): with no reading the claim * is not checked (`not-applicable`), and one more reading never makes the * row more permissive, so a forged or stale row can at most withhold. * - Doubt is never support. A field the answer leaves out, or declines * (`null` / `'unknown'`), is `not-applicable`. A value beside a reading * that settled nothing, doubt on both sides, a fact the run read two * ways, and anything not well formed are `unreachable`: enforce * withholds, observe delivers "not sure". * * And one from the redaction law: a row carries counts and the FIELD names the * app declared (the answer field, the fact's field), never a value from the * answer or from a tool result — and never the contract's `entity`, which an * app may build per user. `answerValidation` is not a name the redaction * vocabulary keeps out; the values stay on the records a policy already names * (`unsupportedValues`, `claimFacts`, the `integrity.context_error` event). */ import { type ClaimLedgerRow, type DeclaredClaim } from '../integrity/unsupported-claim/check.js'; import type { AnswerCheck } from './types.js'; /** Every agent row's id starts with this; a host check id may not while rows are on. */ export declare const AGENT_CHECK_PREFIX = "agent:"; /** The evidence gate's verdict on the delivered candidate: counts and flags only. */ export interface EvidenceCheckInput { /** Values the gate looked up in the tool results (exempt values excluded). */ readonly lookedUp: number; /** Values no tool result this run read carried. */ readonly unsupported: number; /** The evidence index hit its ceiling: an unfound value may sit past the cut. */ readonly truncated: boolean; /** The answer's words and numbers past the gate's reading ceiling, never looked up. */ readonly unread: number; /** The gate's one repair turn ran before this verdict. */ readonly revised: boolean; } /** * The evidence gate bound to the evidence a run read: judges ONE text, the * canonical candidate a validation is about to deliver. */ export type EvidenceJudge = (text: string) => EvidenceCheckInput; /** * The `'names-and-numbers'` row. `undefined` (the gate never ran on the * run's final answer, so no judge was filed) is `unreachable`: a listed check * that did not run never reads as clean. */ export declare function evidenceCheckOf(verdict: EvidenceCheckInput | undefined): AnswerCheck; /** * The `'claims'` rows: one per declared claim, in declaration order, judged * on `candidate` against this run's ledger rows for each declared fact. * Throws what the claim comparison throws (a ledger value JSON cannot render). */ export declare function claimChecksOf(declared: readonly DeclaredClaim[], ledger: readonly ClaimLedgerRow[], candidate: unknown, epoch: number): AnswerCheck[];