@sema-agent/core
Version:
Stateless, task-oriented AI agent core
39 lines (38 loc) • 2.37 kB
JavaScript
import { describeRejectedValue } from "./tool-search-setting.js";
export const RETENTION_CASCADE_DOMAINS = Object.freeze(["checkpoints", "session-trees", "orphan-tool-results"]);
export const RETENTION_CASCADE_EXEMPT = Object.freeze(["session-pollution", "session-capture-optout", "lineage.json"]);
function codedError(code, message) {
const e = new Error(message);
e.code = code;
return e;
}
export function assertRetentionCapability(input) {
const { policy, locked, stores } = input;
const declared = policy;
if (declared !== undefined && (typeof declared !== "object" || declared === null || Array.isArray(declared))) {
throw codedError("config.retention_policy", `retentionPolicy must be an object carrying maxAgeDays (got ${declared === null ? "null" : Array.isArray(declared) ? "an array" : typeof declared}).`);
}
if (policy !== undefined && (!Number.isFinite(policy.maxAgeDays) || policy.maxAgeDays < 0)) {
throw codedError("config.retention_policy", `retentionPolicy.maxAgeDays must be a finite non-negative number of days (got ${describeRejectedValue(policy.maxAgeDays)}).`);
}
const declaredRetention = (name, store) => {
const r = store.retention;
if (r === undefined || r === "none")
return "none";
if (r === "managed")
return "managed";
throw codedError("config.retention_capability", `store "${name}" declares an unparseable retention value ${JSON.stringify(r)} — expected "managed" or "none".`);
};
const declarations = stores
.filter((s) => s.store !== undefined && s.store !== null)
.map(({ name, store }) => ({ name, retention: declaredRetention(name, store) }));
if (!locked || policy === undefined)
return;
const incapable = declarations.filter(({ retention }) => retention !== "managed");
if (incapable.length > 0) {
throw codedError("config.retention_capability", `retention policy is LOCKED but ${incapable.map((s) => s.name).join(", ")} ` +
`declare${incapable.length === 1 ? "s" : ""} retention "none" (or no declaration — read fail-closed as "none"): ` +
`a locked retention policy over stores that cannot delete would be "policy locked, data immortal". ` +
`Wire managed-retention stores, or unlock/remove the retention policy.`);
}
}