UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

843 lines • 58.4 kB
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,
    };
}