@sema-agent/core
Version:
Stateless, task-oriented AI agent core
161 lines (160 loc) • 8.84 kB
JavaScript
import { parseScopeKey } from "./memory-engine/scope-contract.js";
import { thrownText } from "./thrown-value.js";
function codedError(code, message) {
const e = new Error(message);
e.code = code;
return e;
}
export function foldAdmissionFreeze(input) {
return input.delegated ? (input.inherited ?? []) : input.inherited;
}
export function readDurableOrgAdmission(row) {
return { scopes: row.admittedOrgScopes ?? [], writeScope: row.admittedOrgWriteScope ?? null };
}
const ORG_SHAPE = /^org:/;
function orgScopesOf(spec) {
if (spec.scopeContract !== "v2")
return { readOrg: [], writeOrg: null };
const readOrg = spec.scopes.filter((s) => parseScopeKey(s).kind === "org");
const writeOrg = spec.writeScope !== null && parseScopeKey(spec.writeScope).kind === "org" ? spec.writeScope : null;
return { readOrg, writeOrg };
}
export async function admitMemoryScopes(input) {
const { memorySpec, principal, admission, deploymentScopes, parentAdmittedOrgScopes } = input;
const governed = admission !== undefined ||
deploymentScopes.size > 0 ||
input.priorOwnVerdict !== undefined ||
input.governedProvenance ||
input.orgMemoryDenied ||
(parentAdmittedOrgScopes !== undefined && parentAdmittedOrgScopes.length > 0);
if (governed && memorySpec.scopeContract !== "v2") {
const shaped = [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])].find((s) => ORG_SHAPE.test(s));
if (shaped !== undefined) {
throw codedError("memory.admission_denied", `memory scope "${shaped}" is org-shaped but the task did not opt into the v2 scope contract ` +
`(memory.scopeContract: "v2") — on a deployment with org-memory admission configured, org scopes ` +
`outside the contract are refused (fail-closed), not mounted as opaque keys.`);
}
}
const { readOrg, writeOrg } = orgScopesOf(memorySpec);
const allOrg = [...readOrg, ...(writeOrg !== null && !readOrg.includes(writeOrg) ? [writeOrg] : [])];
if (allOrg.length === 0) {
return {
scopes: [...memorySpec.scopes],
writeScope: memorySpec.writeScope,
admittedOrgScopes: [],
droppedDeploymentScopes: [],
writeScopeNarrowed: false,
ownVerdict: undefined,
};
}
const priorOwn = input.priorOwnVerdict;
const applySessionFreeze = (proj) => {
let { admitted, scopes, writeScope, dropped, writeScopeNarrowed } = proj;
if (priorOwn !== undefined) {
const outsideRequest = admitted.filter((s) => !deploymentScopes.has(s) && !priorOwn.scopes.includes(s));
if (outsideRequest.length > 0) {
throw codedError("memory.admission_denied", `org memory scope(s) ${outsideRequest.map((s) => `"${s}"`).join(", ")} are outside this session's frozen ` +
`admission verdict (recorded at suspend) — a session's org grant can only narrow across suspend/resume.`);
}
const frozenOut = admitted.filter((s) => !priorOwn.scopes.includes(s));
if (frozenOut.length > 0) {
dropped = [...dropped, ...frozenOut];
admitted = admitted.filter((s) => priorOwn.scopes.includes(s));
scopes = scopes.filter((s) => !frozenOut.includes(s));
}
if (writeScope !== null && writeOrg !== null && writeScope === writeOrg && priorOwn.writeScope !== writeScope) {
writeScope = null;
writeScopeNarrowed = true;
}
}
return {
scopes,
writeScope,
admittedOrgScopes: admitted,
droppedDeploymentScopes: dropped,
writeScopeNarrowed,
ownVerdict: { scopes: admitted, writeScope: writeScope !== null && writeOrg !== null && writeScope === writeOrg ? writeScope : null },
};
};
const stampedOrigins = memorySpec.scopeOrigins;
const originOf = (scope) => stampedOrigins !== undefined
? (stampedOrigins[scope] === "deployment" ? "deployment" : "request")
: deploymentScopes.has(scope)
? "deployment"
: "request";
const requests = allOrg.map((scope) => ({ scope, origin: originOf(scope) }));
const requestOrigin = requests.filter((r) => r.origin === "request");
if (input.orgMemoryDenied && requestOrigin.length > 0) {
throw codedError(input.complianceDegraded ? "config.compliance_required" : "config.compliance_denied", `org memory scope(s) ${requestOrigin.map((r) => `"${r.scope}"`).join(", ")} are denied for this principal by the ` +
`compliance posture (capability "org_memory_mount"${input.complianceDegraded ? "; posture resolver failing, fail-closed" : ""}).`);
}
if (parentAdmittedOrgScopes !== undefined) {
const exceeding = requestOrigin.filter((r) => !parentAdmittedOrgScopes.includes(r.scope));
if (exceeding.length > 0) {
throw codedError("memory.admission_denied", `delegated child requests org memory scope(s) ${exceeding.map((r) => `"${r.scope}"`).join(", ")} outside the ` +
`parent's frozen admission verdict — a child plane can only narrow the parent's org grant, never exceed it.`);
}
}
if (admission === undefined) {
if (requestOrigin.length > 0) {
throw codedError("memory.admission_required", `org memory scope(s) ${requestOrigin.map((r) => `"${r.scope}"`).join(", ")} come from the request side but this ` +
`deployment has no memory-scope admission resolver (RunnerDeps.memoryScopeAdmission) — refused fail-closed. ` +
`Deployment-pinned org scopes belong in RunnerDeps.deploymentMemoryScopes.`);
}
return applySessionFreeze({
admitted: allOrg,
scopes: [...memorySpec.scopes],
writeScope: memorySpec.writeScope,
dropped: [],
writeScopeNarrowed: false,
});
}
if (requestOrigin.length > 0 && principal === undefined) {
throw codedError("memory.admission_denied", `org memory scope(s) ${requestOrigin.map((r) => `"${r.scope}"`).join(", ")} require an authenticated ` +
`TaskSpec.principal for admission — a principal-less request cannot be admitted to a tenant plane.`);
}
let verdict;
try {
verdict = await admission({
principal,
requested: requests,
requestedWriteScope: writeOrg !== null ? { scope: writeOrg, origin: originOf(writeOrg) } : null,
});
}
catch (err) {
const hinted = err.retryAfterMs;
const e = codedError("memory.admission_required", `memory-scope admission resolver failed (${thrownText(err)}) — refused fail-closed.`);
if (typeof hinted === "number" && Number.isFinite(hinted) && hinted > 0)
e.retryAfterMs = hinted;
throw e;
}
if (!verdict.ok) {
throw codedError("memory.admission_denied", `org memory admission denied: ${verdict.reason}`);
}
const unrequested = verdict.scopes.filter((s) => !allOrg.includes(s));
if (unrequested.length > 0 || (verdict.writeScope !== null && verdict.writeScope !== writeOrg)) {
throw codedError("memory.admission_denied", `memory-scope admission verdict granted unrequested scope(s) ` +
`${[...unrequested, ...(verdict.writeScope !== null && verdict.writeScope !== writeOrg ? [String(verdict.writeScope)] : [])].map((s) => `"${s}"`).join(", ")} — ` +
`admission can only narrow a request, never extend it; treating the verdict as a resolver fault.`);
}
const refusedRequest = requestOrigin.filter((r) => !verdict.scopes.includes(r.scope));
if (refusedRequest.length > 0) {
throw codedError("memory.admission_denied", `org memory scope(s) ${refusedRequest.map((r) => `"${r.scope}"`).join(", ")} were not admitted — the whole ` +
`prepare is refused (two-state verdict; partial admission is never applied silently).`);
}
const dropped = requests.filter((r) => r.origin === "deployment" && !verdict.scopes.includes(r.scope)).map((r) => r.scope);
const admitted = allOrg.filter((s) => !dropped.includes(s));
const scopes = memorySpec.scopes.filter((s) => !dropped.includes(s));
let writeScope = memorySpec.writeScope;
let writeScopeNarrowed = false;
if (writeOrg !== null) {
if (verdict.writeScope === writeOrg && !dropped.includes(writeOrg)) {
writeScope = writeOrg;
}
else {
writeScope = null;
writeScopeNarrowed = true;
}
}
return applySessionFreeze({ admitted, scopes, writeScope, dropped, writeScopeNarrowed });
}