@sema-agent/core
Version:
Stateless, task-oriented AI agent core
422 lines (421 loc) • 23.2 kB
JavaScript
import { COMMAND_RULE_TOOL, PATH_RULE_FACES, escapeForDisclosure, parseRuleText, programRunReachOf, ruleReachesProgramRun, ruleToolGrammarOf } from "./permission-rule-model.js";
import { isNameableToolName, ruleSpellingOf } from "./permission-rule-syntax.js";
import { isShellFaceToolName, pathTargetOf } from "./tool-registry.js";
import { writerOf } from "./permission-rule-store.js";
import { canonicalize } from "./canonical-json.js";
import { types } from "node:util";
import { describeFault, receive } from "./mods/kernel/receive.js";
import { DEFAULT_CAPS } from "./permission-rules.js";
export const ORG_UNAVAILABLE_DECISION_REASON = "org_unavailable";
export const ORG_ADJUDICATION_TIMEOUT_MS = 15_000;
export function settleOrgVerdictWithin(p, fallback, opts) {
return new Promise((resolve) => {
let settled = false;
const finish = (v, cause) => {
if (settled)
return;
settled = true;
clearTimeout(timer);
opts.signal?.removeEventListener("abort", onAbort);
if (cause !== undefined) {
try {
opts.onFallback?.(cause);
}
catch {
}
}
resolve(v);
};
const onAbort = () => finish(fallback, "aborted");
const timer = setTimeout(() => finish(fallback, "timeout"), opts.timeoutMs);
if (opts.signal?.aborted === true) {
finish(fallback, "aborted");
return;
}
opts.signal?.addEventListener("abort", onAbort);
p.then((v) => finish(v), () => finish(fallback));
});
}
export const ORG_RULE_DECISION_REASON = "org_rule";
export const ORG_FETCHED_AT_SKEW_ALLOWANCE_MS = 5 * 60_000;
export const UNGOVERNED_ORG_RESOLUTION = Object.freeze({ source: "org", status: "ungoverned", rules: [], disclosures: [] });
export function createOrgRulePartition(cfg) {
if (cfg === null || typeof cfg !== "object") {
throw new Error("the org partition config must be an object naming a snapshot source and a staleness bound");
}
if (cfg.source === undefined || typeof cfg.source.current !== "function") {
throw new Error("org-governed is declared but no OrgRuleSnapshotProvider is wired as `org.source` — a governed deployment without an org source is a configuration contradiction; refusing to boot rather than running silently ungoverned");
}
if (typeof cfg.stalenessBoundMs !== "number" || !Number.isFinite(cfg.stalenessBoundMs) || cfg.stalenessBoundMs <= 0) {
throw new Error(`org stalenessBoundMs must be a finite positive number of milliseconds (got ${escapeForDisclosure(cfg.stalenessBoundMs)})`);
}
const provider = cfg.source;
const now = cfg.now ?? Date.now;
let memoryState;
const readState = async () => {
const state = cfg.persistence !== undefined ? await cfg.persistence.readOrgState() : memoryState;
return state === undefined ? undefined : orgStateCopyOf(state);
};
const writeState = async (state) => {
if (cfg.persistence !== undefined)
await cfg.persistence.installOrgState(structuredClone(state));
else
memoryState = structuredClone(state);
};
let chain = Promise.resolve();
const serialize = (fn) => {
const run = chain.then(fn, fn);
chain = run.then(() => undefined, () => undefined);
return run;
};
const resolve = async () => {
const disclosures = [];
if (cfg.persistence === undefined) {
disclosures.push("org rule state has no durable persistence wired — the last-known-good snapshot and the anti-rollback mark do not survive a restart");
}
let fetched;
let fetchFailed = false;
const settled = await settleOrgVerdictWithin(provider.current().then((v) => ({ v }), (e) => ({ e })), { timedOut: true }, { timeoutMs: ORG_ADJUDICATION_TIMEOUT_MS });
try {
if ("timedOut" in settled)
throw new Error(`the org snapshot source did not answer within ${ORG_ADJUDICATION_TIMEOUT_MS}ms`);
if ("e" in settled)
throw settled.e;
fetched = orgSnapshotCopyOf(settled.v);
}
catch (err) {
fetchFailed = true;
disclosures.push(`org snapshot source failed: ${escapeForDisclosure(err instanceof Error ? err.message : err)}`);
}
return await settleOrgVerdictWithin(serialize(async () => {
const nowMs = now();
const guardedRead = async (context) => {
try {
return await readState();
}
catch (err) {
disclosures.push(`org state ${context} read failed: ${escapeForDisclosure(err instanceof Error ? err.message : err)}`);
return undefined;
}
};
const installed = await (async () => {
const persisted = await guardedRead("persistence");
if (fetched === undefined)
return persisted;
const invalid = validateOrgSnapshot(fetched, nowMs);
if (invalid !== undefined) {
disclosures.push(`org snapshot refused: ${invalid}; the previously installed snapshot (if any) remains in force`);
return persisted;
}
const persistedFloor = persisted === undefined ? undefined : antiRollbackFloor(persisted);
if (persisted !== undefined && !persistedMarkIsCoherent(persisted)) {
disclosures.push(`the durable org state carries a high-water mark (${escapeForDisclosure(persisted.revisionHighWater)}) that is not a finite number at or above its own snapshot revision (${escapeForDisclosure(persisted.snapshot?.revision)}) — the anti-rollback fence is being held at ${escapeForDisclosure(persistedFloor)} instead, and the durable state should be repaired`);
}
if (persistedFloor !== undefined && fetched.revision < persistedFloor) {
disclosures.push(`org snapshot revision ${fetched.revision} is below the installed high-water mark ${escapeForDisclosure(persistedFloor)} — refusing the rollback; the current deny set is unchanged`);
return persisted;
}
if (persisted !== undefined && fetched.revision === persisted.snapshot.revision && sameOrgPolicyContent(fetched, persisted.snapshot) && fetched.fetchedAtMs <= persisted.snapshot.fetchedAtMs) {
return persisted;
}
if (persisted !== undefined && fetched.revision === persisted.snapshot.revision && !sameOrgPolicyContent(fetched, persisted.snapshot)) {
disclosures.push(`org snapshot revision ${fetched.revision} equals the installed revision but carries DIFFERENT policy content — refusing the swap; the current deny set is unchanged`);
return persisted;
}
const state = {
revisionHighWater: Math.max(persistedFloor !== undefined && Number.isFinite(persistedFloor) ? persistedFloor : 0, fetched.revision),
snapshot: fetched,
installedAtMs: nowMs,
};
try {
await writeState(state);
}
catch (err) {
const reread = await guardedRead("reconciliation");
if (reread !== undefined && antiRollbackFloor(reread) >= state.revisionHighWater) {
disclosures.push(`org snapshot install was superseded by a concurrent install at revision ${escapeForDisclosure(reread.snapshot.revision)} — continuing on the newer installed state`);
return reread;
}
disclosures.push(`org snapshot install failed (${escapeForDisclosure(err instanceof Error ? err.message : err)}) and no superseding installed state exists — org adjudication is UNAVAILABLE`);
return undefined;
}
return state;
})();
const decisionMs = now();
const withinBound = (snap) => decisionMs - snap.fetchedAtMs <= cfg.stalenessBoundMs && snap.fetchedAtMs <= decisionMs + ORG_FETCHED_AT_SKEW_ALLOWANCE_MS;
if (installed !== undefined) {
if (installed.snapshot.fetchedAtMs > decisionMs + ORG_FETCHED_AT_SKEW_ALLOWANCE_MS) {
disclosures.push(`the installed org snapshot claims a FUTURE observation time (${escapeForDisclosure(installed.snapshot.fetchedAtMs)} vs now ${decisionMs}) — org adjudication is UNAVAILABLE; the consuming gate must tighten every terminal allow to a real-approval ask`);
return { source: "org", status: "unavailable", rules: [], disclosures };
}
const servingRefusal = validateOrgSnapshot(installed.snapshot, decisionMs);
if (servingRefusal !== undefined) {
disclosures.push(`the installed org snapshot (revision ${escapeForDisclosure(installed.snapshot.revision)}) does not meet this version's validator: ${servingRefusal} — org adjudication is UNAVAILABLE; the consuming gate must tighten every terminal allow to a real-approval ask`);
return { source: "org", status: "unavailable", rules: [], disclosures };
}
if (withinBound(installed.snapshot)) {
const freshlyInstalled = fetched !== undefined && installed.snapshot === fetched;
if (!freshlyInstalled && !fetchFailed && fetched === undefined) {
disclosures.push("org snapshot source returned no snapshot — continuing on the last-known-good");
}
const degraded = describeUnreadableOrgRows(readListedOrgRules(installed.snapshot.rules).unreadable, installed.snapshot.revision);
if (degraded !== undefined)
disclosures.push(degraded);
return {
source: "org",
status: freshlyInstalled ? "fresh" : "last-known-good",
rules: structuredClone(installed.snapshot.rules),
revision: installed.snapshot.revision,
disclosures,
};
}
disclosures.push(`the newest org snapshot was observed ${decisionMs - installed.snapshot.fetchedAtMs}ms ago (bound ${cfg.stalenessBoundMs}ms) — org adjudication is UNAVAILABLE; the consuming gate must tighten every terminal allow to a real-approval ask`);
return { source: "org", status: "unavailable", rules: [], disclosures };
}
disclosures.push("no org snapshot has ever been installed — org adjudication is UNAVAILABLE; the consuming gate must tighten every terminal allow to a real-approval ask");
return { source: "org", status: "unavailable", rules: [], disclosures };
}), {
source: "org",
status: "unavailable",
rules: [],
disclosures: [...disclosures, `org state persistence did not answer within ${ORG_ADJUDICATION_TIMEOUT_MS}ms — org adjudication is UNAVAILABLE; the consuming gate must tighten every terminal allow to a real-approval ask`],
}, { timeoutMs: ORG_ADJUDICATION_TIMEOUT_MS });
};
return { resolve };
}
function antiRollbackFloor(state) {
const mark = typeof state.revisionHighWater === "number" && Number.isFinite(state.revisionHighWater) ? state.revisionHighWater : undefined;
const own = typeof state.snapshot?.revision === "number" && Number.isFinite(state.snapshot.revision) ? state.snapshot.revision : undefined;
if (mark === undefined)
return own ?? Number.NEGATIVE_INFINITY;
return own === undefined ? mark : Math.max(mark, own);
}
function persistedMarkIsCoherent(state) {
return (typeof state.revisionHighWater === "number" &&
Number.isFinite(state.revisionHighWater) &&
typeof state.snapshot?.revision === "number" &&
Number.isFinite(state.snapshot.revision) &&
state.revisionHighWater >= state.snapshot.revision);
}
export function sameOrgPolicyContent(a, b) {
if (a.rules.length !== b.rules.length)
return false;
const policy = (r) => canonicalize(orgRowPolicyOf(r));
return a.rules.every((r, i) => policy(b.rules[i]) === policy(r));
}
const DISCLOSED_UNREADABLE_ROWS = 20;
function reachOfRowHead(text, behavior) {
const head = typeof text === "string" ? ruleSpellingOf(text)?.toolName : undefined;
if (head === undefined || !isNameableToolName(head))
return "every";
if (head === COMMAND_RULE_TOOL || isShellFaceToolName(head))
return { words: [COMMAND_RULE_TOOL], faces: [] };
if (ruleToolGrammarOf(head) === undefined)
return "every";
const column = Object.hasOwn(PATH_RULE_FACES, head) ? PATH_RULE_FACES[head]?.[behavior] : undefined;
return { words: [head], faces: column ?? [] };
}
function rowReaches(reach, words, face) {
if (reach === "every")
return true;
return reach.words.some((w) => words.includes(w)) || (face !== undefined && reach.faces.includes(face));
}
function listRefusalOf(rules) {
if (typeof rules === "object" && rules !== null) {
if (types.isProxy(rules))
return "rules is a Proxy, not an array";
const held = HELD_LIST_REFUSALS.get(rules);
if (held !== undefined)
return held;
}
if (!Array.isArray(rules))
return "rules is not an array";
const cap = DEFAULT_CAPS.maxRules;
return rules.length > cap ? `rules list has ${rules.length} entries; the cap is ${cap} — refused whole (not truncated)` : undefined;
}
export const ORG_ROW_POLICY_MEMBERS = Object.freeze(["rule", "behavior"]);
const ORG_SNAPSHOT_ENVELOPE_MEMBERS = Object.freeze(["revision", "fetchedAtMs", "signature"]);
const ORG_STATE_MEMBERS = Object.freeze(["revisionHighWater", "installedAtMs"]);
function scalarMembersOf(value, members) {
const held = {};
if (typeof value !== "object" || value === null)
return held;
for (const k of members) {
const v = Object.hasOwn(value, k) ? value[k] : undefined;
if (typeof v === "string" || typeof v === "boolean" || v === null || (typeof v === "number" && Number.isFinite(v)))
held[k] = v;
}
return held;
}
function orgRowPolicyOf(row) {
return scalarMembersOf(row, ORG_ROW_POLICY_MEMBERS);
}
const ORG_RULES_DEPTH = 2;
const ORG_RULES_RECEIPT = Object.freeze({ accessors: "call-once", depth: ORG_RULES_DEPTH, others: "copy", contain: true, isProxy: (v) => types.isProxy(v) });
export function orgRuleListOf(rules) {
const refused = listRefusalOf(rules);
if (refused !== undefined)
return { refused };
const received = receive(rules, ORG_RULES_RECEIPT);
if (!received.ok)
return { refused: `rules could not be received (${describeFault(received.fault)})` };
const copy = received.value;
return { rows: Array.from({ length: copy.length }, (_, i) => orgRowPolicyOf(Object.hasOwn(copy, i) ? copy[i] : undefined)) };
}
const HELD_LIST_REFUSALS = new WeakMap();
function heldRefusalOf(words) {
const held = Object.freeze({});
HELD_LIST_REFUSALS.set(held, words);
return held;
}
function orgSnapshotCopyOf(v) {
if (v === undefined)
return undefined;
if (typeof v === "object" && v !== null && types.isProxy(v))
throw new Error("the snapshot is a Proxy, not data");
const envelope = scalarMembersOf(v, ORG_SNAPSHOT_ENVELOPE_MEMBERS);
const rules = typeof v === "object" && v !== null ? v.rules : undefined;
const refusal = listRefusalOf(rules);
if (refusal !== undefined)
return { ...envelope, rules: heldRefusalOf(refusal) };
const list = orgRuleListOf(rules);
if ("refused" in list)
throw new Error(`the snapshot's ${list.refused}`);
return { ...envelope, rules: list.rows };
}
function orgStateCopyOf(state) {
if (typeof state === "object" && state !== null && types.isProxy(state))
throw new Error("the persisted org state is a Proxy, not data");
const snapshot = typeof state === "object" && state !== null ? state.snapshot : undefined;
return { ...scalarMembersOf(state, ORG_STATE_MEMBERS), snapshot: orgSnapshotCopyOf(snapshot ?? null) };
}
function readOrgRow(row, index) {
const { rule: text, behavior: said } = orgRowPolicyOf(row);
const behavior = said === "ask" ? "ask" : "deny";
const unreadable = (code, detail) => ({
kind: "unreadable",
index,
rule: typeof text === "string" ? text : text === undefined ? "<unreadable>" : escapeForDisclosure(text),
code,
...(detail !== undefined ? { detail } : {}),
behavior,
reach: reachOfRowHead(text, behavior),
});
if (typeof text !== "string" || text === "")
return unreadable("invalid.grammar", "no rule text");
if (said !== "deny" && said !== "ask")
return unreadable("invalid.grammar", said === undefined ? "no behavior" : `behavior "${escapeForDisclosure(said)}" is not deny or ask`);
const parsed = parseRuleText(text, said);
if ("reject" in parsed)
return unreadable(parsed.reject.code);
if (parsed.rule.tool !== COMMAND_RULE_TOOL)
return unreadable("unsupported.tool");
return { kind: "read", index, rule: text, behavior: said, parsed: parsed.rule };
}
export function readOrgRules(rules) {
const list = orgRuleListOf(rules);
if ("refused" in list)
return list;
const rows = list.rows.map((row, i) => readOrgRow(row, i + 1));
const unreadable = rows.filter((r) => r.kind === "unreadable");
return {
rows,
unreadable,
verdictFor(call) {
const words = typeof call.tool === "string" ? [call.tool] : call.tool;
const command = words.includes(COMMAND_RULE_TOOL) && typeof call.command === "string" ? call.command : undefined;
let ask;
let unjudged;
for (const row of rows) {
if (row.kind === "unreadable") {
if (!rowReaches(row.reach, words, call.face))
continue;
const verdict = { behavior: row.behavior, rule: row.rule, unreadable: unreadableOrgRowReason(row) };
if (row.behavior === "deny")
return verdict;
ask ??= verdict;
continue;
}
if (command === undefined)
continue;
const outcome = programRunReachOf(row.parsed, command);
if (outcome.reach === "not_reached")
continue;
if (outcome.reach === "unreadable") {
unjudged ??= { behavior: "ask", rule: row.rule, unreadable: outcome.reason };
continue;
}
if (row.behavior === "deny")
return { behavior: "deny", rule: row.rule };
ask ??= { behavior: "ask", rule: row.rule };
}
return unjudged ?? ask;
},
};
}
export function unenforceableOrgRules(rules) {
return readListedOrgRules(rules).unreadable.map((u) => ({ rule: u.rule, code: u.code }));
}
function readListedOrgRules(rules) {
const reading = readOrgRules(rules);
if ("refused" in reading)
throw new TypeError(`the org rules cannot be read: ${reading.refused}`);
return reading;
}
export function unreadableOrgRowReason(row) {
return `row ${row.index} of the organization snapshot is not a rule this layer reads (${row.code}${row.detail !== undefined ? `: ${row.detail}` : ""}); republish it in the shell tool's command grammar`;
}
export function orgUnreadableClause(reason) {
return `which could not be read against it (${reason})`;
}
export function describeUnreadableOrgRows(unreadable, revision) {
if (unreadable.length === 0)
return undefined;
const named = unreadable
.slice(0, DISCLOSED_UNREADABLE_ROWS)
.map((u) => `row ${u.index} "${escapeForDisclosure(u.rule)}" (${u.code}${u.detail !== undefined ? `: ${u.detail}` : ""})`)
.join(", ");
const more = unreadable.length - DISCLOSED_UNREADABLE_ROWS;
return (`the org snapshot${revision !== undefined ? ` (revision ${escapeForDisclosure(revision)})` : ""} is served DEGRADED: ${unreadable.length} row(s) this layer cannot read — ${named}${more > 0 ? ` and ${more} more` : ""}; ` +
`each stands at its strictest reading over the calls it may reach (a deny row, or one whose behavior cannot be read, refuses them; an ask row asks a person), and every readable row stands as published — republish the named rows in the shell tool's command grammar`);
}
function validateOrgSnapshot(s, nowMs) {
if (typeof s.revision !== "number" || !Number.isFinite(s.revision))
return `revision is not a finite number (${escapeForDisclosure(s.revision)})`;
if (typeof s.fetchedAtMs !== "number" || !Number.isFinite(s.fetchedAtMs))
return `fetchedAtMs is not a finite number (${escapeForDisclosure(s.fetchedAtMs)})`;
if (s.fetchedAtMs > nowMs + ORG_FETCHED_AT_SKEW_ALLOWANCE_MS) {
return `fetchedAtMs is ${s.fetchedAtMs - nowMs}ms in the future (allowance ${ORG_FETCHED_AT_SKEW_ALLOWANCE_MS}ms) — a future-dated observation would satisfy the staleness bound indefinitely`;
}
return listRefusalOf(s.rules);
}
export function orgRuleVerdictFor(rules, call) {
return readListedOrgRules(rules).verdictFor(call);
}
export function orgRuleShadows(orgRules, rule) {
return compileOrgShadowPredicate(orgRules)(rule);
}
export function compileOrgShadowPredicate(orgRules) {
const { rows } = readListedOrgRules(orgRules);
const denies = rows.flatMap((r) => (r.kind === "read" && r.behavior === "deny" ? [r.parsed] : []));
const standing = rows.flatMap((r) => (r.kind === "unreadable" && r.behavior === "deny" ? [r.reach] : []));
return (rule) => {
if (standing.length > 0) {
const word = isShellFaceToolName(rule.tool) ? COMMAND_RULE_TOOL : rule.tool;
const target = pathTargetOf(rule.tool);
const faces = Object.hasOwn(PATH_RULE_FACES, rule.tool)
? (PATH_RULE_FACES[rule.tool]?.allow ?? [])
: target !== undefined
? [target.access === "read" ? "read" : "write"]
: [undefined];
if (standing.some((reach) => faces.some((face) => rowReaches(reach, [word], face))))
return true;
}
if (rule.tool !== COMMAND_RULE_TOOL || denies.length === 0)
return false;
return denies.some((d) => ruleReachesProgramRun(d, rule.command));
};
}
export function isWritablePermissionRuleStore(store) {
return writerOf(store) !== undefined;
}