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) • 4.37 kB
TypeScript
/**
* The lease machine — engagement advances one pass at a time, by evidence.
*
* Pattern: pure reducer. `advanceEngagement(plan, prior, pass)` returns the
* next state, the injection ids to suppress this pass, and the
* standing changes for the record. No I/O, no clock, no model.
* Role: the kernel's law. A TENTATIVE engagement (a regex or classifier
* guess) is renewed only by concrete evidence — the map's own tool
* called, the cursor routed by the system, the model asking by
* name. Without corroboration for `renewalGrace` consecutive
* passes it is PARKED: its cursor stays exactly where the map put
* it, and its prompt and tools simply stop riding the next calls.
* An engagement backed by explicit or structural evidence stands.
*
* Recovery is evidence too: any explicit or structural evidence while parked
* re-engages the map on the spot — the model's accepted `read_skill` pick is
* the recovery door, so parking is never a trap. That door is real as of
* 9.59.0: the reachability gate used to refuse a pick of the node the cursor
* already occupies, which for a single-member map (or any map parked where
* the model wants to return) made parking permanent for the rest of the turn.
* A pick is now routed by INTENT — of a PARKED map's member it is a
* RE-ENGAGEMENT, which changes engagement and not position.
*
* Measured grounding: in the recorded 30-call stuck turn (an entry regex
* matched a noun), the map's four tools were never called and 29 of 30 moves
* were "stay". Under grace 3 this reducer parks it on call four, saving the
* remaining ~26 calls from re-serving ~7k characters of the wrong map.
*/
import { type EngagementPass } from './evidence.js';
import type { EngagementChange, EngagementPlan, MapEngagement } from './types.js';
/** What one pass of the reducer hands back. */
export interface EngagementAdvance {
/** Next engagement state — write it back to scope under the alias key. */
readonly next: MapEngagement;
/** Injection ids whose contributions are suppressed THIS pass (parked maps' members). */
readonly parkedInjectionIds: readonly string[];
/**
* Tool NAMES held off the wire this pass — every tool contributed by a
* parked map's members (9.59.0).
*
* The engagement axis suppresses tools on its OWN authority, independently
* of `scopeTools`. The two are orthogonal and always were: `scopeTools`
* answers "do this map's tools follow the CURSOR?", parking answers "is this
* map talking at all?". Before this field, parking answered only the first
* half of its own promise — with `scopeTools` false (the default for flat
* graphs) a parked map's prompt stopped and all four of its
* tool schemas kept riding, so the wire actively contradicted the park.
*/
readonly parkedToolNames: readonly string[];
/** Standing changes this pass, for the typed events. Empty on a quiet pass. */
readonly changes: readonly EngagementChange[];
}
/**
* Advance every mounted map's engagement by one pass.
*
* Laws, in order:
* 1. A map first earns a record when its cursor lands on a member or a member
* activates; the founding strength is the winning clause's strength.
* 2. Renewal evidence resets `idle` and may UPGRADE the standing's strength
* (never downgrade — a guess later confirmed by the system stops decaying).
* An upgrade is a CHANGE: it emits, and `foundedBy`/`foundedAt` keep the
* cause the engagement actually started on.
* 3. A tentative engagement with no evidence counts one idle pass when ALL
* THREE clauses hold: its contribution was served last pass, none of its
* tools was called, and the model called something else instead. At
* `renewalGrace` it parks. A pass with no tool calls at all counts nothing
* (the model was thinking, not ignoring), and neither does a pass where
* the map's contribution never reached the wire (it cannot be ignored if
* it was not there).
* 4. `nonParkable` maps never park, whatever the count.
* 5. Explicit or structural evidence re-engages a parked map immediately.
*/
export declare function advanceEngagement(plan: EngagementPlan, prior: MapEngagement | undefined, pass: EngagementPass): EngagementAdvance;