agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
132 lines (131 loc) • 7.08 kB
TypeScript
/**
* policy — the shape check and the union of footprintjs `RedactionPolicy`
* values. Nothing here decides what is secret: footprintjs's `RedactionRule`
* is the one owner of that (`footprintjs/advanced` · `RedactionRule`). This
* file only answers two questions about a policy as DATA:
*
* 1. Is it a policy footprintjs can apply, or a typo that would be dropped
* in silence? (`assertRedactionPolicy`)
* 2. When one run is covered by several declared policies — an agent's own,
* the members of a composition, the caller that handed one down through a
* tool — what is the ONE policy that run applies? (`unionRedactionPolicies`)
*
* The union only ever ADDS names. A run that more than one declaration covers
* masks everything any of them names; no declaration can take away a name
* another one gave. Over-masking is the safe direction, and it is the only
* direction a union can move.
*/
import type { RedactionMarks, RedactionPolicy } from 'footprintjs';
/**
* Refuse a value that is not a policy footprintjs can apply — by name, at the
* place it was declared, before any run.
*
* Refused: a non-object; an unknown field (`key:` for `keys:` would otherwise
* be ignored and the run would mask nothing); a `keys` entry that is not a
* non-empty string; a `patterns` / `emitPatterns` entry that is not a RegExp;
* a FROZEN global or sticky RegExp (footprintjs resets `lastIndex` before each
* test and cannot on a frozen one, so it would throw mid-run, at the first
* event); a `fields` map whose values are not lists of non-empty strings; and a
* policy that names nothing at all — a door set to "redact nothing" reads like
* protection and is none.
*
* @param site where it was declared, for the message (`Agent.create`, …)
*/
export declare function assertRedactionPolicy(policy: unknown, site: string): asserts policy is RedactionPolicy;
/**
* The one policy for a run covered by several declarations: every name any of
* them selects. `undefined` when none is present. A single distinct policy is
* returned AS IT IS (the same object), so a run covered by one declaration
* hands footprintjs exactly the object that was declared.
*/
export declare function unionRedactionPolicies(...policies: readonly (RedactionPolicy | undefined)[]): RedactionPolicy | undefined;
/**
* The policy a paused run's MARKS stand for: the names its rule kept out of
* every record — a key a policy selected when it was written, a per-call mark,
* a mapper's taint — carried by the pause's checkpoint
* (`FlowchartCheckpoint.redactionMarks`, names only). A resumed leg is covered
* by them (`RunnerBase · emitPauseResume`), so a value its first leg kept out
* stays out of the second leg's records even when the per-run `redact` that
* selected it is not passed again. `undefined` when the checkpoint carries none.
*/
export declare function policyOfMarks(marks: RedactionMarks | undefined): RedactionPolicy | undefined;
/** A RegExp as plain data. */
interface CarriedPattern {
readonly source: string;
readonly flags: string;
}
/** A policy's selectors as plain data (`keys`, `patterns`, `fields`). */
interface CarriedSelectors {
readonly keys?: readonly string[];
readonly patterns?: readonly CarriedPattern[];
readonly fields?: Readonly<Record<string, readonly string[]>>;
}
/**
* A redaction policy as plain data — names, and each pattern as a REFERENCE
* (its source and flags) to a RegExp the reading side must already hold — so
* the policy a caller handed ONE run
* (`agent.run(input, { redact })`) can ride that run's state into its pause
* checkpoint and cover the resumed leg (`Agent · resume`), wherever and
* whenever it resumes. Written by the seed stage (`AgentState.runRedaction`).
*/
export interface CarriedRedactionPolicy extends CarriedSelectors {
readonly emitPatterns?: readonly CarriedPattern[];
readonly diagnostics?: CarriedSelectors;
/**
* The conversation vocabulary's version the policy was built under, when it
* keeps the conversation out (`conversation.ts` · `carriedRunPolicy`) — a
* resumed leg under another version is covered by the current list too.
*/
readonly vocabulary?: string;
}
/**
* The vocabulary version a carried policy recorded ({@link CarriedRedactionPolicy}),
* or `undefined` when it recorded none. Read only after
* {@link policyFromCarried} accepted the same value — which refuses one whose
* version is not text.
*/
export declare function carriedVocabularyOf(value: unknown): string | undefined;
/** `policy` as plain data ({@link CarriedRedactionPolicy}). */
export declare function carriedRedactionPolicy(policy: RedactionPolicy): CarriedRedactionPolicy;
/** Why a carried policy cannot cover a resumed leg ({@link CarriedPolicyError}). */
export type CarriedPolicyRefusal = 'unreadable' | 'unknown-pattern';
/**
* Thrown by {@link policyFromCarried}: the checkpoint's policy is not one this
* library wrote (`'unreadable'`), or it names a pattern the resuming side does
* not hold (`'unknown-pattern'`). The message names no policy, pattern or value.
*/
export declare class CarriedPolicyError extends Error {
readonly refusal: CarriedPolicyRefusal;
constructor(refusal: CarriedPolicyRefusal, site: string);
}
/**
* The policy a checkpoint carried ({@link carriedRedactionPolicy}), rebuilt and
* checked like any declared one. `undefined` when it carries none. A value
* that is not one this library wrote is REFUSED: a resumed leg whose records
* its policy could not keep covered must not start.
*
* A PATTERN IS NEVER COMPILED FROM A CHECKPOINT. A checkpoint is data that can
* come back from storage someone else controls, and a pattern compiled from it
* could be one built to hang the matcher. A carried pattern is a REFERENCE —
* its source and flags — to a RegExp the resuming side already holds: one of
* `trusted` (the agent's declared policy, the policy the resume names, the
* library's own vocabulary), matched exactly and handed back as THAT object. A
* reference to one it does not hold is refused (`'unknown-pattern'`). Keys and
* fields are names, matched exactly, and carried as they are.
*
* @param site where it is read, for the message (`Agent.resume`)
* @param trusted the policies whose patterns a carried reference may name
* @throws CarriedPolicyError
*/
export declare function policyFromCarried(value: unknown, site: string, trusted: readonly (RedactionPolicy | undefined)[]): RedactionPolicy | undefined;
/**
* Whether `policy` names anything at all — a key, a pattern, a field, an
* event name or a diagnostic selector. Every policy the library accepts does
* (`assertRedactionPolicy`); a run covered by one serves EVERY event by the
* value-kind rule (`served.ts`), even when footprintjs's rule has no name to
* select in it (a policy of event names or diagnostic selectors only).
*
* @internal
*/
export declare function namesAnything(policy: RedactionPolicy | undefined): boolean;
export {};