UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

97 lines • 4.27 kB
"use strict"; /** * time/checkRecord — the record half of the result checks (time design * § 9.2, § 9.6, step T8): the shapes a `period` row carries * (`PeriodDiffers`, `ReadSource`), the checkpoint door's tests for them * (`isPeriodDiffers`, `isShifted`), and the two reads over the turn's * wall-clock sources (`distinctSources`, `clocksDiffer`). * * Pattern: pure shapes and guards; no conversion, no drift, no clock. * Role: split from `check.ts` BY FILE for the synchronous doors — the * checkpoint door's row test (`coverage/period.ts` · * `periodRowIsWellFormed`) is on every agent's graph, and a bundler * places a whole file there — so this file imports only * `instant.ts` and the range and zone types (the optional-family * law, `test/trace-toolpack/browserGraph.test.ts`). `check.ts` * re-exports every public name. * Emits: N/A. * * @example * ```ts * clocksDiffer([ * { toolName: 'orders', zone: 'America/New_York' }, * { toolName: 'tickets', zone: 'Europe/Berlin' }, * ]); // { tools: ['orders', 'tickets'], zones: ['America/New_York', 'Europe/Berlin'] } * ``` */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isShifted = exports.isPeriodDiffers = exports.clocksDiffer = exports.distinctSources = void 0; const instant_js_1 = require("./instant.js"); // ─── Clocks ────────────────────────────────────────────────────────────── /** * The wall-clock sources of one answer, one per tool and zone in the order * met — the limits block names each. Fresh plain objects. */ function distinctSources(sources) { const seen = new Set(); const out = []; for (const s of sources) { const key = JSON.stringify([s.toolName, s.zone]); if (seen.has(key)) continue; seen.add(key); out.push({ toolName: s.toolName, zone: s.zone }); } return out; } exports.distinctSources = distinctSources; /** * `clocks-differ` (§ 9.6) — the tools and zones when the wall-clock sources * of one answer declare more than one zone; `undefined` otherwise. A label * only: it changes no standing, and every comparison is made on instants. */ function clocksDiffer(sources) { const distinct = distinctSources(sources); const zones = [...new Set(distinct.map((s) => s.zone))]; if (zones.length < 2) return undefined; return { tools: [...new Set(distinct.map((s) => s.toolName))], zones }; } exports.clocksDiffer = clocksDiffer; // ─── The row arm ───────────────────────────────────────────────────────── const isRange = (value) => { if (typeof value !== 'object' || value === null) return false; const r = value; const from = (0, instant_js_1.instantOf)(r.from, 'lenient')?.ms; const to = (0, instant_js_1.instantOf)(r.to, 'lenient')?.ms; return from !== undefined && to !== undefined && from < to; }; const isRanges = (value) => Array.isArray(value) && value.every(isRange); /** The checkpoint door's test for a row's {@link PeriodDiffers}. */ function isPeriodDiffers(value) { if (typeof value !== 'object' || value === null || Array.isArray(value)) return false; const d = value; return ((d.against === 'asked' || d.against === 'person') && isRange(d.asked) && isRanges(d.read) && d.read.length > 0 && (d.source === 'declared' || d.source === 'sent' || d.source === 'shifted' || d.source === 'asked') && (d.stepMs === undefined || (Number.isInteger(d.stepMs) && d.stepMs > 0)) && isRanges(d.missing) && isRanges(d.extra) && d.missing.length + d.extra.length > 0); } exports.isPeriodDiffers = isPeriodDiffers; /** The checkpoint door's test for a row's `shifted`. */ function isShifted(value) { return (typeof value === 'object' && value !== null && Number.isInteger(value.byMs)); } exports.isShifted = isShifted; //# sourceMappingURL=checkRecord.js.map