@sema-agent/core
Version:
Stateless, task-oriented AI agent core
930 lines (929 loc) • 43.4 kB
JavaScript
import { createHash } from "node:crypto";
import { closeSync, existsSync, fsyncSync, linkSync, lstatSync, openSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
import { basename, dirname, join } from "node:path";
import { QUARANTINE_DIR, appendChallengeEvents, enqueueMemoryAnnouncement, ensureDirExists, v1MemoryPathKeyResolver, lineageContributionsOfSession, lockedStrictUpdate, markSessionPolluted, readProjectionDebts, readSessionPollution, readStrictSidecar, ControlPlaneCorruptError } from "./layout.js";
import { thrownText } from "../thrown-value.js";
export const DELEGATION_SETTLEMENT_FILE = "delegation-settlement.json";
function reqStr(v) {
return typeof v === "string" && v.length > 0;
}
function safeBasename(v) {
return typeof v === "string" && v.length > 0 && !v.includes("/") && !v.includes("\\") && v !== "." && v !== "..";
}
function safeRelPath(v) {
if (typeof v !== "string" || v.length === 0 || v.startsWith("/") || v.startsWith("\\") || /^[A-Za-z]:/.test(v))
return false;
return v.split(/[\/\\]/).every((seg) => seg.length > 0 && seg !== "." && seg !== "..");
}
const SETTLEMENT_EVENT_STATUSES = new Set(["clean", "external", "expired", "void", "unattestable"]);
function coerceSettlement(raw) {
if (raw === undefined)
return { version: 1, rows: [], events: [], effects: {} };
const rec = raw;
if (typeof rec !== "object" || rec === null || !Array.isArray(rec.rows) || !Array.isArray(rec.events) || typeof rec.effects !== "object" || rec.effects === null || Array.isArray(rec.effects)) {
throw new ControlPlaneCorruptError("memory delegation-settlement ledger has the wrong shape");
}
if (rec.version !== 1)
throw new ControlPlaneCorruptError(`memory delegation-settlement ledger has an unrecognized version (${String(rec.version)}) — refusing (fail-closed)`);
for (const r of rec.rows) {
const row = r;
if (typeof row !== "object" || row === null || !reqStr(row.settleId) || !reqStr(row.sessionId) || typeof row.launchedAt !== "number" || !Number.isFinite(row.launchedAt) || (row.lane !== "background" && row.lane !== "sync") || (row.status !== "pending" && row.status !== "unattestable") || (row.toolUseId !== undefined && !reqStr(row.toolUseId))) {
throw new ControlPlaneCorruptError("memory delegation-settlement ledger: a row is malformed (unknown status/lane, missing id, or a non-finite timestamp) — refusing (fail-closed; an unevaluable row must not fold as clean)");
}
}
for (const e of rec.events) {
const ev = e;
const kindOk = ev?.kind === "settle" || ev?.kind === "admin-resolve" || ev?.kind === "annotation";
const statusOk = ev?.status === undefined || SETTLEMENT_EVENT_STATUSES.has(ev.status);
if (typeof ev !== "object" || ev === null || !reqStr(ev.settleId) || !reqStr(ev.eventId) || typeof ev.at !== "number" || !Number.isFinite(ev.at) || !kindOk || !statusOk || (ev.kind === "settle" && ev.status === undefined) || (ev.kind === "admin-resolve" && (ev.status === undefined || !reqStr(ev.requestId)))) {
throw new ControlPlaneCorruptError("memory delegation-settlement ledger: an event is malformed (unknown kind/status, missing ids, an unattributed admin ruling, or a non-finite timestamp) — refusing (fail-closed)");
}
}
for (const [k, v] of Object.entries(rec.effects)) {
if (!reqStr(k) || !reqStr(v))
throw new ControlPlaneCorruptError("memory delegation-settlement ledger: an effects watermark entry is malformed — refusing (fail-closed)");
}
return rec;
}
export function syncSettleId(sessionId, toolCallId) {
return `sync:${encodeURIComponent(sessionId)}:${encodeURIComponent(toolCallId)}`;
}
export function registerDelegationLaunch(controlDir, input) {
lockedStrictUpdate(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger", coerceSettlement, (rec) => {
if (rec.rows.some((r) => r.settleId === input.settleId))
return { result: undefined };
rec.rows.push({ settleId: input.settleId, sessionId: input.sessionId, launchedAt: input.now(), lane: "background", status: "pending", ...(input.toolUseId !== undefined ? { toolUseId: input.toolUseId } : {}) });
return { next: rec, result: undefined };
});
}
export function recordSyncUnattestable(controlDir, input) {
const settleId = syncSettleId(input.sessionId, input.toolCallId);
lockedStrictUpdate(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger", coerceSettlement, (rec) => {
if (rec.rows.some((r) => r.settleId === settleId))
return { result: undefined };
rec.rows.push({ settleId, sessionId: input.sessionId, launchedAt: input.now(), lane: "sync", status: "unattestable" });
return { next: rec, result: undefined };
});
}
export function settleDelegation(controlDir, input) {
const eventId = input.eventId ?? `settle:${input.settleId}:${input.status}`;
lockedStrictUpdate(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger", coerceSettlement, (rec) => {
if (rec.events.some((e) => e.eventId === eventId))
return { result: undefined };
rec.events.push({ settleId: input.settleId, eventId, at: input.now(), kind: "settle", status: input.status, ...(input.note !== undefined ? { note: input.note } : {}) });
return { next: rec, result: undefined };
});
}
export function resolveSettlementRecord(controlDir, input) {
if (typeof input.requestId !== "string" || input.requestId.length === 0) {
const e = new Error("resolveSettlement requires a non-empty requestId (the audit attribution of who resolved) — refused, never defaulted.");
e.code = "memory.settlement_resolve_unattributed";
throw e;
}
if (input.to !== "clean" && input.to !== "external") {
const e = new Error(`resolveSettlement verdict must be "clean" or "external" (got ${JSON.stringify(input.to)}) — refused loudly, never folded.`);
e.code = "memory.settlement_resolve_invalid";
throw e;
}
const eventId = `admin:${input.requestId}:${input.settleId}:${input.to}`;
lockedStrictUpdate(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger", coerceSettlement, (rec) => {
if (!rec.rows.some((r) => r.settleId === input.settleId)) {
const e = new Error(`resolveSettlement: unknown settleId ${JSON.stringify(input.settleId)}`);
e.code = "memory.settlement_resolve_unknown";
throw e;
}
if (rec.events.some((e2) => e2.eventId === eventId))
return { result: undefined };
rec.events.push({ settleId: input.settleId, eventId, at: input.now(), kind: "admin-resolve", status: input.to, requestId: input.requestId });
return { next: rec, result: undefined };
});
}
function foldOne(row, events) {
let effective = row.status;
let everExternal = false;
let terminalEventId;
let adminRuled = false;
for (const e of events) {
const s = e.status;
if (s === undefined)
continue;
if (e.kind === "settle") {
if (s === "external") {
everExternal = true;
if (effective !== "external" && (effective !== "clean" || adminRuled)) {
effective = "external";
terminalEventId = e.eventId;
}
}
else if (s === "clean" || s === "void") {
if (effective === "pending") {
effective = s;
terminalEventId = e.eventId;
}
}
else if (s === "expired" || s === "unattestable") {
if (effective === "pending") {
effective = s;
terminalEventId = e.eventId;
}
}
}
else if (e.kind === "admin-resolve") {
adminRuled = true;
if (s === "external") {
everExternal = true;
effective = "external";
terminalEventId = e.eventId;
}
else if (s === "clean") {
effective = "clean";
terminalEventId = e.eventId;
}
}
}
return { row, effective, everExternal, ...(terminalEventId !== undefined ? { terminalEventId } : {}) };
}
export function effectiveSettlements(controlDir) {
const rec = coerceSettlement(readStrictSidecar(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger"));
const bySettle = new Map();
for (const e of rec.events) {
const arr = bySettle.get(e.settleId);
if (arr === undefined)
bySettle.set(e.settleId, [e]);
else
arr.push(e);
}
return rec.rows.map((row) => foldOne(row, bySettle.get(row.settleId) ?? []));
}
export function sessionSettlements(controlDir, sessionId) {
return effectiveSettlements(controlDir).filter((s) => s.row.sessionId === sessionId);
}
export function classifySessionSettlements(rows) {
let sawPending = false;
let exposedCause;
let reason;
for (const s of rows) {
if (s.effective === "external") {
exposedCause = "observed";
reason = "a delegated child of this session settled with an observed external-content attestation";
break;
}
if (s.effective === "unattestable" || s.effective === "expired") {
if (exposedCause === undefined) {
exposedCause = "static";
reason = s.effective === "unattestable" ? "a delegation of this session delivered without a provable attestation (permanently unprovable is not clean)" : "a delegation of this session never settled inside its evidence window (expired unprovable is not clean)";
}
continue;
}
if (s.effective === "pending")
sawPending = true;
}
if (exposedCause !== undefined)
return { state: "exposed", cause: exposedCause, ...(reason !== undefined ? { reason } : {}) };
if (sawPending)
return { state: "pending" };
return { state: "clean" };
}
export function expireOverdueSettlements(controlDir, input) {
const overdue = effectiveSettlements(controlDir).filter((s) => s.effective === "pending" && input.now() - s.row.launchedAt > input.timeoutMs);
for (const s of overdue)
settleDelegation(controlDir, { settleId: s.row.settleId, status: "expired", now: input.now });
return overdue.map((s) => s.row.settleId);
}
export function replayExternalSettlementEffects(controlDir, input) {
const applied = [];
const folded = effectiveSettlements(controlDir).filter((s) => s.effective === "external" && s.terminalEventId !== undefined);
if (folded.length === 0)
return applied;
const rec = coerceSettlement(readStrictSidecar(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger"));
for (const s of folded) {
if (rec.effects[s.row.settleId] === s.terminalEventId)
continue;
const sessionId = s.row.sessionId;
const outcome = markSessionPolluted(controlDir, sessionId, "a delegated child of this session settled external after launch (delegation settlement account)", input.now, "observed");
if (outcome === "unpersisted")
continue;
try {
const swept = lineageContributionsOfSession(controlDir, sessionId);
const contributions = input.carry ? swept.filter((c) => c.marked !== true) : swept;
appendChallengeEvents(controlDir, contributions.map((c) => ({
eventId: `settlement:${s.row.settleId}:${s.terminalEventId}:${c.entryId}`,
entryId: c.entryId,
reason: "challenged: the contributing session's delegation settled external",
challengedRev: c.lastRev,
})), input.now);
}
catch {
continue;
}
try {
enqueueMemoryAnnouncement(controlDir, {
kind: "gate",
at: input.now(),
items: [`delegation settlement: a background delegation of session ${JSON.stringify(sessionId)} settled EXTERNAL after launch — the session is marked and its unmarked committed contributions are challenged`],
});
}
catch {
}
lockedStrictUpdate(controlDir, DELEGATION_SETTLEMENT_FILE, "memory delegation-settlement ledger", coerceSettlement, (r) => {
r.effects[s.row.settleId] = s.terminalEventId;
return { next: r, result: undefined };
});
applied.push({ settleId: s.row.settleId, sessionId });
}
return applied;
}
export const SESSION_ACCOUNTS_FILE = "session-accounts.json";
function malformedAccountRow(row) {
return (typeof row !== "object" ||
row === null ||
!reqStr(row.sessionId) ||
typeof row.openedAt !== "number" ||
!Number.isFinite(row.openedAt) ||
!Array.isArray(row.unattributed) ||
(row.closedAt !== undefined && (typeof row.closedAt !== "number" || !Number.isFinite(row.closedAt))) ||
(row.terminatedAt !== undefined && (typeof row.terminatedAt !== "number" || !Number.isFinite(row.terminatedAt))) ||
(row.leg !== undefined && !reqStr(row.leg)) ||
(row.unadjudicated !== undefined && row.unadjudicated !== true));
}
function isUnattributedMember(x) {
return typeof x === "object" && x !== null && reqStr(x.scope) && safeRelPath(x.rel);
}
function coerceSessionAccounts(raw) {
if (raw === undefined)
return { version: 2, rows: [] };
const rec = raw;
if (typeof rec !== "object" || rec === null || !Array.isArray(rec.rows))
throw new ControlPlaneCorruptError("memory session-account ledger has the wrong shape");
if (rec.version !== 1 && rec.version !== 2)
throw new ControlPlaneCorruptError(`memory session-account ledger has an unrecognized version (${String(rec.version)}) — refusing (fail-closed)`);
const bad = () => {
throw new ControlPlaneCorruptError("memory session-account ledger: a row is malformed — refusing (fail-closed; an unevaluable row must not read as adjudicated)");
};
const rows = rec.rows;
for (const r of rows) {
const row = r;
if (malformedAccountRow(row))
bad();
const members = Array.isArray(row.unattributed) ? row.unattributed : bad();
if (rec.version === 1) {
if (members.some((x) => typeof x !== "string"))
bad();
}
else {
if (!members.every(isUnattributedMember))
bad();
if (row.unattributable !== undefined && (!Array.isArray(row.unattributable) || row.unattributable.some((x) => typeof x !== "string")))
bad();
if (row.writeScope !== undefined && !reqStr(row.writeScope))
bad();
}
}
return rec.version === 1 ? { version: 1, rows: rows } : { version: 2, rows: rows };
}
function convertSessionAccounts(read, controlDir) {
if (read.version === 2)
return { rec: read, converted: false };
const resolve = v1MemoryPathKeyResolver(controlDir);
const rows = read.rows.map((r) => {
const unattributed = [];
const unattributable = [];
for (const relPath of r.unattributed) {
const key = resolve(relPath);
if (key === undefined)
unattributable.push(relPath);
else
unattributed.push(key);
}
return {
sessionId: r.sessionId,
openedAt: r.openedAt,
unattributed,
...(unattributable.length > 0 ? { unattributable } : {}),
...(r.closedAt !== undefined ? { closedAt: r.closedAt } : {}),
...(r.unadjudicated !== undefined ? { unadjudicated: r.unadjudicated } : {}),
};
});
return { rec: { version: 2, rows }, converted: true };
}
export function convertV1SidecarKeys(controlDir) {
readProjectionDebts(controlDir);
readHolds(controlDir);
readSessionAccountsConverted(controlDir);
}
function readSessionAccountsConverted(controlDir) {
const read = coerceSessionAccounts(readStrictSidecar(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger"));
if (read.version === 2)
return read;
return lockedStrictUpdate(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger", coerceSessionAccounts, (again) => {
const { rec, converted } = convertSessionAccounts(again, controlDir);
return converted ? { next: rec, result: rec } : { result: rec };
});
}
export function foreignDanglingSessionAccounts(controlDir, selfSessionId) {
const rec = readSessionAccountsConverted(controlDir);
return rec.rows.filter((r) => r.sessionId !== selfSessionId && (r.closedAt === undefined || r.unadjudicated === true));
}
export function openLayerWriters(controlDir, selfLeg) {
const open = readSessionAccountsConverted(controlDir).rows.filter((r) => (selfLeg === undefined || r.leg !== selfLeg) && (r.writeScope !== undefined ? r.terminatedAt === undefined : r.closedAt === undefined));
return { scopes: new Set(open.flatMap((r) => (r.writeScope !== undefined ? [r.writeScope] : []))), unscoped: open.filter((r) => r.writeScope === undefined).length };
}
export function sessionAccountLeg(controlDir, sessionId) {
return readSessionAccountsConverted(controlDir).rows.find((r) => r.sessionId === sessionId)?.leg;
}
export function sessionAccountWriteHome(controlDir, sessionId) {
const read = coerceSessionAccounts(readStrictSidecar(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger"));
if (read.version !== 2)
return undefined;
const row = read.rows.find((r) => r.sessionId === sessionId);
return row?.writeScope === undefined ? undefined : { writeScope: row.writeScope, openedAt: row.openedAt };
}
export function emptyUnattributedSet() {
return { has: () => false, empty: true };
}
function memberKey(scope, rel) {
return JSON.stringify([scope, rel]);
}
export function openSessionAccount(controlDir, input) {
lockedStrictUpdate(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger", coerceSessionAccounts, (read) => {
const { rec } = convertSessionAccounts(read, controlDir);
const row = rec.rows.find((r) => r.sessionId === input.sessionId);
if (row !== undefined && input.writeScope !== undefined)
row.writeScope = input.writeScope;
if (row !== undefined) {
delete row.terminatedAt;
if (input.leg !== undefined)
row.leg = input.leg;
else
delete row.leg;
}
if (row === undefined) {
rec.rows.push({ sessionId: input.sessionId, openedAt: input.now(), ...(input.writeScope !== undefined ? { writeScope: input.writeScope } : {}), ...(input.leg !== undefined ? { leg: input.leg } : {}), unattributed: [...input.unattributed] });
}
else if (row.closedAt !== undefined && row.unadjudicated === undefined) {
row.openedAt = input.now();
delete row.closedAt;
row.unattributed = [...input.unattributed];
}
else {
row.openedAt = input.now();
delete row.closedAt;
delete row.unadjudicated;
const merged = new Map(row.unattributed.map((m) => [memberKey(m.scope, m.rel), m]));
for (const m of input.unattributed)
merged.set(memberKey(m.scope, m.rel), { scope: m.scope, rel: m.rel });
row.unattributed = [...merged.values()];
}
return { next: rec, result: undefined };
});
}
export function sessionUnattributedSet(controlDir, sessionId) {
const row = readSessionAccountsConverted(controlDir).rows.find((r) => r.sessionId === sessionId);
if (row === undefined)
return emptyUnattributedSet();
const all = (row.unattributable?.length ?? 0) > 0;
const keys = new Set(row.unattributed.map((m) => memberKey(m.scope, m.rel)));
return { has: (scope, rel) => all || keys.has(memberKey(scope, rel.split("\\").join("/"))), empty: !all && keys.size === 0 };
}
export function closeSessionAccount(controlDir, input) {
return lockedStrictUpdate(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger", coerceSessionAccounts, (read) => {
const { rec } = convertSessionAccounts(read, controlDir);
const row = rec.rows.find((r) => r.sessionId === input.sessionId);
if (row === undefined)
return { result: "absent" };
if (input.leg !== undefined && row.leg !== input.leg)
return { result: "stale" };
row.closedAt = input.now();
delete row.unadjudicated;
for (const r of rec.rows)
delete r.unadjudicated;
return { next: rec, result: "written" };
});
}
export function terminateSessionAccount(controlDir, input) {
return lockedStrictUpdate(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger", coerceSessionAccounts, (read) => {
const { rec } = convertSessionAccounts(read, controlDir);
const row = rec.rows.find((r) => r.sessionId === input.sessionId);
if (row === undefined)
return { result: "absent" };
if (input.leg !== undefined && row.leg !== input.leg)
return { result: "stale" };
row.terminatedAt = input.now();
return { next: rec, result: "written" };
});
}
export function resolveSessionAccountRecord(controlDir, input) {
if (typeof input.requestId !== "string" || input.requestId.length === 0) {
const e = new Error("resolveSessionAccount requires a non-empty requestId (the audit attribution of who closed) — refused, never defaulted.");
e.code = "memory.session_account_resolve_unattributed";
throw e;
}
lockedStrictUpdate(controlDir, SESSION_ACCOUNTS_FILE, "memory session-account ledger", coerceSessionAccounts, (read) => {
const { rec } = convertSessionAccounts(read, controlDir);
const row = rec.rows.find((r) => r.sessionId === input.sessionId);
if (row === undefined) {
const e = new Error(`resolveSessionAccount: unknown sessionId ${JSON.stringify(input.sessionId)}`);
e.code = "memory.session_account_resolve_unknown";
throw e;
}
row.closedAt = input.now();
row.unadjudicated = true;
row.terminatedAt = row.closedAt;
return { next: rec, result: undefined };
});
}
export const HOLDS_FILE = "holds.json";
export const HOLD_DIR = "hold";
const HOLD_STATUSES = new Set(["capturing", "held", "released", "disposed"]);
const HOLD_TERMINALS = new Set(["dirty", "expired", "conflict", "discarded", "capture_lost"]);
function coerceHolds(raw) {
if (raw === undefined)
return { version: 2, rows: [] };
const rec = raw;
if (typeof rec !== "object" || rec === null || !Array.isArray(rec.rows))
throw new ControlPlaneCorruptError("memory instruction-hold ledger has the wrong shape");
if (rec.version !== 1 && rec.version !== 2)
throw new ControlPlaneCorruptError(`memory instruction-hold ledger has an unrecognized version (${String(rec.version)}) — refusing (fail-closed)`);
const v1 = rec.version === 1;
const rows = [];
const raws = rec.rows;
for (const r of raws) {
const row = r;
if (typeof row !== "object" ||
row === null ||
!reqStr(row.holdId) ||
!reqStr(row.sessionId) ||
(row.op !== "add" && row.op !== "update") ||
!safeRelPath(row.slug) ||
!reqStr(row.scope) ||
!reqStr(row.captureName) ||
!reqStr(row.contentDigest) ||
typeof row.capturedAt !== "number" ||
!Number.isFinite(row.capturedAt) ||
!Array.isArray(row.settleIds) ||
row.settleIds.some((x) => typeof x !== "string") ||
!HOLD_STATUSES.has(row.status) ||
(row.disposition !== undefined && (typeof row.disposition !== "object" || row.disposition === null || !HOLD_TERMINALS.has(row.disposition.terminal) || (row.disposition.quarantineName !== undefined && !safeBasename(row.disposition.quarantineName)))) ||
(row.resolved !== undefined && row.resolved !== "release" && row.resolved !== "discard") ||
(row.resolvedAt !== undefined && (typeof row.resolvedAt !== "number" || !Number.isSafeInteger(row.resolvedAt) || row.resolvedAt < 0 || row.resolvedAt >= 2 ** 50 || row.resolved === undefined)) ||
(row.entryId !== undefined && typeof row.entryId !== "string") ||
(row.baseRev !== undefined && typeof row.baseRev !== "string") ||
(row.op === "update" && (!reqStr(row.entryId) || !reqStr(row.baseRev))) ||
(v1 ? !safeRelPath(row.relPath) : !safeRelPath(row.rel)) ||
!safeBasename(row.captureName)) {
throw new ControlPlaneCorruptError("memory instruction-hold ledger: a row is malformed — refusing (fail-closed; an unevaluable hold must not read as settled)");
}
if (v1) {
const { relPath: _relPath, ...rest } = row;
rows.push({ ...rest, rel: `${row.slug}.md` });
}
else {
rows.push(row);
}
}
return { version: 2, rows };
}
function holdsOnDiskAreV1(raw) {
return typeof raw === "object" && raw !== null && raw.version === 1;
}
export function readHolds(controlDir) {
const raw = readStrictSidecar(controlDir, HOLDS_FILE, "memory instruction-hold ledger");
if (!holdsOnDiskAreV1(raw))
return coerceHolds(raw).rows;
return lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (again) => ({ next: again, result: again.rows }));
}
function sha256(buf) {
return createHash("sha256").update(buf).digest("hex");
}
let stagingSeq = 0;
function uniqueStagingName(holdId, now) {
stagingSeq += 1;
return `${holdId}.staging-${now()}-${process.pid}-${stagingSeq}`;
}
function stagingGenerationPattern(holdId) {
return new RegExp(`^${holdId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.staging-\\d+-\\d+-\\d+(?:\\.claim-\\d+-\\d+)*$`);
}
function claimStaging(stagingPath) {
stagingSeq += 1;
const claimed = `${stagingPath}.claim-${process.pid}-${stagingSeq}`;
try {
renameSync(stagingPath, claimed);
return claimed;
}
catch {
return stagingPath;
}
}
function dropStaging(claimedPath) {
try {
unlinkSync(claimedPath);
}
catch {
}
}
export function stagingPathBeside(absPath, stagingName) {
return join(dirname(absPath), stagingName);
}
function writeCustodyVerified(dest, bytes) {
try {
const fd = openSync(dest, "wx", 0o600);
try {
writeFileSync(fd, bytes);
fsyncSync(fd);
}
finally {
closeSync(fd);
}
return sha256(readFileSync(dest)) === sha256(bytes);
}
catch {
return false;
}
}
export function retireStagingToCustody(claimedPath, custodyDir, stagingName) {
const unsettled = (why) => ({ settled: false, at: `${claimedPath} (${why})` });
let bytes;
try {
bytes = readFileSync(claimedPath);
ensureDirExists(custodyDir);
}
catch {
return unsettled("the staged bytes could not be read into the control plane");
}
if (!writeCustodyVerified(join(custodyDir, stagingName), bytes))
return unsettled("the control-plane custody copy could not be written");
try {
unlinkSync(claimedPath);
}
catch {
return unsettled("a copy reached the control plane; this one could not be removed");
}
return { settled: true, at: `${basename(custodyDir)}/${stagingName} in the memory control plane` };
}
export function noReplaceRestore(stagingPath, destPath) {
try {
linkSync(stagingPath, destPath);
}
catch (err) {
if (err.code !== "EEXIST") {
try {
writeFileSync(destPath, readFileSync(stagingPath), { flag: "wx" });
}
catch (err2) {
return err2.code === "EEXIST" ? "kept" : "stranded";
}
try {
unlinkSync(stagingPath);
}
catch {
}
return "restored";
}
return "kept";
}
try {
unlinkSync(stagingPath);
}
catch {
}
return "restored";
}
export function openInstructionHold(controlDir, input) {
const holdId = `hold-${input.now()}-${createHash("sha256").update(`${input.sessionId}\n${input.rel}\n${input.content}`).digest("hex").slice(0, 12)}`;
const buf = Buffer.from(input.content, "utf8");
const digest = sha256(buf);
const captureName = `${holdId}.md`;
const holdDir = join(controlDir, HOLD_DIR);
let thirdWriterStrandedAt;
const refuse = (rawReason, terminal) => {
const reason = thirdWriterStrandedAt === undefined ? rawReason : `${rawReason}; a concurrent writer's bytes are preserved at ${thirdWriterStrandedAt}`;
try {
disposeHold(controlDir, { holdId, terminal, now: input.now });
}
catch {
}
return { ok: false, holdId, reason };
};
try {
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
if (rec.rows.some((r) => r.holdId === holdId))
return { result: undefined };
rec.rows.push({
holdId,
sessionId: input.sessionId,
...(input.entryId !== undefined ? { entryId: input.entryId } : {}),
op: input.op,
...(input.baseRev !== undefined ? { baseRev: input.baseRev } : {}),
rel: input.rel,
slug: input.slug,
scope: input.scope,
captureName,
contentDigest: digest,
capturedAt: input.now(),
settleIds: [...input.settleIds],
status: "capturing",
});
return { next: rec, result: undefined };
});
}
catch (err) {
return { ok: false, reason: `hold ledger refused: ${thrownText(err)}` };
}
try {
ensureDirExists(holdDir);
}
catch (err) {
return refuse(`hold capture failed: ${thrownText(err)}`, "capture_lost");
}
if (!writeCustodyVerified(join(holdDir, captureName), buf)) {
return refuse("hold capture verification failed (the custody copy could not be written, made durable, or hashed back to the captured digest)", "capture_lost");
}
const stagingName = uniqueStagingName(holdId, input.now);
const stagingPath = stagingPathBeside(input.absPath, stagingName);
try {
renameSync(input.absPath, stagingPath);
}
catch (err) {
const code = err.code;
if (code === "ENOENT") {
}
else {
return refuse(`hold removal failed (${code ?? "rename error"}): the plane file was not moved`, "discarded");
}
}
const claimedPath = existsSync(stagingPath) ? claimStaging(stagingPath) : stagingPath;
if (existsSync(claimedPath)) {
const moved = readFileSync(claimedPath);
if (sha256(moved) === digest) {
dropStaging(claimedPath);
}
else {
const restore = noReplaceRestore(claimedPath, input.absPath);
if (restore !== "restored") {
const retired = retireStagingToCustody(claimedPath, holdDir, stagingName);
if (restore === "stranded" || !retired.settled)
thirdWriterStrandedAt = retired.at;
}
}
}
try {
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const row = rec.rows.find((r) => r.holdId === holdId);
if (row === undefined || row.status !== "capturing")
return { result: undefined };
row.status = "held";
return { next: rec, result: undefined };
});
}
catch (err) {
return refuse(`hold ledger flip refused: ${thrownText(err)}`, "discarded");
}
return { ok: true, holdId, ...(thirdWriterStrandedAt !== undefined ? { thirdWriterStrandedAt } : {}) };
}
export function reconcileHolds(controlDir, input) {
const holdDir = join(controlDir, HOLD_DIR);
const discloseStranded = (holdId, rel, at) => {
try {
enqueueMemoryAnnouncement(controlDir, {
kind: "gate",
at: input.now(),
items: [`instruction hold ${holdId}: a concurrent writer's bytes for ${JSON.stringify(rel)} could not be restored onto the plane — they are preserved at ${at} for host recovery`],
});
}
catch {
console.warn(`[sema] instruction hold ${holdId}: concurrent-writer bytes preserved at ${at} could not be restored or announced`);
}
};
const finishRemoval = (row, plane) => {
const stagingName = uniqueStagingName(row.holdId, input.now);
renameSync(plane, stagingPathBeside(plane, stagingName));
const staging = claimStaging(stagingPathBeside(plane, stagingName));
if (sha256(readFileSync(staging)) === row.contentDigest) {
dropStaging(staging);
return;
}
const restore = noReplaceRestore(staging, plane);
if (restore === "restored")
return;
const retired = retireStagingToCustody(staging, holdDir, stagingName);
if (restore === "stranded" || !retired.settled)
discloseStranded(row.holdId, row.rel, retired.at);
};
const seatListing = new Map();
const listSeat = (seatDir) => {
const cached = seatListing.get(seatDir);
if (cached !== undefined)
return cached;
let names;
try {
names = readdirSync(seatDir);
}
catch {
names = [];
}
seatListing.set(seatDir, names);
return names;
};
const sweepStagingGenerations = (row, plane, custody) => {
const seatDir = dirname(plane);
const pattern = stagingGenerationPattern(row.holdId);
for (const name of listSeat(seatDir)) {
if (!pattern.test(name))
continue;
const staged = claimStaging(join(seatDir, name));
let bytes;
try {
if (!lstatSync(staged).isFile())
continue;
bytes = readFileSync(staged);
}
catch {
continue;
}
if (sha256(bytes) === row.contentDigest) {
if (custody === "holds" || (custody === "absent" && writeCustodyVerified(join(holdDir, row.captureName), bytes))) {
dropStaging(staged);
continue;
}
}
discloseStranded(row.holdId, row.rel, retireStagingToCustody(staged, holdDir, name).at);
}
};
const rows = readHolds(controlDir).filter((r) => r.status === "capturing");
for (const row of rows) {
const custody = join(holdDir, row.captureName);
let custodyBytes;
try {
custodyBytes = readFileSync(custody);
}
catch {
custodyBytes = undefined;
}
const custodyState = custodyBytes === undefined ? "absent" : sha256(custodyBytes) === row.contentDigest ? "holds" : "mismatch";
try {
sweepStagingGenerations(row, join(input.homeOf(row.scope), row.rel), custodyState);
}
catch {
}
let terminalLost = false;
if (existsSync(custody)) {
const bytes = custodyBytes ?? readFileSync(custody);
if (sha256(bytes) !== row.contentDigest) {
terminalLost = true;
}
else {
const plane = join(input.homeOf(row.scope), row.rel);
if (existsSync(plane)) {
try {
finishRemoval(row, plane);
}
catch {
}
}
}
}
else {
const plane = join(input.homeOf(row.scope), row.rel);
if (existsSync(plane)) {
const bytes = readFileSync(plane);
if (sha256(bytes) === row.contentDigest) {
try {
ensureDirExists(holdDir);
if (!writeCustodyVerified(custody, bytes))
throw new Error("the custody copy could not be written or made durable");
finishRemoval(row, plane);
}
catch {
terminalLost = true;
}
}
else {
terminalLost = true;
}
}
else {
terminalLost = true;
}
}
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const r = rec.rows.find((x) => x.holdId === row.holdId);
if (r === undefined || r.status !== "capturing")
return { result: undefined };
if (terminalLost) {
r.status = "disposed";
r.disposition = { terminal: "capture_lost" };
}
else {
r.status = "held";
}
return { next: rec, result: undefined };
});
}
}
export function disposeHold(controlDir, input) {
const rows = readHolds(controlDir);
const row = rows.find((r) => r.holdId === input.holdId);
if (row === undefined || row.status === "disposed" || row.status === "released")
return { ok: false };
const custody = join(controlDir, HOLD_DIR, row.captureName);
const quarantineName = `${input.now()}-hold-${row.captureName}`;
const qDir = join(controlDir, QUARANTINE_DIR);
let moved = false;
try {
ensureDirExists(qDir);
renameSync(custody, join(qDir, quarantineName));
moved = true;
}
catch {
moved = existsSync(join(qDir, quarantineName));
}
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const r = rec.rows.find((x) => x.holdId === input.holdId);
if (r === undefined || r.status === "disposed" || r.status === "released")
return { result: undefined };
r.status = "disposed";
r.disposition = { terminal: input.terminal, ...(moved ? { quarantineName } : {}) };
return { next: rec, result: undefined };
});
return { ok: true, ...(moved ? { quarantineName } : {}) };
}
export function markHoldReleased(controlDir, input) {
const captureName = lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const r = rec.rows.find((x) => x.holdId === input.holdId);
if (r === undefined || (r.status !== "held" && !(r.status === "disposed" && r.disposition?.terminal === "expired")))
return { result: undefined };
r.status = "released";
delete r.resolved;
delete r.resolvedAt;
return { next: rec, result: r.captureName };
});
if (captureName === undefined)
return;
try {
unlinkSync(join(controlDir, HOLD_DIR, captureName));
}
catch {
}
}
export function resolveHoldRecord(controlDir, input) {
if (typeof input.requestId !== "string" || input.requestId.length === 0) {
const e = new Error("resolveHold requires a non-empty requestId (the audit attribution of who resolved) — refused, never defaulted.");
e.code = "memory.hold_resolve_unattributed";
throw e;
}
if (input.action !== "release" && input.action !== "discard") {
const e = new Error(`resolveHold action must be "release" or "discard" (got ${JSON.stringify(input.action)}) — refused loudly, never folded.`);
e.code = "memory.hold_resolve_invalid";
throw e;
}
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const r = rec.rows.find((x) => x.holdId === input.holdId);
if (r === undefined) {
const e = new Error(`resolveHold: unknown holdId ${JSON.stringify(input.holdId)}`);
e.code = "memory.hold_resolve_unknown";
throw e;
}
if (r.status !== "held" && !(r.status === "disposed" && r.disposition?.terminal === "expired" && input.action === "release")) {
const e = new Error(`resolveHold: hold ${JSON.stringify(input.holdId)} is ${r.status}${r.disposition !== undefined ? ` (${r.disposition.terminal})` : ""} — only a held row, or an expired disposition (release), can be resolved`);
e.code = "memory.hold_resolve_invalid_state";
throw e;
}
r.resolved = input.action;
const nextGeneration = Math.max(input.now(), 0, (r.resolvedAt ?? 0) + 1);
if (!Number.isSafeInteger(nextGeneration) || nextGeneration < 0 || nextGeneration >= 2 ** 50) {
const e = new Error(`resolveHold: hold ${JSON.stringify(input.holdId)} cannot mint a fresh verdict generation (${String(nextGeneration)} — an exhausted window, a deranged clock, or a corrupt ledger row) — refused, never written.`);
e.code = "memory.hold_resolve_invalid_state";
throw e;
}
r.resolvedAt = nextGeneration;
return { next: rec, result: undefined };
});
}
export function clearHoldResolution(controlDir, input) {
lockedStrictUpdate(controlDir, HOLDS_FILE, "memory instruction-hold ledger", coerceHolds, (rec) => {
const r = rec.rows.find((x) => x.holdId === input.holdId);
if (r === undefined || r.resolved === undefined || r.resolvedAt !== input.ifResolvedAt)
return { result: undefined };
delete r.resolved;
delete r.resolvedAt;
return { next: rec, result: undefined };
});
}
export function readHoldCustody(controlDir, row) {
const seats = [join(controlDir, HOLD_DIR, row.captureName), ...(row.disposition?.quarantineName !== undefined ? [join(controlDir, QUARANTINE_DIR, row.disposition.quarantineName)] : [])];
for (const seat of seats) {
try {
const bytes = readFileSync(seat);
if (sha256(bytes) === row.contentDigest)
return bytes.toString("utf8");
}
catch {
}
}
return undefined;
}
export function sessionBlocksCleanRelease(controlDir, sessionId) {
if (readSessionPollution(controlDir, sessionId) !== undefined)
return true;
return sessionSettlements(controlDir, sessionId).some((s) => s.effective !== "clean" && s.effective !== "void");
}