agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
84 lines • 4.85 kB
TypeScript
/**
* skillVocabulary — what a skill PRODUCES and CONSUMES, as data (9.25.0).
*
* Two programs meet here. The claim-check store gave artifacts a consumer
* vocabulary — `kind` (`'dataset/rows'`, `'chart/spec'`), declared by the
* producer and exact-matched by every consumer. The skill graph gave a run a
* declared shape — which skill holds the tenure, in what order, running which
* steps. Neither could see the other: a skill whose whole job was to turn a
* dataset into a chart said so only in prose, so nothing could check that
* anything on the agent ever MAKES a dataset.
*
* defineSkill({ id: 'charting', …,
* consumes: ['dataset/rows'], // what it needs to arrive
* produces: ['chart/spec'], // what it leaves behind
* steps: [{ tool: 'fetch', note: '…', produces: ['dataset/rows'] },
* { tool: 'render', note: '…', consumes: ['dataset/rows'] }] })
*
* Vocabularies are DECLARATIONS, not machinery: nothing at run time reads
* them, nothing is enforced at dispatch (that is `wants`' job, and it happens
* against the real store), and a skill that declares none is byte-identical to
* one that never heard of them. What they buy is (1) a build-time check that
* a consumed kind has a producer somewhere, and (2) a fact on the skill's
* metadata that a lens can draw — the data legs of a run, before the run.
*
* ── The satisfiability rule, and exactly what it can see ────────────────────
* A consumed kind `K` at a consumer `C` is SATISFIED when any of these holds:
*
* 1. **A wants-declaring tool in scope names `K`.** For a skill: any of its
* own tools. For a step: the tool that step runs. This is the honest
* escape hatch — `wants` is redeemed at dispatch against the live store,
* and the ref the model speaks may have been minted by another agent, an
* earlier turn, or a job that ran last night. A declaration backed by a
* real redemption path is never called unsatisfied.
* 2. **Something on this agent declares `produces: K`** — any skill, or any
* step of any skill, including `C` itself.
* 3. (steps only) **An earlier step of the same skill produces `K`**, or
* **the skill's own `consumes` names `K`** — it arrived from outside, and
* the skill's contract says so.
*
* Otherwise: `artifact-kind-unsatisfied`, a WARNING.
*
* **The boundary, stated because a check that overclaims is worse than none.**
* This does NOT reason about route order. A producer declared anywhere on the
* agent silences the check, even if no declared route reaches the consumer
* from it — because `read_skill` can put the cursor on any open skill, and the
* artifact store OUTLIVES the turn. The only thing this proves is the strong
* one: *nothing on this agent claims to make what this consumer claims to
* need.* Cross-agent and cross-run flows through the store are invisible to
* it, and so is any tool that mints an artifact without a `produces`
* declaration — which is why the warning says so in its own message and why
* it is never an error.
*/
import type { GraphProblem } from './skillGraphCheckup.js';
import type { Injection } from './types.js';
/** The two vocabularies a skill or a step may declare. */
export interface ArtifactVocabulary {
/** Artifact KINDS this leaves behind for something later to redeem. */
readonly produces?: readonly string[];
/** Artifact KINDS this needs to have arrived. */
readonly consumes?: readonly string[];
}
/**
* Validate one declaration at its authoring point. Every refusal happens
* where both halves are in hand — the `validateSkillSteps` law, applied to
* the other declaration on the same options bag.
*
* @param where the refusal's first words, e.g. `defineSkill(billing)`.
* @param what which field is being checked, for the message.
*/
export declare function assertArtifactVocabulary(where: string, what: 'produces' | 'consumes', kinds: readonly string[] | undefined): void;
/** Read a skill injection's declared vocabularies off its metadata bag (the
* `steps` precedent — the engine ignores unknown keys). `undefined` when the
* skill declared none, so a caller can skip the whole feature. */
export declare function vocabularyOf(injection: Injection): ArtifactVocabulary | undefined;
/**
* Check every declared vocabulary on a set of skills. Pure + side-effect-free,
* and returns `[]` immediately when nothing declares a vocabulary (the
* zero-cost gate — an agent that never heard of this feature pays one
* `Array.some`).
*
* @param skills every skill injection the agent will carry.
*/
export declare function checkArtifactVocabularies(skills: readonly Injection[]): GraphProblem[];
//# sourceMappingURL=skillVocabulary.d.ts.map