UNPKG

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.21 kB
/** * scripts/label — the ONE rule that turns a code call's record into a label, * and the label's words. * * Pattern: pure function over two separate facts (design § 4.3). * Role: core/ layer leaf. Asked by the dispatch loop when it files a call's * `script` row (`rows.ts` · `scriptRowFor`); every sentence that names * an outcome — the attachment's label line, the recovery clause, the * answer account — reads the row's label through {@link labelWords}. * Emits: N/A. * * ## Three facts, read in one order * * The record holds three facts about a code call, written by three mechanisms: * EXECUTION evidence (the runner's facts — `codeRunnerTool.ts` · * `CodeRunFacts`, taken right after `tool.execute` returns), call SETTLEMENT * (did the call return, throw, or never enter `execute`) and result DELIVERY * (the tool's ceiling replaced the payload). A label is read from execution * evidence first, then settlement, and NEVER from delivery: a withheld result * does not undo a completed execution (it rides the row as `resultWithheld`). * * | the record says | label | * |---|---| * | an explicit `exitCode: 0` | `completed` | * | an explicit non-zero `exitCode` (a whole number — {@link isExitCode}) | `completed-with-failure` | * | `serviceError` and no exit code | `outcome-unknown` | * | `ok: true`, no exit code | `reported-success` | * | `ok: false`, no exit code, no service error (a stopped process included) | `reported-failure` | * | facts that report no outcome (`ok` absent, no exit code) | — no execution evidence: the settlement decides | * | no facts, the call returned | `returned` | * | no facts, the call threw (a timeout, a cancellation, a staging refusal) | `outcome-unknown` | * | the call never entered `execute` (or has not settled) | `submitted` | * * Only an explicit exit code proves the program reached an exit. `ok` is a * VERDICT: it never yields `completed`, and no word here prints an exit number * the record does not hold. * * @example * ```ts * scriptLabelOf({ settlement: 'returned', facts: { exitCode: 0 } }); // { label: 'completed', exitCode: 0 } * scriptLabelOf({ settlement: 'returned', facts: { ok: false, serviceError: true } }); // { label: 'outcome-unknown', serviceError: true } * scriptLabelOf({ settlement: 'threw' }); // { label: 'outcome-unknown' } * labelWords('completed-with-failure', 7); // 'completed with failure, exit 7' * ``` */ /** * Whether `value` is an exit code: a whole number, as a process reports one * (a negative one included — a signal, on some runtimes). THE rule for every * writer and reader of a script's exit code — the label below, and the * readers of a saved record (`rows.ts` · `scriptRowIsWellFormed`, * `attachment.ts` · `recordedScripts`, `match.ts` · `recordedBlocks`), so the * writer never files a row the checkpoint door refuses. A runner that reports * anything else (`1.5`, `NaN`) reported no exit code. */ export const isExitCode = (value) => Number.isInteger(value); /** * Whether a recorded label and exit code agree, as {@link scriptLabelOf} * writes them: an exit code rides exactly the two labels one proves — `0` on * `completed`, any other on `completed-with-failure` — and no other label. * A record where they disagree holds a value no writer of this library files. */ export function exitCodeFits(label, exitCode) { if (label === 'completed') return exitCode === 0; if (label === 'completed-with-failure') return isExitCode(exitCode) && exitCode !== 0; return exitCode === undefined; } /** * The label of one call — execution evidence first, then settlement. `facts` * is ABSENT when the tool filed none (a declared tool that is not * `codeRunnerTool`, or a call that never reached its runner). */ export function scriptLabelOf(input) { const facts = input.facts; if (facts !== undefined) { if (isExitCode(facts.exitCode)) { return { label: facts.exitCode === 0 ? 'completed' : 'completed-with-failure', exitCode: facts.exitCode, }; } if (facts.serviceError === true) return { label: 'outcome-unknown', serviceError: true }; if (facts.ok === true) return { label: 'reported-success' }; if (facts.ok === false) return { label: 'reported-failure' }; // Facts with no outcome in them — the runner reported neither an exit code // nor a verdict — are no execution evidence: the settlement decides below. } switch (input.settlement) { case 'not-entered': return { label: 'submitted' }; case 'returned': return { label: 'returned' }; case 'threw': return { label: 'outcome-unknown' }; } } /** * The label's own words — the one phrase every library sentence about a call's * outcome uses (design § 4.3). `exitCode` is printed only for * `completed-with-failure`, and only the number the record holds. */ export function labelWords(label, exitCode) { switch (label) { case 'submitted': return 'submitted'; case 'returned': return 'tool call returned; execution not confirmed'; case 'reported-success': return 'runner reported success; no exit code'; case 'reported-failure': return 'runner reported failure; no exit code'; case 'completed': return 'completed, exit 0'; case 'completed-with-failure': return exitCode === undefined ? 'completed with failure' : `completed with failure, exit ${exitCode}`; case 'outcome-unknown': return 'outcome unknown'; } } /** Every label, in the design's order — for a reader that validates one. */ export const SCRIPT_LABELS = Object.freeze([ 'submitted', 'returned', 'reported-success', 'reported-failure', 'completed', 'completed-with-failure', 'outcome-unknown', ]); //# sourceMappingURL=label.js.map