UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

34 lines (33 loc) • 1.92 kB
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; 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 ${String(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) .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.`); } }