@sema-agent/core
Version:
Stateless, task-oriented AI agent core
843 lines • 58.4 kB
JavaScript
import { isAbsolute, sep } from "node:path";
import { deliverEngineNotice } from "../types.js";
import { admitMemoryScopes } from "../memory-admission.js";
import { adoptLegacyRepoDirs, canonicalize, deriveRepoControlPlaneDir, deriveProjectControlDir, deriveProjectMemoryDir, deriveRepoMemoryDir, drainMemoryAnnouncements, enqueueMemoryAnnouncement, isContainedIn, lookupProjectIdHint, recordProjectIdHint, resolveMemoryEngineRoot } from "../memory-engine/layout.js";
import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir, mergeHarvestReports, mergeInjections, needsDualRoots, parsedProjectPlane } from "../memory-engine/dual-root.js";
import { memoryProjectScopeAbsentNotice, normalizeMemorySpec } from "../memory.js";
import { deriveSupersededSet } from "../memory-engine/consolidation.js";
import { shadowNamesOf } from "../memory-engine/shadowing.js";
import { MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA, MEMORY_ANNOUNCEMENT_READONLY_CODA, MEMORY_CAPTURE_INDETERMINATE_NOTICE, MEMORY_CAPTURE_OPTOUT_NOTICE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, MemoryEngine, entryFileHeadCarriesOrigin, memoryCaptureOptedOutNotice, memoryCaptureOptOutUnpersistedNotice, memoryConsolidationRecommendedNotice, memoryHarvestQuarantinedNotice, memoryHoldNotices, memoryRecallDisciplineSegment, memoryRestoreWithheldNotice, memorySessionPollutedNotice, pollutionContainmentCounts, } from "../memory-engine/engine.js";
import { adjudicateCaptureOptOut, captureOptOutDeniedError, captureOptOutUnpersistedError } from "./memory-capture-optout.js";
import { readSessionCaptureOptOut } from "../memory-engine/layout.js";
import { createMemoryEngineTools } from "../memory-engine/tools.js";
import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
import { writableRootOf } from "../memory-engine/types.js";
import { asThrownError, thrownText } from "../thrown-value.js";
let undeclaredCapturePostureAnnounced = false;
export async function prepareMemory(input) {
const { spec, deps, sessionId, taskRootPath, admissionCtx } = input;
let memoryWriteGate;
const memorySpec = normalizeMemorySpec(spec.memory);
let admittedOrgScopes = [];
let ownOrgVerdict;
const deploymentScopeSet = new Set(deps.deploymentMemoryScopes ?? []);
const scopeOriginsSnapshot = memorySpec?.scopeOrigins !== undefined ? { ...memorySpec.scopeOrigins } : undefined;
if (memorySpec && scopeOriginsSnapshot !== undefined)
memorySpec.scopeOrigins = scopeOriginsSnapshot;
if (memorySpec && memorySpec.enabled && deps.memoryBackend) {
const outcome = await admitMemoryScopes({
memorySpec,
principal: spec.principal,
admission: deps.memoryScopeAdmission,
deploymentScopes: deploymentScopeSet,
orgMemoryDenied: admissionCtx.orgMemoryDenied,
complianceDegraded: admissionCtx.complianceDegraded,
parentAdmittedOrgScopes: admissionCtx.parentAdmittedOrgScopes,
priorOwnVerdict: admissionCtx.priorOwnVerdict,
governedProvenance: admissionCtx.governedProvenance,
});
admittedOrgScopes = outcome.admittedOrgScopes;
ownOrgVerdict = outcome.ownVerdict;
for (const droppedScope of outcome.droppedDeploymentScopes) {
deps.onError?.(new Error(`org memory scope "${droppedScope}" (deployment-declared) was narrowed away (admission resolver or the session's frozen verdict) — the layer is not mounted this session.`), { phase: "memory", sessionId });
}
if (outcome.writeScopeNarrowed) {
deps.onError?.(new Error(`org memory writeScope "${String(memorySpec.writeScope)}" was not explicitly granted by admission — the session's memory write face is read-only (org layers default read-only).`), { phase: "memory", sessionId });
}
memorySpec.scopes = outcome.scopes;
memorySpec.writeScope = outcome.writeScope;
}
if (memorySpec?.enabled === true && memorySpec.projectKey?.absent !== undefined) {
deliverEngineNotice(deps.onNotice, memoryProjectScopeAbsentNotice({ reason: memorySpec.projectKey.absent, taskRoot: taskRootPath, sessionId, writeScope: memorySpec.writeScope }));
}
const useMemoryEngine = Boolean(memorySpec && memorySpec.enabled && deps.memoryBackend);
const capturePosture = input.memoryCapturePolicy ?? "open";
const captureEntitlement = input.captureEntitlement ?? { value: undefined, faulted: false };
const captureDeclaredRaw = memorySpec?.capture === "off";
if (captureDeclaredRaw && memorySpec !== undefined && !memorySpec.enabled) {
deps.onError?.(new Error(`memory.capture:"off" appears beside memory.enabled:false — not a contradiction (memory is off entirely, so nothing is captured either way); the opt-out declaration is covered by enabled:false this run.`), { phase: "config", sessionId });
}
const captureDeclared = captureDeclaredRaw && useMemoryEngine;
const captureFloored = input.captureFloor === true && useMemoryEngine;
if (captureDeclared && !captureFloored) {
const verdict = adjudicateCaptureOptOut({ posture: capturePosture, entitlement: captureEntitlement, subject: "declaration" });
if (!verdict.allowed)
throw captureOptOutDeniedError(verdict.detail);
if (verdict.faultDisclosure !== undefined) {
deps.onError?.(new Error(verdict.faultDisclosure), { phase: "config", sessionId });
}
if (input.captureCarrierUnsupported === true) {
const e = new Error(`memory.capture:"off" cannot be honored on this deployment shape: the execution environment is remote/per-run ` +
`and no RunnerDeps.memoryCaptureRecordStore is supplied, so core cannot know the control plane survives to a ` +
`resume replica — a privacy promise that silently expires at the first resume is refused rather than made. A ` +
`deployment whose control plane IS durable (a single persistent host using a remote sandbox) opts back in by ` +
`supplying the store explicitly — fileSessionCaptureRecordStore(controlDir) is that one-line declaration.`);
e.code = "config.memory_capture_unsupported";
throw e;
}
}
let captureOptedOut = false;
let captureIndeterminate = false;
let captureLineageIndeterminate = false;
let memoryEngineSession;
const openedLegs = [];
let memoryTools;
let writeChannelOpen = false;
let memoryMarkedEntriesServed = false;
let effectiveMemoryScopes;
const originOf = (scope) => scopeOriginsSnapshot !== undefined
? scopeOriginsSnapshot[scope] === "deployment"
? "deployment"
: "request"
: deploymentScopeSet.has(scope)
? "deployment"
: "request";
const materializedResidue = [];
if (useMemoryEngine && memorySpec) {
try {
const backend = deps.memoryBackend;
const pinned = backend.directoryRoot;
const engineRoot = resolveMemoryEngineRoot(deps.memoryEngineDir);
const repoRoot = deps.rootPath ?? taskRootPath;
if (repoRoot) {
adoptLegacyRepoDirs(engineRoot, repoRoot, (err) => deps.onError?.(err, { phase: "memory", sessionId }));
}
let identityKey;
if (memorySpec.scopeContract === "v2" && repoRoot) {
const consumesProjectIdentity = [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])]
.map(parseScopeKey)
.some((k) => k.kind === "proj" || k.kind === "userproj");
let marker = null;
try {
marker = resolveProjectId(repoRoot);
}
catch (err) {
if (consumesProjectIdentity)
throw err;
deps.onError?.(asThrownError(err), { phase: "config", sessionId });
}
if (marker) {
identityKey = marker.projectId;
const firstSwitch = lookupProjectIdHint(engineRoot, repoRoot) !== marker.projectId;
recordProjectIdHint(engineRoot, repoRoot, marker.projectId);
if (firstSwitch) {
try {
const oldCtl = deriveRepoControlPlaneDir(engineRoot, repoRoot);
const newCtl = deriveProjectControlDir(engineRoot, marker.projectId);
const drained = drainMemoryAnnouncements(oldCtl);
for (const ann of drained.queue)
enqueueMemoryAnnouncement(newCtl, ann);
}
catch {
}
}
if (memorySpec.writeScope !== null) {
const w = parseScopeKey(memorySpec.writeScope);
if ((w.kind === "proj" || w.kind === "userproj") && w.projectId !== marker.projectId) {
const e = new Error(`memory scope contract v2: writeScope ${memorySpec.writeScope} targets projectId ${w.projectId}, ` +
`but this checkout's marker (.sema/project) declares ${marker.projectId} — refusing a mis-addressed write.`);
e.code = "config.memory_project_identity";
throw e;
}
}
}
else {
const hint = lookupProjectIdHint(engineRoot, repoRoot);
if (hint !== undefined) {
deps.onError?.(new Error(`memory project marker missing but recoverable: ${repoRoot} previously carried projectId ${hint} ` +
`(.sema/project deleted?). Restore the marker to keep the identity-keyed memory mount; this session ` +
`falls back to the path-derived key.`), { phase: "config", sessionId });
}
}
}
const memoryDir = typeof pinned === "string" && pinned
? pinned
: identityKey !== undefined
? deriveProjectMemoryDir(engineRoot, identityKey)
: deriveRepoMemoryDir(engineRoot, repoRoot);
const planes = memorySpec.scopeContract === "v2" ? classifyScopePlanes(memorySpec.scopes, memorySpec.writeScope) : undefined;
const dual = planes !== undefined && needsDualRoots(planes);
const personalOnly = planes !== undefined && !dual && planes.project.length === 0 && planes.writePlane !== "project" && (planes.personal.length > 0 || planes.writePlane === "personal");
if (memorySpec.scopeContract === "v2" && !personalOnly) {
assertScopeContractPlacement({
parsedScopes: dual
? parsedProjectPlane(planes, memorySpec.writeScope)
: [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])].map(parseScopeKey),
memoryDir,
repoRoot,
});
}
const personalMemoryDir = derivePersonalMemoryDir(engineRoot);
const personalControlDir = derivePersonalControlDir(engineRoot);
const effectiveControlDir = (b, fallback) => {
const pinnedCtl = b.controlPlaneRoot;
return typeof pinnedCtl === "string" && pinnedCtl ? pinnedCtl : fallback;
};
const captureStoreOpt = (b, fallback) => deps.memoryCaptureRecordStore !== undefined ? { captureRecordStore: deps.memoryCaptureRecordStore({ controlDir: effectiveControlDir(b, fallback) }) } : {};
const choosePersonalBackend = () => typeof pinned === "string" && pinned ? new FileMemoryEngineBackend(personalMemoryDir, { controlDir: personalControlDir }) : backend;
const createPersonalEngine = (personalBackend) => {
return {
engine: new MemoryEngine({ backend: personalBackend, memoryDir: personalMemoryDir, controlDir: personalControlDir, onIncident: onEngineIncident, provenance: input.memoryProvenance, ...captureStoreOpt(personalBackend, personalControlDir), ...(deps.memorySessionIncarnation !== undefined ? { sessionIncarnation: deps.memorySessionIncarnation } : {}), ...(input.deps.memoryConsolidation !== undefined ? { consolidation: input.deps.memoryConsolidation } : {}) }),
backend: personalBackend,
};
};
const onEngineIncident = (err) => deps.onError?.(err, { phase: "memory", sessionId });
const adoptionRestricted = input.memoryPersistenceDeclared === false;
const armCaptureOptOut = async (eng) => {
const standingRead = await eng.sessionCaptureOptOutOrFault(sessionId);
if (standingRead.fault) {
captureIndeterminate = true;
deps.onError?.(new Error(`the capture opt-out record store is unreadable at prepare — this session's capture state is indeterminate, and every memory commit boundary (read-side adoption included) suppresses fail-closed until the store answers.`), { phase: "memory", sessionId });
}
if (input.captureLineageFault === true) {
const firstIndeterminate = !captureIndeterminate;
captureIndeterminate = true;
captureLineageIndeterminate = true;
if (firstIndeterminate) {
deps.onError?.(new Error(`this session's fork-lineage metadata is unreadable — whether it continues an opted-out source session cannot be established, so its capture state is indeterminate: every memory commit boundary (read-side adoption included) suppresses fail-closed; no opt-out record is minted from an unreadable state.`), { phase: "memory", sessionId });
}
}
const standing = standingRead.record;
let floored = captureFloored;
if (!floored && !captureDeclared && standing === undefined && input.captureFloorIndeterminate === true) {
const rows = new Map();
for (const row of input.captureAncestors ?? [])
rows.set(row.sessionId, row.controlDir);
if (input.parentSessionId !== undefined && !rows.has(input.parentSessionId))
rows.set(input.parentSessionId, input.parentCaptureQueryDir);
let anyFault = standingRead.fault;
let found = false;
for (const [ancestorId, ancestorDir] of rows) {
const samePlane = await eng.sessionCaptureOptOutOrFault(ancestorId);
if (samePlane.record !== undefined) {
found = true;
break;
}
if (samePlane.fault)
anyFault = true;
if (ancestorDir !== undefined && ancestorDir !== eng.controlPlaneDir) {
try {
const crossPlane = deps.memoryCaptureRecordStore !== undefined ? await deps.memoryCaptureRecordStore({ controlDir: ancestorDir }).read(ancestorId) : readSessionCaptureOptOut(ancestorDir, ancestorId);
if (crossPlane !== undefined) {
found = true;
break;
}
}
catch {
anyFault = true;
}
}
}
if (found)
floored = true;
else if (anyFault) {
if (!captureIndeterminate) {
captureIndeterminate = true;
deps.onError?.(new Error(`the spawning session's capture opt-out state was INDETERMINATE at spawn (its record store faulted) and the live re-query still cannot answer — this delegated session inherits the suppression: every memory commit boundary (read-side adoption included) suppresses fail-closed until the store answers; no opt-out record is minted from an unreadable state.`), { phase: "memory", sessionId });
}
}
}
let forkInherited = false;
if (!floored && !captureDeclared && standing === undefined && input.captureForkOrigin !== undefined) {
const src = await eng.sessionCaptureOptOutOrFault(input.captureForkOrigin);
if (src.record !== undefined)
forkInherited = true;
else if (src.fault && !captureIndeterminate) {
captureIndeterminate = true;
deps.onError?.(new Error(`this session is a FORK of session "${input.captureForkOrigin}" whose capture opt-out record store is unreadable — the fork's capture state is indeterminate (the copied transcript may be governed by a standing opt-out), so every memory commit boundary suppresses fail-closed until the store answers; no opt-out record is minted from an unreadable state.`), { phase: "memory", sessionId });
}
}
if (standing === undefined && !captureDeclared && !floored && !forkInherited)
return;
if (standing !== undefined && !captureDeclared && !floored && capturePosture !== "open") {
const verdict = adjudicateCaptureOptOut({ posture: capturePosture, entitlement: captureEntitlement, subject: "standing-record" });
if (!verdict.allowed)
throw captureOptOutDeniedError(verdict.detail);
}
if (standing === undefined) {
const outcome = await eng.markSessionCaptureOptOut(sessionId, captureDeclared ? `declared on TaskSpec.memory.capture` : forkInherited ? `inherited capture opt-out from the forked source session` : `inherited capture opt-out floor from the spawning session`);
if (outcome === "unpersisted") {
deliverEngineNotice(deps.onNotice, memoryCaptureOptOutUnpersistedNotice({ sessionId, ingress: "declaration" }));
throw captureOptOutUnpersistedError(sessionId, "declaration");
}
if (outcome === "created")
deliverEngineNotice(deps.onNotice, memoryCaptureOptedOutNotice({ sessionId, origin: captureDeclared ? "declaration" : forkInherited ? "fork-origin" : "delegation-floor" }));
}
else if (!captureDeclared) {
deliverEngineNotice(deps.onNotice, memoryCaptureOptedOutNotice({ sessionId, origin: "standing-record" }));
}
captureOptedOut = true;
if (input.memoryCapturePolicyDeclared !== true && !undeclaredCapturePostureAnnounced) {
undeclaredCapturePostureAnnounced = true;
deps.onError?.(new Error(`a session memory-capture opt-out was honored under the DEFAULT capture posture (no RunnerDeps.memoryCapturePolicy configured) — ` +
`the switch is now in use; declare "open", "governed" or "capture-required" to make the deployment's stance explicit.`), { phase: "config", sessionId });
}
};
const retrievalBackend = (b, planeRestricted) => planeRestricted
? (b.restrictedAdoptionView?.({ audit: false }) ??
b.retrievalView?.() ??
b)
: (b.retrievalView?.() ?? b);
const planeScopes = (scopes, write) => [...new Set([...scopes, ...(write !== null ? [write] : [])])];
const mountedScopeRows = (dual
? [
...planeScopes(planes.project, planes.writePlane === "project" ? memorySpec.writeScope : null),
...planeScopes(planes.personal, planes.writePlane === "personal" ? memorySpec.writeScope : null),
]
: planeScopes(memorySpec.scopes, memorySpec.writeScope)).map((scope) => ({ scope, origin: originOf(scope) }));
const pollutedOpts = (engine) => {
const rec = engine.sessionPollution(sessionId);
return rec !== undefined ? { polluted: { reason: rec.reason, ...(rec.cause !== undefined ? { cause: rec.cause } : {}) } } : {};
};
let writeEngine;
let writeHandle;
let readOnlyEngine;
let readOnlyHandle;
let injectFn;
let harvestBoth;
let toolPlanes;
const admitNothingOptsNow = async () => {
if (input.memoryPersistenceDeclared === false) {
return { admitNothing: { reason: "harvest admitted nothing: memory persistence is declared unavailable for this session (memoryPersistenceCapable: false)" } };
}
if (captureLineageIndeterminate) {
return { admitNothing: { reason: `harvest admitted nothing: this session's fork-lineage metadata is unreadable — whether it continues an opted-out source cannot be established, so commits are suppressed fail-closed` } };
}
const own = captureOptedOut ? { record: { at: 0, reason: "in-run state" }, fault: false } : await writeEngine.sessionCaptureOptOutOrFault(sessionId);
if (own.record !== undefined) {
return { admitNothing: { reason: `harvest admitted nothing: this session declared memory capture opt-out (memory.capture: "off")` } };
}
if (own.fault) {
return { admitNothing: { reason: `harvest admitted nothing: the capture opt-out record store is unreadable — the opt-out state is indeterminate and commits are suppressed fail-closed` } };
}
const ancestors = new Map();
for (const row of input.captureAncestors ?? [])
ancestors.set(row.sessionId, row.controlDir);
if (input.parentSessionId !== undefined && !ancestors.has(input.parentSessionId))
ancestors.set(input.parentSessionId, input.parentCaptureQueryDir);
if (input.captureForkOrigin !== undefined && !ancestors.has(input.captureForkOrigin))
ancestors.set(input.captureForkOrigin, undefined);
for (const [ancestorId, ancestorDir] of ancestors) {
const samePlane = await writeEngine.sessionCaptureOptOutOrFault(ancestorId);
let crossPlane;
if (ancestorDir !== undefined && ancestorDir !== writeEngine.controlPlaneDir) {
try {
crossPlane = deps.memoryCaptureRecordStore !== undefined ? await deps.memoryCaptureRecordStore({ controlDir: ancestorDir }).read(ancestorId) : readSessionCaptureOptOut(ancestorDir, ancestorId);
}
catch {
return { admitNothing: { reason: `harvest admitted nothing: a spawning session's capture record store is unreadable — the floor state is indeterminate and commits are suppressed fail-closed` } };
}
}
if (samePlane.record !== undefined || crossPlane !== undefined) {
return { admitNothing: { reason: `harvest admitted nothing: a spawning session declared memory capture opt-out — the opt-out is a delegation floor no descendant loosens`, cause: "capture_optout_inherited" } };
}
if (samePlane.fault) {
return { admitNothing: { reason: `harvest admitted nothing: the capture opt-out record store is unreadable while a spawning session's floor is in question — suppressed fail-closed` } };
}
}
return {};
};
if (dual) {
const personalBackendChosen = choosePersonalBackend();
{
const projCtl = effectiveControlDir(backend, identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveRepoControlPlaneDir(engineRoot, repoRoot));
const persCtl = effectiveControlDir(personalBackendChosen, personalControlDir);
const overlap = (a, b) => isContainedIn(a, b) || isContainedIn(b, a);
const refuse = (what, a, b) => {
const e = new Error(`memory dual-root configuration error: ${what} overlap (${canonicalize(a)} vs ${canonicalize(b)}) — the planes' data roots and control planes must all be disjoint.`);
e.code = "config.memory_dual_root_overlap";
throw e;
};
if (overlap(memoryDir, personalMemoryDir))
refuse("the project and personal memory roots", memoryDir, personalMemoryDir);
if (overlap(projCtl, persCtl))
refuse("the project and personal control planes", projCtl, persCtl);
for (const [ctlName, ctl] of [["project control plane", projCtl], ["personal control plane", persCtl]]) {
for (const [rootName, dataRoot] of [["project memory root", memoryDir], ["personal memory mount", personalMemoryDir]]) {
if (overlap(ctl, dataRoot))
refuse(`the ${ctlName} and the ${rootName}`, ctl, dataRoot);
}
}
}
const projectEngine = new MemoryEngine({
backend,
memoryDir,
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveRepoControlPlaneDir(engineRoot, repoRoot),
onIncident: onEngineIncident,
provenance: input.memoryProvenance,
...captureStoreOpt(backend, identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveRepoControlPlaneDir(engineRoot, repoRoot)), ...(deps.memorySessionIncarnation !== undefined ? { sessionIncarnation: deps.memorySessionIncarnation } : {}),
...(input.deps.memoryConsolidation !== undefined ? { consolidation: input.deps.memoryConsolidation } : {}),
});
const personal = createPersonalEngine(personalBackendChosen);
const personalEngine = personal.engine;
const p = planes;
await armCaptureOptOut(p.writePlane === "personal" ? personalEngine : projectEngine);
const writeIsPersonal = p.writePlane === "personal";
const mounts = [
{ engine: writeIsPersonal ? personalEngine : projectEngine, scopes: writeIsPersonal ? p.personal : p.project, write: p.writePlane === null ? null : memorySpec.writeScope },
{ engine: writeIsPersonal ? projectEngine : personalEngine, scopes: writeIsPersonal ? p.project : p.personal, write: null },
];
const mounted = [];
let shadowNames;
for (const m of mounts) {
const handle = await m.engine.materialize(m.scopes, m.write, {
adoptionRestricted: adoptionRestricted || captureOptedOut || captureIndeterminate,
sessionId,
...(m.write === null && shadowNames !== undefined && shadowNames.size > 0 ? { shadowNames } : {}),
});
openedLegs.push(() => void m.engine.endSessionLeg(handle, sessionId));
mounted.push(handle);
materializedResidue.push(...planeScopes(m.scopes, m.write));
if (m.write !== null) {
try {
const withheld = new Set(m.engine.readChallengeExclusions().keys());
const committed = await m.engine.listCommittedHeaders([m.write]);
const superseded = deriveSupersededSet(committed, { excluded: (id) => withheld.has(id) });
shadowNames = shadowNamesOf(committed, m.write, { excluded: (id) => withheld.has(id) || superseded.has(id) });
}
catch {
shadowNames = undefined;
}
}
}
const projectHandle = writeIsPersonal ? mounted[1] : mounted[0];
const personalHandle = writeIsPersonal ? mounted[0] : mounted[1];
memoryMarkedEntriesServed = projectHandle.markedEntriesPresent === true || personalHandle.markedEntriesPresent === true;
writeEngine = writeIsPersonal ? personalEngine : projectEngine;
writeHandle = writeIsPersonal ? personalHandle : projectHandle;
readOnlyEngine = writeIsPersonal ? projectEngine : personalEngine;
readOnlyHandle = writeIsPersonal ? projectHandle : personalHandle;
injectFn = () => mergeInjections(projectEngine.inject(projectHandle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark }), personalEngine.inject(personalHandle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark }));
toolPlanes = [
{
backend: retrievalBackend(backend, adoptionRestricted || captureOptedOut || captureIndeterminate || p.writePlane !== "project"),
scopes: planeScopes(p.project, p.writePlane === "project" ? memorySpec.writeScope : null),
recordRetrieved: (ids) => projectEngine.recordRetrieved(ids),
challengeExclusions: () => projectEngine.readChallengeExclusions(),
enginePlaneProvenance: projectEngine.provenanceMode,
committedHeaders: () => projectEngine.listCommittedHeaders(planeScopes(p.project, p.writePlane === "project" ? memorySpec.writeScope : null)),
},
{
backend: retrievalBackend(personal.backend, adoptionRestricted || captureOptedOut || captureIndeterminate || p.writePlane !== "personal"),
scopes: planeScopes(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null),
recordRetrieved: (ids) => personalEngine.recordRetrieved(ids),
challengeExclusions: () => personalEngine.readChallengeExclusions(),
enginePlaneProvenance: personalEngine.provenanceMode,
committedHeaders: () => personalEngine.listCommittedHeaders(planeScopes(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null)),
},
];
harvestBoth = async (phase) => {
const writeFirst = writeIsPersonal ? [personalEngine, personalHandle] : [projectEngine, projectHandle];
const readOther = writeIsPersonal ? [projectEngine, projectHandle] : [personalEngine, personalHandle];
const writeReport = await writeFirst[0].harvest(writeFirst[1], { ...pollutedOpts(writeFirst[0]), sessionId, ...(await admitNothingOptsNow()), phase });
let readReport;
let readFailure;
try {
readReport = await readOther[0].harvest(readOther[1]);
}
catch (err) {
readFailure = thrownText(err);
}
const merged = readReport !== undefined ? mergeHarvestReports(writeReport, readReport) : writeReport;
if (readFailure !== undefined)
merged.warnings.push(`read-plane harvest failed (write-plane yield committed): ${readFailure}`);
return merged;
};
}
else if (personalOnly) {
const personal = createPersonalEngine(choosePersonalBackend());
const personalEngine = personal.engine;
await armCaptureOptOut(personalEngine);
const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted: adoptionRestricted || captureOptedOut || captureIndeterminate, sessionId });
openedLegs.push(() => void personalEngine.endSessionLeg(handle, sessionId));
materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
memoryMarkedEntriesServed = handle.markedEntriesPresent === true;
writeEngine = personalEngine;
writeHandle = handle;
injectFn = () => personalEngine.inject(handle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark });
harvestBoth = async (phase) => personalEngine.harvest(handle, { ...pollutedOpts(personalEngine), sessionId, ...(await admitNothingOptsNow()), phase });
toolPlanes = [
{
backend: retrievalBackend(personal.backend, adoptionRestricted || captureOptedOut || captureIndeterminate || memorySpec.writeScope === null),
scopes: planeScopes(memorySpec.scopes, memorySpec.writeScope),
recordRetrieved: (ids) => personalEngine.recordRetrieved(ids),
challengeExclusions: () => personalEngine.readChallengeExclusions(),
enginePlaneProvenance: personalEngine.provenanceMode,
committedHeaders: () => personalEngine.listCommittedHeaders(planeScopes(memorySpec.scopes, memorySpec.writeScope)),
},
];
}
else {
const engine = new MemoryEngine({
backend,
memoryDir,
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveRepoControlPlaneDir(engineRoot, repoRoot),
onIncident: onEngineIncident,
provenance: input.memoryProvenance,
...captureStoreOpt(backend, identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveRepoControlPlaneDir(engineRoot, repoRoot)), ...(deps.memorySessionIncarnation !== undefined ? { sessionIncarnation: deps.memorySessionIncarnation } : {}),
...(input.deps.memoryConsolidation !== undefined ? { consolidation: input.deps.memoryConsolidation } : {}),
});
await armCaptureOptOut(engine);
const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted: adoptionRestricted || captureOptedOut || captureIndeterminate, sessionId });
openedLegs.push(() => void engine.endSessionLeg(handle, sessionId));
materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
memoryMarkedEntriesServed = handle.markedEntriesPresent === true;
writeEngine = engine;
writeHandle = handle;
injectFn = () => engine.inject(handle, { writeToolMounted: writeChannelOpen, reminderMark: input.reminderMark });
harvestBoth = async (phase) => engine.harvest(handle, { ...pollutedOpts(engine), sessionId, ...(await admitNothingOptsNow()), phase });
toolPlanes = [
{
backend: retrievalBackend(backend, adoptionRestricted || captureOptedOut || captureIndeterminate || memorySpec.writeScope === null),
scopes: planeScopes(memorySpec.scopes, memorySpec.writeScope),
recordRetrieved: (ids) => engine.recordRetrieved(ids),
challengeExclusions: () => engine.readChallengeExclusions(),
enginePlaneProvenance: engine.provenanceMode,
committedHeaders: () => engine.listCommittedHeaders(planeScopes(memorySpec.scopes, memorySpec.writeScope)),
},
];
}
for (const [scope, count] of [...(writeHandle.shadowedByScope ?? []), ...(readOnlyHandle?.shadowedByScope ?? [])]) {
if (count <= 0 || scope === memorySpec.writeScope)
continue;
const row = mountedScopeRows.find((r) => r.scope === scope);
if (row !== undefined)
row.shadowed = (row.shadowed ?? 0) + count;
}
const foreignUnderRoot = [];
if (input.writeToolsMounted && writeHandle.writeScope !== null && input.advertisedWritableDirs !== undefined) {
const controlPlane = canonicalize(writeEngine.controlPlaneDir);
if (isContainedIn(writableRootOf(writeHandle), controlPlane))
foreignUnderRoot.push(`the engine's control plane ${controlPlane}`);
}
if (foreignUnderRoot.length > 0) {
deps.onError?.(new Error(`memory advertised writable directory refused: the write scope's root ${writableRootOf(writeHandle)} contains what is not the model's to touch (${foreignUnderRoot.join("; ")}) — the file tools' root fence is directory-granular, so admitting it would expose those files; memory writes through the file tools stay closed this session and the write instruction is not taught.`), { phase: "config", sessionId });
}
writeChannelOpen =
input.writeToolsMounted &&
writeHandle.writeScope !== null &&
foreignUnderRoot.length === 0 &&
(input.advertisedWritableDirs === undefined || (await input.advertisedWritableDirs.admit({ path: writableRootOf(writeHandle), advertiser: "memory", expectCanonical: writableRootOf(writeHandle) })));
memoryWriteGate = async (w) => {
if (readOnlyEngine !== undefined && readOnlyHandle !== undefined) {
const ro = readOnlyEngine.gateWrite(readOnlyHandle, w.key, w.content);
if (!ro.ok)
return ro;
}
if (input.memoryPersistenceDeclared === false) {
const root = writeHandle.writableRoot;
if (root !== null && (w.key === root || w.key.startsWith(`${root}${sep}`))) {
return {
ok: false,
code: "read_only_layering",
reason: `memory persistence is declared unavailable for this session (memoryPersistenceCapable: false) — writes into the memory store are refused. Nothing was written.`,
muted: false,
};
}
}
{
const root = writeHandle.writableRoot;
if (root !== null && (w.key === root || w.key.startsWith(`${root}${sep}`))) {
const state = captureOptedOut ? { record: { at: 0, reason: "in-run state" }, fault: false } : await writeEngine.sessionCaptureOptOutOrFault(sessionId);
if (state.record !== undefined || state.fault) {
return {
ok: false,
code: "read_only_layering",
reason: state.record !== undefined
? `memory capture is off for this session at the user's request (memory.capture: "off") — writes into the memory store are refused. Nothing was written.`
: `the capture opt-out record store is unreadable, so this session's capture state is indeterminate — writes into the memory store are refused fail-closed. Nothing was written.`,
muted: false,
};
}
}
}
return writeEngine.gateWrite(writeHandle, w.key, w.content);
};
let pollutionAnnounced = false;
const announceHarvestContainment = (report) => {
const { count, moved, escalated } = pollutionContainmentCounts(report);
const indexOnly = input.memoryProvenance !== "off" && count === 0 && report.containment?.indexRolledBack === true;
if (count > 0 || indexOnly) {
let reason;
try {
reason = writeEngine.sessionPollution(sessionId)?.reason;
}
catch {
}
deliverEngineNotice(deps.onNotice, memoryHarvestQuarantinedNotice({ count, moved, escalated, ...(report.reportId !== undefined ? { reportId: report.reportId } : {}), ...(reason !== undefined ? { reason } : {}), sessionId, provenance: input.memoryProvenance, ...(indexOnly ? { indexRolledBack: true } : {}) }));
}
if (report.restoreWithheld !== undefined && report.restoreWithheld.length > 0) {
deliverEngineNotice(deps.onNotice, memoryRestoreWithheldNotice({ paths: report.restoreWithheld, sessionId }));
}
for (const notice of memoryHoldNotices(report, sessionId))
deliverEngineNotice(deps.onNotice, notice);
const consolidationNotice = memoryConsolidationRecommendedNotice(report, sessionId);
if (consolidationNotice !== undefined)
deliverEngineNotice(deps.onNotice, consolidationNotice);
};
const harvestSafe = async (phase = "terminal") => {
try {
const report = await harvestBoth(phase);
if (!report.ok && report.incident) {
const named = report.reportId !== undefined ? `${report.incident.kind}, report ${report.reportId}` : report.incident.kind;
deps.onError?.(new Error(`memory harvest refused (${named}): ${report.incident.detail}`), { phase: "memory", sessionId });
}
announceHarvestContainment(report);
try {
deps.onMemoryHarvestReport?.(report, { sessionId, phase });
}
catch {
}
return report;
}
catch (err) {
try {
deps.onError?.(asThrownError(err), { phase: "memory", sessionId });
}
catch {
}
return undefined;
}
};
const resolveCaptureEntitlementFresh = async () => {
if (deps.runtimeCapsResolver === undefined)
return { value: undefined, faulted: false };
try {
const caps = (await deps.runtimeCapsResolver(spec.principal)) ?? undefined;
const v = caps?.allowMemoryOptOut;
if (v !== undefined && typeof v !== "boolean")
return { value: undefined, faulted: true };
return { value: v, faulted: false };
}
catch {
return { value: undefined, faulted: true };
}
};
memoryEngineSession = {
engine: writeEngine,
handle: writeHandle,
inject: injectFn,
harvest: harvestSafe,
release: () => {
for (const end of openedLegs)
end();
},
captureOptOut: {
optedOut: () => {
if (captureOptedOut)
return true;
const r = writeEngine.sessionCaptureOptOutOrFault(sessionId);
return r instanceof Promise ? r.then((s) => s.record !== undefined) : r.record !== undefined;
},
indeterminate: () => {
if (captureOptedOut)
return false;
const r = writeEngine.sessionCaptureOptOutOrFault(sessionId);
return r instanceof Promise
? r.then((s) => s.record === undefined && (captureIndeterminate || s.fault))
: r.record === undefined && (captureIndeterminate || r.fault);
},
flip: async (reason) => {
const entitlement = await resolveCaptureEntitlementFresh();
const verdict = adjudicateCaptureOptOut({ posture: capturePosture, entitlement, subject: "declaration" });
if (!verdict.allowed)
throw captureOptOutDeniedError(verdict.detail);
if (verdict.faultDisclosure !== undefined)
deps.onError?.(new Error(verdict.faultDisclosure), { phase: "config", sessionId });
if (input.captureCarrierUnsupported === true) {
const e = new Error(`memory capture opt-out cannot be honored on this deployment shape: the execution environment is remote/per-run ` +
`and no RunnerDeps.memoryCaptureRecordStore is supplied — the record would not survive to a resume replica. Nothing was recorded.`);
e.code = "config.memory_capture_unsupported";
throw e;
}
const trimmed = reason?.trim();
const outcome = await writeEngine.markSessionCaptureOptOut(sessionId, trimmed !== undefined && trimmed !== "" ? `host flip verb: ${trimmed.slice(0, 200)}` : "host flip verb");
if (outcome === "unpersisted") {
deliverEngineNotice(deps.onNotice, memoryCaptureOptOutUnpersistedNotice({ sessionId, ingress: "flip-verb" }));
throw captureOptOutUnpersistedError(sessionId, "flip-verb");
}
captureOptedOut = true;
if (outcome === "created") {
deliverEngineNotice(deps.onNotice, memoryCaptureOptedOutNotice({ sessionId, origin: "flip-verb" }));
if (input.memoryCapturePolicyDeclared !== true && !undeclaredCapturePostureAnnounced) {
undeclaredCapturePostureAnnounced = true;
deps.onError?.(new Error(`a session memory-capture opt-out was honored under the DEFAULT capture posture (no RunnerDeps.memoryCapturePolicy configured) — ` +
`the switch is now in use; declare "open", "governed" or "capture-required" to make the deployment's stance explicit.`), { phase: "config", sessionId });
}
}
const sweep = await writeEngine.sweepSessionCaptureResidue(writeHandle);
if (sweep.withheld.length > 0) {
deliverEngineNotice(deps.onNotice, memoryRestoreWithheldNotice({ paths: sweep.withheld, sessionId }));
}
if (sweep.failures.length > 0) {
const named = sweep.failures
.slice(0, 5)
.map((f) => `${f.path} (${f.detail})`)
.join("; ");
const e = new Error(`memory capture opt-out is ON (the one-way record stands) but the boundary sweep could not contain ` +
`${sweep.failures.length} path(s) on the writable memory root — the named residue stays on the authoritative ` +
`plane until a retry or host action clears it: ${named}${sweep.failures.length > 5 ? "; …" : ""}`);
e.code = "memory.capture_optout_sweep_failed";
throw e;
}
return { outcome };
},
},
pollution: {
polluted: () => writeEngine.sessionPollution(sessionId),
markPolluted: (reason, cause) => {
const outcome = writeEngine.markSessionPolluted(sessionId, reason, cause);
if (outcome === "existed" || (outcome === "unpersisted" && pollutionAnnounced))
return;
pollutionAnnounced = true;
deliverEngineNotice(deps.onNotice, memorySessionPollutedNotice({ reason, sessionId, provenance: input.memoryProvenance }));
},
},
contentSafety: {
trustedTools: new Set(memorySpec.trustedTools ?? []),
execIsExternalContent: memorySpec.execIsExternalContent === true,
},
...(input.memoryProvenance !== "off"
? { settlement: { controlDir: writeEngine.controlPlaneDir, sessionId, provenance: "carry" } }
: {}),
...(input.memoryProvenance !== "off"
? {
recallTaint: {
judgeDeliveredPath: (absPath) => {
try {
if (!isAbsolute(absPath))
return false;
const roots = [writeHandle.memoryDir, ...(readOnlyHandle !== undefined ? [readOnlyHandle.memoryDir] : [])];
if (!roots.some((r) => isContainedIn(r, absPath)))
return false;
return entryFileHeadCarriesOrigin(absPath);
}
catch {
return false;
}
},
},
}
: {}),
};
effectiveMemoryScopes = {
state: "mounted",
contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy",
scopes: mountedScopeRows,
writeScope: memorySpec.writeScope,
...(memorySpec.projectKey !== undefined ? { projectKey: memorySpec.projectKey } : {}),
};
if (input.memoryProvenance !== "off") {
const session = memoryEngineSession;
const markDerived = (ids) => {
const shown = ids.slice(0, 3).join(", ") + (ids.length > 3 ? ", …" : "");
session.pollution.markPolluted(`this session read the content of external-origin memory entr${ids.length === 1 ? "y" : "ies"} ${shown}`, "derived");
};
for (const plane of toolPlanes)
plane.onTaintedDelivery = markDerived;
}
if (input.memorySearchToolsPlanned)
memoryTools = createMemoryEngineTools({ planes: toolPlanes, sessionPollution: () => writeEngine.sessionPollution(sessionId), provenance: input.memoryProvenance, writeScope: memorySpec.writeScope });
}
catch (err) {
if (memoryEngineSession === undefined)
for (const end of openedLegs)
end();
if (typeof err.code === "string" &&
(err.code.startsWith("config.memory_scope") ||
err.code.startsWith("config.memory_project") ||
err.code === "config.memory_dual_root_overlap" ||
err.code === "memory.capture_optout_denied" ||
err.code === "memory.capture_optout_unpersisted" ||
err.code.startsWith("config.memory_capture"))) {
throw err;
}
deps.onError?.(asThrownError(err), { phase: "memory", sessionId });
if (effectiveMemoryScopes === undefined) {
effectiveMemoryScopes = {
state: "memoryless",
reason: "mount-failed",
contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy",
scopes: [],
writeScope: null,
...(materializedResidue.length > 0 ? { materializedResidue: [...new Set(materializedResidue)] } : {}),
};
}
}
}
if (memorySpec && memorySpec.enabled && !useMemoryEngine) {
const detail = "TaskSpec.memory is enabled but RunnerDeps.memoryBackend is not configured; memory is inactive for this task (the legacy memoryStore fallback was retired in design/138 S4 and the dep was removed in design/157 B19).";
deps.onError?.(new Error(detail), { phase: "config", sessionId });
}
const composeInjection = (facts) => {
let memoryBlock;
let seedFiles;
let recallDisciplineSegment;
if (memoryEngineSession) {
const injection = memoryEngineSession.inject();
let blockBody = injection.block;
if (captureOptedOut) {
blockBody = [MEMORY_CAPTURE_OPTOUT_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
}
else if (captureIndeterminate && facts.rosterCanPersist) {
blockBody = [MEMORY_CAPTURE_INDETERMINATE_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
}
else if (!facts.rosterCanPersist && injection.instruction === "" && injection.readOnlyNotice === undefined) {
blockBody = blockBody.trim() ? `${MEMORY_READONLY_NOTICE}\n\n${blockBody}` : MEMORY_READONLY_NOTICE;
}
else if (!facts.rosterCanPersist && injection.instruction !== "") {
blockBody = [MEMORY_READONLY_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
}
else if (input.memoryPersistenceDeclared === true && injection.readOnlyNotice !== undefined) {
blockBody = [injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
}
if (!facts.rosterCanPersist &&
(injection.announceBlock?.trim() ?? "") !== "" &&
blockBody.includes(injection.announceBlock) &&
!blockBody.trimEnd().endsWith(MEMORY_ANNOUNCEMENT_READONLY_CODA)) {
blockBody = `${blockBody}\n\n${MEMORY_ANNOUNCEMENT_READONLY_CODA}`;
}
if (captureOptedOut &&
facts.rosterCanPersist &&
(injection.announceBlock?.trim() ?? "") !== "" &&
blockBody.includes(injection.announceBlock) &&
!blockBody.trimEnd().endsWith(MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA)) {
blockBody = `${blockBody}\n\n${MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA}`;
}
if (blockBody.trim())
memoryBlock = blockBody;
if (memoryTools !== undefined) {
recallDisciplineSegment = memoryRecallDisciplineSegment(input.memoryProvenance, { markedEntriesServed: memoryMarkedEntriesServed });
memoryBlock = memoryBlock !== undefined ? `${memoryBlock}\n\n${recallDisciplineSegment}` : recallDisciplineSegment;
}
if (memoryEngineSession.handle.writeScope !== null && writeChannelOpen && facts.rosterCanPersist && !captureOptedOut && !captureIndeterminate) {
memoryBlock = memoryBlock !== undefined ? `${memoryBlock}\n\n${MEMORY_PREFERENCE_DISCIPLINE}` : MEMORY_PREFERENCE_DISCIPLINE;
}
if (memoryBlock !== undefined && injection.indexSeed !== undefined && facts.rosterCanPersist && !captureOptedOut && !captureIndeterminate)
seedFiles = [injection.indexSeed];
}
return {
memoryBlock,
...(recallDisciplineSegment !== undefined ? { recallDisciplineSegment } : {}),
...(seedFiles !== undefined ? { seedFiles } : {}),
};
};
if (effectiveMemoryScopes === undefined) {
effectiveMemoryScopes = memorySpec
? memorySpec.enabled
? { state: "memoryless", reason: "no-backend", contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy", scopes: [], writeScope: null }
: { state: "none", reason: "disabled", scopes: [], writeScope: null }
: { state: "none", reason: "no-spec", scopes: [], writeScope: null };
}
return {
memoryEngineSession,
admittedOrgScopes,
ownOrgVerdict,
effectiveMemoryScopes,
...(memoryTools !== undefined ? { memoryTools } : {}),
...(memoryWriteGate !== undefined ? { memoryWriteGate } : {}),
composeInjection,
};
}