agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
119 lines • 6.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.compileVerificationConfig = void 0;
/**
* Compile the explicit verifier's authored rules and retention permission.
* Role: closure-only configuration; callbacks never enter recorded state.
*/
const admit_js_1 = require("../../../integrity/claim-binding/admit.js");
const capture_js_1 = require("../../../integrity/claim-binding/capture.js");
const scope_js_1 = require("../../../integrity/claim-binding/scope.js");
const boundedJson_js_1 = require("../../../lib/boundedJson.js");
const canonicalJson_js_1 = require("../../../lib/canonicalJson.js");
const envelope_js_1 = require("../../../semantics/envelope.js");
const WITHHELD = Object.freeze({
resultVisible: false,
scopeVisible: false,
});
const GRANTED = Object.freeze({ resultVisible: true, scopeVisible: true });
function sameScope(left, right) {
// Functions are author-owned identities, not JSON or a stringified source.
if (left.dimensions.length !== right.dimensions.length ||
left.dimensions.some((dimension, index) => dimension.normalize !== right.dimensions[index].normalize))
return false;
const data = (scope) => ({
...scope,
dimensions: scope.dimensions.map((dimension) => ({ ...dimension, normalize: undefined })),
});
return (0, canonicalJson_js_1.canonicalJson)(data(left)) === (0, canonicalJson_js_1.canonicalJson)(data(right));
}
/** Only the existing detached capture ports can enter the author's callback. */
function authorizationInputOf(raw) {
const source = (0, boundedJson_js_1.ownData)(raw, ['dispatch', 'returned', 'served']);
const dispatch = (0, boundedJson_js_1.ownData)((0, boundedJson_js_1.copyJson)(source.dispatch, scope_js_1.BINDING_LIMITS.scopeBytes * 2, true), [
'identity',
'id',
'toolName',
'toolCallId',
'iteration',
'scopeDeclaration',
'scope',
'periodDimension',
'unavailable',
]);
const identity = (0, boundedJson_js_1.ownData)(dispatch.identity, ['namespace', 'runId', 'ordinal']);
const declaration = (0, boundedJson_js_1.ownData)(dispatch.scopeDeclaration, ['id', 'version']);
const returned = (0, boundedJson_js_1.ownData)((0, boundedJson_js_1.copyJson)(source.returned, scope_js_1.BINDING_LIMITS.resultBytes + scope_js_1.BINDING_LIMITS.scopeBytes, true), ['resultId', 'semantics', 'unavailable']);
if (dispatch.unavailable !== undefined ||
returned.unavailable !== undefined ||
!(0, scope_js_1.boundedText)(identity.namespace) ||
!(0, scope_js_1.boundedText)(identity.runId) ||
typeof identity.ordinal !== 'number' ||
dispatch.id !==
(0, capture_js_1.resultIdentityOf)({
namespace: identity.namespace,
runId: identity.runId,
ordinal: identity.ordinal,
}) ||
returned.resultId !== dispatch.id ||
!(0, scope_js_1.boundedText)(dispatch.toolName) ||
!(0, scope_js_1.boundedText)(dispatch.toolCallId) ||
typeof dispatch.iteration !== 'number' ||
!Number.isSafeInteger(dispatch.iteration) ||
dispatch.iteration < 0 ||
!(0, scope_js_1.boundedText)(declaration.id) ||
!(0, scope_js_1.boundedText)(declaration.version) ||
(Object.hasOwn(dispatch, 'periodDimension') && !(0, scope_js_1.boundedText)(dispatch.periodDimension)) ||
(0, envelope_js_1.readSemantics)(returned.semantics) === undefined)
throw new Error('Invalid verification authorization input.');
(0, boundedJson_js_1.ownData)((0, boundedJson_js_1.copyJson)(dispatch.scope, scope_js_1.BINDING_LIMITS.scopeBytes, true));
return Object.freeze({
dispatch: Object.freeze(dispatch),
returned: Object.freeze(returned),
served: (0, boundedJson_js_1.copyJson)(source.served, scope_js_1.BINDING_LIMITS.resultBytes, true),
});
}
/** Strict configuration admission runs once, not at every verification. */
function compileVerificationConfig(raw) {
const source = (0, boundedJson_js_1.ownData)(raw, ['rules', 'authorizeEvidence']);
const rules = (0, scope_js_1.ownConfigArray)(source.rules, scope_js_1.BINDING_LIMITS.results).map(admit_js_1.bindingRuleOf);
if (rules.length === 0 || typeof source.authorizeEvidence !== 'function')
throw new Error('findings.verify requires rules and an explicit authorizeEvidence callback.');
const authorize = source.authorizeEvidence;
const ids = new Set();
const scopes = new Map();
for (const rule of rules) {
if (ids.has(rule.id))
throw new Error('Duplicate findings verification rule.');
ids.add(rule.id);
const prior = scopes.get(rule.toolName);
if (prior !== undefined && !sameScope(prior, rule.scopeDeclaration))
throw new Error('Conflicting findings verification scopes for one tool.');
scopes.set(rule.toolName, rule.scopeDeclaration);
}
return Object.freeze({
rules: Object.freeze(rules),
scopeForTool: (toolName) => scopes.get(toolName),
authorizeEvidence: (input) => {
try {
const response = authorize(authorizationInputOf(input));
// A mistaken async callback cannot grant access. Consume rejection of
// a genuine Promise without awaiting it or invoking an arbitrary then.
if (response instanceof Promise) {
void Promise.prototype.then.call(response, undefined, () => undefined);
return WITHHELD;
}
const decision = (0, boundedJson_js_1.ownData)(response, ['resultVisible', 'scopeVisible']);
return decision.resultVisible === true && decision.scopeVisible === true
? GRANTED
: WITHHELD;
}
catch {
// Never record policy exception text, return values or private inputs.
return WITHHELD;
}
},
});
}
exports.compileVerificationConfig = compileVerificationConfig;
//# sourceMappingURL=verificationConfig.js.map