agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
74 lines (73 loc) • 3.64 kB
TypeScript
/**
* among — a name that resolves to nothing is a named miss over the names the
* tool read, never "it does not exist".
*
* Pattern: one rule set, two doors — `absent()` mints by it
* ({@link mintAmong}), and readers find the names facet by it
* ({@link namesFacetOf}).
* Role: core/ layer (L1), pure.
* Emits: N/A.
*
* ## The failure this file answers
*
* A lookup checked a name against an inventory export, found nothing, and
* refused with "No array matches 'X'. Known arrays: … a wrong identifier, not
* missing data". Models then told users "X is not in your estate" — when the
* tool had only failed to find X in ONE export. A pre-check over a known list
* IS a search, and a declaration is itself a claim. So the miss is an absence
* over the names actually read, and the mint ADDS a gap the author cannot
* remove: `{ kind: 'scope', what: 'names outside <source>', relevance:
* 'bears', bears: 'source' }`. The only opt-out is `authoritative: { why }`,
* and `check:semantics` lists every use of it. A read that did not see the
* whole list (`partial: true` — a truncated or paged inventory) checked even
* less, so it ALSO gets a completeness gap, `{ kind: 'scope', what: 'not every
* name in <source> was read', relevance: 'bears', bears: 'completeness' }`,
* which `authoritative` never removes.
*
* The gap holds only where `among` is declared: a plain `absent({ what })`, or
* a refusal the tool throws, never passes through here. `count`,
* `authoritative.why` and `partial` are the TOOL's claims, said out loud and
* not verified by this library.
*
* ## The names themselves are not served
*
* `among.names` is read for one thing: that `count` agrees with it
* (`names-count-mismatch`). No name reaches the model, an event or a record
* beyond what the absence already carries. Two reviews found that a short
* list of "nearest" names acts as an inventory listing rather than a "did you
* mean?", invites an answer about a different name, and carries whatever
* text the inventory holds — and the study's harmful refusal listed names
* too. Serving names waits on a bench arm that measures count-only against a
* near-match "did you mean?".
*/
import type { CompletenessGapItem, NamesFacetItem, SourceGapItem, ToolAbsence } from './types.js';
/** The code a count that disagrees with its names is refused under. */
export declare const NAMES_COUNT_MISMATCH = "names-count-mismatch";
/** What the mint composes from one `among`, for `absent()` to place. */
export interface MintedAmong {
/** The first `checked` item. */
readonly facet: NamesFacetItem;
/**
* The first `not_checked` items, in order: the source gap (unless
* `authoritative`), then the completeness gap (when `partial`). Empty only
* for an authoritative whole read.
*/
readonly gaps: readonly (SourceGapItem | CompletenessGapItem)[];
/** The absence's provenance, in the declaration's camelCase form. */
readonly provenance: {
readonly measuredAt: string;
readonly source: string;
};
}
/**
* Mint one `among` declaration, refusing (throwing, where `absent()` is
* called) anything it cannot honour. Nothing of the looked-for value is
* written into what it composes.
*/
export declare function mintAmong(raw: unknown): MintedAmong;
/**
* The names facet of an absence minted with `among` — its `checked` item with
* `facet: 'names'` — or `undefined`. An envelope minted elsewhere is read as
* found, never repaired.
*/
export declare function namesFacetOf(absence: ToolAbsence): NamesFacetItem | undefined;