pub fn delete_mem(
engine: &mut Engine,
params: MemDeleteParams,
) -> Result<MemDeleteResponse, FullEngineError>Expand description
Unregister a writable mem at runtime. The unified-engine
counterpart to full’s memstead_git_branch::mem_management::delete_mem.
Ordering guarantees mirror full’s:
-
Pre-mutation checks (input validation, name resolution, allowlist match). Any failure here leaves the engine untouched and performs zero filesystem writes.
-
Router unregister (snapshot swap via
memstead_base::Engine::unregister_writable_mem). After this the mem is no longer visible to readers. The unregister hands back the backend handle so step 3 can drive backend-side cleanup without re-resolving the mount. -
Optional disk delete. A failure here is non-fatal: the mem is already unregistered, the leftover artifacts are a follow-up concern, and the response reports
files_deleted: falsewith a typedMEM_FILES_NOT_DELETEDwarning naming what survived.- Folder mount:
remove_dir_all(location)removes the mem directory.backend.delete_artifacts()is a no-op (folder backends keep the default impl). - Mem-db-backed (git-branch) mount:
backend.delete_artifacts()dropsrefs/heads/<branch_leaf>and prunes__MEMSTEAD:mems/<branch_leaf>/config.json. There is no on-disk directory to rmdir.
files_deleted: truereflects “every backend-visible artifact for this mem has been removed” — the wire shape is unchanged but the semantic now covers both backends symmetrically. - Folder mount:
Operator-mode bypass. When MemDeleteParams::operator_mode is
true, Step 2 ([[mem_management.delete]] allowlist match) is
skipped. All other steps run identically — including input
validation, name resolution, the policy safeguard, router
unregister, backend cleanup, and persistence. The flag is set by
the transport that established operator intent at boot (today,
memstead-mcp --operator-mode) and is not exposed as a wire-shape
input.
Policy safeguard. Step 3 (MEM_REFERENCED_BY_POLICY) fires when
delete_files: true AND another writable mem has a
cross_mem_links grant pointing into the target. The gating is
independent of operator_mode: storage destruction would orphan
the grant, so the refusal is a hard stop until the grant is
revoked. When delete_files: false (router-only unregister), the
storage survives and the grant remains valid against it — the
check is skipped. This matches the verb split exposed at the CLI
layer (mem unregister is the verb that produces delete_files: false; mem delete is the verb that produces delete_files: true).
Hierarchical candidate composition is symmetric with
create_mem: the router records the create-time path on
each writable entry, and Step 2 below reads it back via
[memstead_base::MemRouterSnapshot::mem_path_for_mem] to assemble
the same <mem_path>/<name> (or bare <name>) string the
create-side composer matched against.