agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
136 lines • 6.25 kB
JavaScript
/**
* The disposition ledger — nobody's silence goes uncounted.
*
* Pattern: small mutable accumulator behind a read-only report, the
* context-ledger ingestion shape (accumulate during, read after).
* Role: every Context Integrity check files one disposition per
* encounter here. The ledger's two jobs:
*
* 1. THE INVARIANT — for every check that was registered, an encounter
* count of zero is itself reportable. `assertAlive()` fails when a
* registered check saw work available and filed nothing at all —
* which is the wiring-rot failure mode ("the checker was unhooked and
* the suite stayed green"), distinct from a clean run (encounters
* with zero findings — healthy) and from a quiet run (no applicable
* work — also healthy, and stated as such).
*
* 2. THE CANARY — in dev posture, a run mints one deliberately
* contradictory synthetic encounter per registered check at start.
* A checker that cannot catch its own canary is dead, and the run
* says so by name instead of shipping a green report. Synthetic
* findings are counted apart and never touch the real numbers.
*
* Everything here is plain data; `report()` returns fresh POJOs safe for
* events, snapshots, and recordings.
*/
/** Thrown by `assertAlive()` when a registered check demonstrably never ran. */
export class CheckerDeadError extends Error {
check;
seam;
constructor(check, seam, detail) {
super(`[integrity] checker_dead: '${check}' at the ${seam} seam ${detail} ` +
`A green report from a check that never ran is decoration, not health — two shipped ` +
`checks in this codebase decayed exactly this way. Re-wire the check or unregister it.`);
this.name = 'CheckerDeadError';
this.check = check;
this.seam = seam;
}
}
/**
* Did this row file NOTHING — not a pass, a fail, a not-applicable or an
* unreachable? The first half of theorem (i) below, and the ONE owner of it:
* `assertAlive` throws on it when work existed, and a reader of the
* `integrity.disposition` rows (an exporter deciding which rows are worth a
* reader's attention) asks the same question of the same counts.
*/
export function filedNothing(row) {
return row.checked + row.notApplicable + row.unreachable === 0;
}
const keyOf = (check, seam) => `${seam}