agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
106 lines (105 loc) • 5.53 kB
TypeScript
/**
* overclaim — the rule pack that checks a declaration like a claim: a refusal
* or an absence never asserts more than was read.
*
* Pattern: a pure rule pack (the `tool-lint/rules.ts` shape), asked by the
* `check:semantics` gate (`check.ts`). No IO, no model.
* Role: lib/ layer (L1), pure. Reads the recognizers this folder owns.
* Emits: N/A.
*
* ## The finding it answers
*
* A registered study (two models) found that a tool's refusal text that said
* more than its check — "No array matches 'X'. Known arrays: … a wrong
* identifier, not missing data" — made replies WORSE: models told users "X is
* not in your estate" when the tool had only failed to find X in one
* inventory export. A refused call read nothing; an absence read what its
* `checked` names. Neither may say what does not exist, or that the input is
* wrong.
*
* ## The rules
*
* • `refusal-asserts-absence` — a not-read result (a refusal a tool throws
* or returns; an effects envelope whose status is `invalid`, `denied` or
* `failure`) carries an absence (`af_absent`), or a sentence about what
* was looked up from {@link NON_EXISTENCE} or {@link WRONGNESS}.
* • `absence-asserts-wrongness` — an item's `what`/`why`, `try_instead`,
* the typed tool's `why`, or an extra key's text has a sentence about
* what was looked up that calls it wrong ({@link WRONGNESS}).
* • `authoritative-names` — every `among.authoritative` use, listed for
* review: it removes the gap "names outside <source>".
*
* A sentence is ABOUT what was looked up when it names the looked-up argument
* or its value (`LookupSubject` — a described refusal sample's, or an
* absence's `looked_for` and facet argument; with neither, a quoted span
* stands for the value). A format, range, permission or transport message
* exempts a WRONGNESS phrase only; a NON-EXISTENCE phrase about the lookup
* always fires.
*
* ## The phrase packs — closed, versioned, small
*
* Two fixed lists of English phrases, matched after NFC, case folding and
* curly-apostrophe folding. They are a gate's net, not a grammar: a phrasing
* they miss is a missed finding, never a pass. The fuller detection grammar
* (clauses, negation scope, languages) belongs to the delivery check, a later
* piece; it may reuse these lists. {@link OVERCLAIM_PHRASES_VERSION} changes
* whenever a list does.
*/
import type { ToolAbsence } from './coverage/types.js';
/** Bumped whenever {@link NON_EXISTENCE} or {@link WRONGNESS} changes. */
export declare const OVERCLAIM_PHRASES_VERSION = 1;
/** The opt-in rule sets `check:semantics` takes (`rules: ['overclaim']`). */
export type SemanticsRuleSet = 'overclaim';
/** The closed list of rule sets, as data. */
export declare const SEMANTICS_RULE_SETS: readonly SemanticsRuleSet[];
/** The codes this pack files. */
export type OverclaimCode = 'refusal-asserts-absence' | 'absence-asserts-wrongness' | 'authoritative-names';
/** One finding of this pack, before the gate stamps tool, severity and index. */
export interface OverclaimIssue {
readonly code: OverclaimCode;
/** The field, dot-pathed from the value judged (`try_instead`, `checked[0].authoritative`). */
readonly field: string;
/** What is wrong and the fix — without the tool name; the gate adds it. */
readonly message: string;
}
/** The first non-existence phrase in `text`, or `undefined`. */
export declare function nonExistencePhrase(text: string): string | undefined;
/** The first phrase in `text` that calls the input wrong, or `undefined`. */
export declare function wrongnessPhrase(text: string): string | undefined;
/**
* What a refusal or an absence is ABOUT: the looked-up argument's name and
* the value asked for. A rule fires only on a sentence that names one of them
* — "PS-ARRAY-99 is the wrong identifier" is a claim about the thing looked
* up; "start_date is not a valid ISO-8601 date" is about another argument.
*/
export interface LookupSubject {
readonly argument?: string;
readonly value?: string;
}
/** True when a sentence is a format, range, permission or transport message. */
export declare function isExemptMessage(sentence: string): boolean;
/**
* True when `value` is a result that READ NOTHING by its own declaration — an
* effects envelope whose `status` is `invalid`, `denied` or `failure`.
*/
export declare function isNotReadResult(value: unknown): boolean;
/**
* `refusal-asserts-absence` over one refusal — the text a tool throws, the
* value it returns when it refuses, or a described sample
* `{ text, argument?, value? }`. A refused call read nothing, so it may carry
* no absence, and no sentence ABOUT what was looked up that says it does not
* exist or that the input is wrong. A sentence about another argument, or a
* format, range, permission or transport message, is not that claim.
*/
export declare function refusalIssues(value: unknown, field: string): OverclaimIssue[];
/**
* `absence-asserts-wrongness` and `authoritative-names` over one absence. An
* absence says what was searched; it never calls the input wrong — a name
* missing from one list may exist elsewhere.
*/
export declare function absenceIssues(absence: ToolAbsence): OverclaimIssue[];
/**
* The absences a sample result carries — a bare one, or one a `coverage()`
* ledger bounds, to any depth: the shapes the dispatch door recognizes.
*/
export declare function absencesIn(value: unknown): ToolAbsence[];