How ai-memory Handles Destructive Operations: Safe Purging and Resetting Data

ai-memory implements a controlled, multi-stage safety protocol for destructive operations that guards against live processes, validates deletions through admission webhooks, performs logical deletes by default, and only physically removes data when explicitly requested via the --compact flag.

The akitaonrails/ai-memory repository treats data removal as a critical, irreversible action requiring multiple safeguards. Whether you are resetting a local workspace or purging an entire project, the system employs a controlled, multi-stage process that prioritizes data integrity through live-process detection, pre-deletion validation hooks, and atomic transaction handling.

The Six-Stage Safety Protocol

Every destructive operation in ai-memory follows a rigorous pipeline designed to prevent accidental data loss.

Stage 1: Guarding Against Live Processes

Before touching any on-disk database or wiki files, ai-memory verifies that no other process holds the SQLite inode. In crates/ai-memory-cli/src/commands/reset.rs, the sibling_processes function scans for concurrent ai-memory instances. If a sibling process is detected, the operation aborts immediately with a busy_message error to prevent database corruption during active sessions.

// Guard against a running sibling process (reset command)
let siblings = sibling_processes();
if !siblings.is_empty() {
    bail!(busy_message("reset", &siblings));
}

Stage 2: Admission Webhook Validation

For project-wide purges (purge-project, purge-session, delete-workspace), the system runs an admission webhook before executing any SQL DELETE statements. As implemented in crates/ai-memory-mcp/src/admin.rs within the handle_purge_project function, this webhook can reject the operation based on external policy checks, keeping source data entirely intact if validation fails.

// Admission webhook check before purge-project (simplified)
let pre_checkpoint = checkpoint_or_500(&state.wiki,
    format!("pre-purge-project {label}"));
/* … webhook runs, may reject … */
let checkpoint = checkpoint_or_warn(&state.wiki,
    format!("purge-project {label}"));

Stage 3: Logical Deletion (Soft Delete)

By default, purging records a tombstone entry rather than immediately erasing rows. The implementation in crates/ai-memory-store/src/ops.rs marks records as deleted while preserving the corresponding wiki directory structure temporarily. This soft-delete approach maintains referential integrity and allows for potential recovery until a compaction run occurs.

Stage 4: Optional Compact Mode for Hard Deletion

When the caller passes --compact, the system converts logical deletes into physical ones. According to docs/lifecycle-ops.md, this triggers an FTS index rebuild and a SQLite VACUUM operation, permanently removing tombstoned records and reclaiming disk space.

Stage 5: Atomicity and Ordering

The purge executes inside a single-writer SQLite actor that guarantees no other writes interleave during the transaction. File cleanup occurs after the database transaction commits; any filesystem removal failure is reported via structured logging but does not rollback the committed database purge. This logic resides in crates/ai-memory-wiki/src/wiki.rs within the purge_* helper functions.

Stage 6: Logging and Observability

Every step emits structured logs using tracing::info!(path = …, "purge") and fires mirror-notification events (X-Memory-Op: purge_project). Downstream services can subscribe to these events to react to deletions in real-time, as documented in docs/marker-file.md.

Resetting the ai-memory Environment

The ai-memory reset command provides a safe mechanism for wiping local data stores.

By default, reset runs as a dry-run, displaying the directories that would be removed without modifying the filesystem. When you supply the --confirm flag, the command executes the full safety protocol:

  1. Runs the live-process guard (sibling_processes) to ensure exclusive database access
  2. Wipes three data sub-directories: wiki/, db/, and raw/
  3. Preserves the logs/ directory for audit trails
  4. Emits structured logs via tracing::info! for each removed path

# Dry-run a reset (shows what would be removed)

ai-memory reset

# Perform a full reset (must be alone, no other ai-memory process)

ai-memory reset --confirm

Purging Projects, Sessions, and Workspaces

Project-Level Purge Operations

The purge-project command removes the UUID-namespaced wiki root and raw workstream segments for the selected project. It succeeds only when no managed work-stream lease is active, unless you override this with --force. The thin client wrapper in crates/ai-memory-cli/src/commands/purge_project.rs forwards these requests to the /admin/purge-project MCP endpoint.


# Logical purge of a project (default, keeps tombstones)

ai-memory purge-project --workspace default --project my-project --confirm

# Hard purge + rebuild indexes

ai-memory purge-project --workspace default --project my-project --confirm --compact

Session and Workspace Scope

purge-session and delete-workspace operate with identical safety semantics, scoped to a single session or the entire workspace respectively. As noted in docs/lifecycle-ops.md (lines 32-34), these commands follow the same admission-before-delete pattern and support --compact for hard deletion.

Summary

  • Live-process detection in reset.rs prevents destructive operations against active databases using inode-locking checks.
  • Admission webhooks in admin.rs allow external validation to block purges before SQL execution.
  • Logical deletion is the default behavior, creating tombstones rather than immediate erasure.
  • Physical deletion requires the explicit --compact flag, which runs VACUUM and FTS rebuilds.
  • Atomic execution inside a single-writer SQLite actor ensures transactional integrity during purges.
  • Comprehensive logging via tracing and X-Memory-Op events provides full audit trails of destructive actions.

Frequently Asked Questions

What happens if I run ai-memory reset without --confirm?

The command executes a dry-run that lists all files and directories slated for removal without actually deleting them. You must explicitly add --confirm to execute the destructive operation, at which point the system also checks for sibling processes to ensure safe execution.

How does ai-memory prevent data corruption during concurrent access?

Before any destructive operation, the system calls sibling_processes() to detect other ai-memory instances holding the SQLite database inode. If detected, the operation aborts with a busy error. Additionally, all writes route through a single-writer SQLite actor that serializes access and prevents interleaved transactions.

What is the difference between purging and compacting in ai-memory?

Purging (the default) performs a logical delete that marks records with tombstones and removes wiki directories, but leaves database rows intact for potential recovery. Compacting (invoked with --compact) physically removes tombstoned records, rebuilds the FTS search indexes, and runs SQLite's VACUUM command to reclaim disk space permanently.

Can I recover data after running purge-project?

Data recovery is possible only if you have not run the command with --compact. The default logical delete preserves database tombstones and wiki structures temporarily. Once you execute a compact operation or run VACUUM manually, the data is permanently erased from both the database and filesystem.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →