noa-receipt
Version:
NOA Agent Action Receipt — open, offline-verifiable provenance for AI-agent actions. The governance/receipt organ only; the NOA brain is separate and proprietary.
98 lines (97 loc) • 4.35 kB
JavaScript
import { isProxy as _isProxy, hasOwn as _hasOwn } from "./intrinsics.js";
import { decodeDocument } from "./bytes.js";
const _ownKeys = Reflect.ownKeys;
const _getOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor;
const _getPrototypeOf = Reflect.getPrototypeOf;
const _objectPrototype = Object.prototype;
const _isArray = Array.isArray;
const _isSafeInteger = Number.isSafeInteger;
const _create = Object.create;
const _freeze = Object.freeze;
export function inertOptions(schema, input, what) {
return admit(schema, input, what, 0);
}
const MAX_OPTION_DEPTH = 1;
function admit(schema, input, what, depth) {
if (input === undefined || input === null) {
return { ok: true, value: _freeze(_create(null)) };
}
if (_isProxy(input)) {
return { ok: false, reason: `${what}: a Proxy is not accepted — its traps are attacker code running inside the validator` };
}
const t = typeof input;
if (t === "function") {
return { ok: false, reason: `${what}: options must be a plain object, never a function` };
}
if (t !== "object") {
return { ok: false, reason: `${what}: options must be a plain object` };
}
if (_isArray(input)) {
return { ok: false, reason: `${what}: options must be a plain object, never an array` };
}
const proto = _getPrototypeOf(input);
if (proto !== _objectPrototype && proto !== null) {
return {
ok: false,
reason: `${what}: options must be a plain object (Object.prototype or null prototype) — an exotic prototype carries machinery that is not the caller's configuration`,
};
}
const out = _create(null);
const keys = _ownKeys(input);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (typeof key === "symbol") {
return { ok: false, reason: `${what}: symbol-keyed options are not accepted` };
}
const field = _hasOwn(schema, key) ? schema[key] : undefined;
if (field === undefined) {
return { ok: false, reason: `${what}: unknown option "${key}" — an unrecognised member is a misconfiguration, not a default` };
}
const desc = _getOwnPropertyDescriptor(input, key);
if (desc === undefined) {
return { ok: false, reason: `${what}: option "${key}" has no readable own descriptor` };
}
if (desc.get !== undefined || desc.set !== undefined) {
return { ok: false, reason: `${what}: option "${key}" is an accessor — reading it would run caller code inside the boundary` };
}
const raw = desc.value;
if (raw === undefined)
continue;
if (field.kind === "boolean") {
if (typeof raw !== "boolean") {
return { ok: false, reason: `${what}: option "${key}" must be a boolean` };
}
out[key] = raw;
continue;
}
if (field.kind === "count") {
if (typeof raw !== "number" || !_isSafeInteger(raw) || raw < 0) {
return { ok: false, reason: `${what}: option "${key}" must be a non-negative safe integer` };
}
const max = field.max;
if (max === undefined || raw > max) {
return { ok: false, reason: `${what}: option "${key}" exceeds its permitted ceiling` };
}
out[key] = raw;
continue;
}
if (field.kind === "nested") {
if (field.schema === undefined) {
return { ok: false, reason: `${what}: option "${key}" is declared nested without a schema — an unvalidated sub-object is not configuration` };
}
if (depth >= MAX_OPTION_DEPTH) {
return { ok: false, reason: `${what}: option "${key}" nests deeper than the schema permits` };
}
const inner = admit(field.schema, raw, `${what}.${key}`, depth + 1);
if (!inner.ok)
return { ok: false, reason: inner.reason };
out[key] = inner.value;
continue;
}
const decoded = decodeDocument(raw, `${what}: option "${key}"`);
if (!decoded.ok)
return { ok: false, reason: decoded.reason };
out[key] = decoded.text;
}
return { ok: true, value: _freeze(out) };
}