UNPKG

agentfootprint

Version:

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

110 lines • 7.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.requireVerificationOnResume = exports.verificationCheckpointOf = exports.readVerificationCheckpoint = void 0; /** * One admission boundary for the verifier's private checkpoint carrier. * Role: join validated observation identities to retained lineage/counters, * never reconstruct evidence, evaluate a claim or authenticate storage. * Historical observations without a carrier are readable but supply no grant. */ const boundedJson_js_1 = require("../../../lib/boundedJson.js"); const canonicalJson_js_1 = require("../../../lib/canonicalJson.js"); const capture_js_1 = require("../../../integrity/claim-binding/capture.js"); const scope_js_1 = require("../../../integrity/claim-binding/scope.js"); const verificationRow_js_1 = require("./verificationRow.js"); const verificationState_js_1 = require("./verificationState.js"); /** Classify stored rows as data, using the same strict new-row reader on both paths. */ function verificationRowsOf(raw) { // The legacy optional ledger treats undefined as absence. The NEW evidence // carrier has no such exception: its own present-only reader stays strict. const rows = (0, scope_js_1.ownConfigArray)(raw === undefined ? [] : raw, Number.MAX_SAFE_INTEGER); const observations = []; for (const row of rows) { if (row === null || typeof row !== 'object' || Array.isArray(row)) throw new TypeError('Invalid findings verification ledger.'); const kind = Object.getOwnPropertyDescriptor(row, 'kind'); if (kind === undefined || !('value' in kind)) throw new TypeError('Invalid findings verification row kind.'); if (kind.value === 'claim-verification') observations.push((0, verificationRow_js_1.readClaimVerificationRow)(row)); } return observations; } /** Read a present carrier beside its ledger; the checkpoint owner authenticates origin. */ function readVerificationCheckpoint(raw, ledger) { const admitted = (0, verificationState_js_1.readVerificationState)(raw, 0); let largestClaimOrdinal = 0; const seen = new Set(); // Reuse the dense own-data array owner, not the saved value's iterator. // No new ledger length cap: older ledger rows retain their existing budget. for (const observation of verificationRowsOf(ledger)) { const identity = (0, verificationRow_js_1.readClaimIdentity)(observation.claimId); if (identity.namespace !== admitted.evidence.namespace || !admitted.evidence.runIds.includes(identity.runId) || seen.has(identity.ordinal)) throw new TypeError('Invalid findings verification claim lineage.'); seen.add(identity.ordinal); largestClaimOrdinal = Math.max(largestClaimOrdinal, identity.ordinal); if (observation.outcome !== 'unverified') { const resolved = observation.resolved; const result = (0, capture_js_1.readResultIdentity)(resolved.resultId); if (result.namespace !== admitted.evidence.namespace || !admitted.evidence.runIds.includes(result.runId) || result.ordinal >= admitted.nextResultOrdinal) throw new TypeError('Invalid findings verification result lineage.'); const receipt = admitted.evidence.results.find((item) => item.id === resolved.resultId); const facts = receipt?.facts?.filter((fact) => fact.entity === resolved.evidence.subject.id && fact.field === resolved.evidence.predicate); if (receipt === undefined || receipt.unavailable !== undefined || (0, canonicalJson_js_1.canonicalJson)(receipt.scope) !== (0, canonicalJson_js_1.canonicalJson)(resolved.scope) || (0, canonicalJson_js_1.canonicalJson)(receipt.coverage) !== (0, canonicalJson_js_1.canonicalJson)(resolved.coverage) || (0, canonicalJson_js_1.canonicalJson)(receipt.period) !== (0, canonicalJson_js_1.canonicalJson)(resolved.period) || facts?.length !== 1 || (0, canonicalJson_js_1.canonicalJson)(facts[0].value) !== (0, canonicalJson_js_1.canonicalJson)(resolved.evidence.value)) throw new TypeError('Recorded comparison does not name its retained receipt.'); } } return (0, verificationState_js_1.readVerificationState)(admitted, largestClaimOrdinal); } exports.readVerificationCheckpoint = readVerificationCheckpoint; /** * Shared by conversation-history and full pause boundaries. Presence is strict: * undefined, inherited fields and accessors are not absence or live evidence. */ function verificationCheckpointOf(container) { if (container === null || typeof container !== 'object' || Array.isArray(container)) throw new TypeError('Invalid findings verification checkpoint container.'); const descriptor = Object.getOwnPropertyDescriptor(container, 'claimVerification'); if (descriptor === undefined) { if ('claimVerification' in container) throw new TypeError('Inherited findings verification state is not a checkpoint.'); return undefined; } if (!('value' in descriptor)) throw new TypeError('Findings verification state must be stored data.'); const source = (0, boundedJson_js_1.ownData)(container); const ledger = (0, scope_js_1.ownConfigArray)(source.findingsLedger === undefined ? [] : source.findingsLedger, Number.MAX_SAFE_INTEGER); return readVerificationCheckpoint(descriptor.value, ledger); } exports.verificationCheckpointOf = verificationCheckpointOf; /** Never silently discard a previously opted-in verifier on newest-version resume. */ function requireVerificationOnResume(container, enabled) { const state = verificationCheckpointOf(container); if (state === undefined && container !== null && typeof container === 'object') { const ledgerDescriptor = Object.getOwnPropertyDescriptor(container, 'findingsLedger'); if (ledgerDescriptor === undefined && 'findingsLedger' in container) throw new TypeError('Findings verification ledger must be own stored data.'); if (ledgerDescriptor !== undefined && !('value' in ledgerDescriptor)) throw new TypeError('Findings verification ledger must be stored data.'); if (verificationRowsOf(ledgerDescriptor?.value).length > 0) throw new TypeError('This saved run has findings verification observations but no retained evidence ' + 'carrier. It is readable history, not a resumable verification checkpoint.'); } if (state !== undefined && !enabled) throw new TypeError('This saved run carries findings verification evidence. Continue it with findings ' + 'verification enabled; disabling it would silently discard saved checks.'); return state; } exports.requireVerificationOnResume = requireVerificationOnResume; //# sourceMappingURL=verificationCheckpoint.js.map