Memory Provenance and Deletion: Trace and Remove Session Memories

Learn how OpenClaw tracks session-derived memories and controls their deletion. This page explains admission policy and memory forget, including previews and deletion boundaries for operators.

Read this when

  • You want to exclude a source from automatic memory ingestion
  • You need to remove memories derived from specific sessions or participants
  • You are reviewing memory provenance, deletion coverage, or retained data

OpenClaw keeps a record of which source session produced each memory staged through automatic session ingestion or historical session backfill. That lineage lets openclaw memory forget drop tracked entries and their associated artifacts, and it marks the chosen sessions as forgotten so a later ingestion pass will not bring them back.

Two distinct controls exist for different jobs. Admission policy keeps matching sessions out of future dreaming ingestion and session backfill. Forget strips identifiable artifacts from the sessions you pick. Neither one wipes everything the agent has ever seen or written.

Both controls live in the bundled memory-core plugin. Other memory plugins may offer different commands and different deletion behavior.

Warning

Unless you supply --dry-run, memory forget acts right away. It leaves original session transcripts untouched, does not remove every freeform memory edit, and ignores copies stored outside the memory stores it inspects. Read the report and the deletion boundaries before you run it.

Preview and forget a session

Pick an explicit agent so you know exactly which store you are modifying. Enumerate its sessions to obtain the complete session key or ID. Session IDs are exact and case-sensitive; a shortened form will not match a longer ID:

openclaw sessions --agent <agent-id> --limit all --json
openclaw memory forget --agent <agent-id> --session <id-or-key> --dry-run --json

Look at sessionResolutions to confirm the intended sessions, entryKeys and mixedLineageEntryKeys for full-entry deletions, and artifacts for the stores affected. Go through curatedWrites and untargetableEntryKeys on their own; neither gives you a full accounting of what will survive.

Once the selection looks right, rerun the command without --dry-run:

openclaw memory forget --agent <agent-id> --session <id-or-key> --json

No extra confirmation prompt or --apply flag exists. The preview reflects the current state and is not stored as a deletion plan. During a sensitive cleanup, pause direct agent edits and external writers; they do not hold the memory plugin's mutation lock. Afterwards, run the preview again to see whether any attributable artifacts remain.

The complete flag list, selector semantics, and report fields appear in memory forget.

What lineage is recorded

Three record types each serve a different purpose:

RecordGranularityWritten byUsed for
Chunk provenanceIndex chunkClassification code at index timeTrust gating and recall framing
Entry originsTracked entrySession ingestion, backfill, and consolidationFinding entries derived from a selected session
Curated-write recordsMemory fileThe memory write observerIdentifying files to review during a purge

Chunk provenance captures the origin class and session kind. Entry origins, by contrast, tie an entry key to an agent and source session inside SQLite. Promotion markers in MEMORY.md bridge the visible entry to those origin rows.

When dreaming merges or supersedes tracked entries, reconciliation moves the parents' origins onto the surviving entry. This happens in code around the model call, including for participating agents that share a workspace; the model never owns the origin rows.

When backfill coalesces the same claim from several sessions, every source origin is kept, and the repeated claim is not tallied as extra evidence.

Coverage is not complete. Handwritten notes, direct agent edits, and entries staged before lineage tracking may have no entry origins. The report's untargetableEntryKeys lists promotion markers with no origins in the selected agent's store, not every piece of untracked prose. Such entries cannot be picked out by lineage alone, though explicit session references or exact corpus quotations may still match the file scrub.

Admission: keeping sources out of memory

To keep Gmail hook sessions out of dreaming ingestion and session backfill:

{
  plugins: {
    entries: {
      "memory-core": {
        config: {
          memoryPolicy: {
            excludeSessions: {
              hookExternalContentSources: ["gmail"],
            },
          },
        },
      },
    },
  },
}

Channel/plugin identifiers (not room IDs) and chat types can also be excluded. Empty or omitted lists add no policy exclusions. A match in any list excludes the whole session; values match recorded session metadata, not conversation text.

Both paths consult the policy before reading the transcript. Automatic ingestion also writes the exclusion reason into its ingestion checkpoint. Removing a matching rule makes a session eligible for a later sweep, subject to the other trust and ingestion gates. A session recorded as forgotten stays excluded.

Policy is prospective: it does not erase an existing corpus, staged candidate, or promoted entry. Use memory forget for existing attributable data. See Memory config for exact matching rules and exclusion reasons.

The admission boundary

PathConfigured admission exclusions
Automatic dreaming ingestionApplied before transcript reads
Manual session-backfillApplied in preview, REM, and apply modes
Raw transcript indexingNot applied
Direct writes and session hooksNot applied

Matching depends on retained session metadata; missing fields never match a rule. Automatic dreaming separately skips retained archives. To exclude an archived session from backfill and transcript indexing as well, explicitly forget its full session ID. Those paths check forgotten-session records even when the former channel, chat type, or hook-source metadata is gone.

An excluded session can still edit MEMORY.md, USER.md, or another workspace file if its tools allow it. Restrict the relevant file, shell, and external-harness capabilities when you need to prevent those writes, and review enabled memory-writing hooks. Admission policy is not a filesystem permission. Observed writes are reported for review, not given per-entry lineage.

Deletion: purging what a session produced

Selectors target sessions, not individual facts about a person. --participant selects sessions with that recorded actor ID; it does not search memory text for a name. --hook-source selects sessions with that recorded external-content source. Both require retained metadata. Explicit IDs and keys can also resolve retained archives.

A tracked entry with any selected origin is removed whole, even when it also has unselected origins. These removals appear in mixedLineageEntryKeys. The purge does not ask a model to subtract one person's contribution from merged prose. Surviving sources may support a new entry later, but automatic reconstruction is not guaranteed.

The cleanup covers matching promoted entries, session-corpus lines, memory index chunks and their full-text/vector rows, cached embeddings, short-term state, ingestion deduplication state, and dreaming rewrite preimages. It also removes whole lines containing exact selected corpus snippets from scanned memory files and dream diaries. The command reference describes the counters and selection limits.

Purged sessions stay purged

A real purge records each selected session as forgotten in the selected agent's SQLite database before removing its artifacts. Automatic ingestion, historical session backfill, and transcript indexing, including memory index --force, check these records. Automatic ingestion records the reason forgotten.

The memory plugin coordinates purges with its staging and file mutations. A pending dream narrative is skipped if its tracked source entries or prior diary context were removed before publication. This does not retroactively identify untracked paraphrases in older diary entries.

Indexing checks again before publishing chunks or cached embeddings, so a result prepared before the purge cannot restore forgotten session data or a stale memory-file snapshot. An affected index run reports that its source changed; rerun openclaw memory index --agent <agent-id> to index current data.

Repeating a purge does not lift that exclusion. It applies to those session IDs in that agent's store, not to future conversations with the same person or hook source. Keep an admission rule for future matching sessions, within the admission boundary.

What deletion does not cover

  • Original transcripts and archives. Memory cleanup leaves them in the session store. Session deletion is a separate lifecycle operation and ordinarily retains a deleted-transcript archive. Do not treat either command as proof that all conversation copies have been erased.
  • Untracked older memories. No origin row means no lineage-based deletion. New session backfill preserves origins, but it does not retroactively supply lineage for candidates staged by older versions. Inspect those separately.
  • Freeform edits. curatedWrites reports recognized writes or write attempts with a relativePath and observedAt. That record alone does not delete a file or identify contributing lines. Supported write/edit/patch transcript records supplement the latest file-level observer record, but can include unsuccessful attempts. Arbitrary shell writes and external edits are not fully tracked.
  • Paraphrases and other copies. Exact corpus quotations can be removed, but untracked paraphrases, exports, external backups, other plugins' stores, and independently copied files are outside this cleanup. A reported curated file can still lose lines that match a tracked entry or exact quotation.
  • Other agents. Selection and forgotten-session records are per agent. Repeat the review for each relevant agent, including agents sharing a workspace; one agent's report does not establish that every index is clean.

An empty preview indicates that those selectors and matching rules did not locate any further artifacts. This does not guarantee that no related information still exists.

Purging a person or a source end to end

For a participant, begin by running a preview in each relevant agent:

openclaw memory forget --agent <agent-id> --participant <actor-id> --dry-run --json

Confirm the resolved session IDs prior to removing --dry-run. Doing so deletes tracked entries derived from any content in those sessions, which includes more than just messages authored by that participant. When participant metadata is absent from an archive, include its explicit --session <id-or-key> selector.

For a source, rely on its recorded hook identifier:

openclaw memory forget --agent <agent-id> --hook-source gmail --dry-run --json

Once the reviewed selection has been applied, check retained files and untracked memories, manage transcript and archive retention separately, and execute the preview again. If future sessions from that source should also be excluded from dreaming ingestion and session backfill, add an admission rule.

1,647 words · updated Aug 28, 2026