Memory with a paper trail
How OpenClaw records where each remembered fact came from, what the forget command can actually remove from a session, and the parts of the record that no lineage based deletion will ever reach
Deleting a memory is easy to promise and hard to do honestly. An assistant that has been reading your sessions for months has spread what it learned across entries, index chunks, diaries and caches, and any deletion story has to say which of those it reaches. The OpenClaw answer is lineage, in the sense that it records where a staged memory came from and uses that record to remove what can be attributed. It is also unusually clear about the parts it cannot reach, which is the more useful half of the documentation.
Two controls, different jobs
- Admission policy keeps matching sessions out of future dreaming ingestion and session backfill, while the forget command removes identifiable artifacts that selected sessions already produced.
- Three separate records carry lineage, with chunk provenance written by classification code at index time for trust gating and recall framing, entry origins linking an entry key to an agent and a source session in the database, and curated write records naming the memory files a purge should review.
- Selectors identify sessions rather than individual facts, so choosing a participant selects the sessions carrying that recorded actor identifier and does not search memory text for a name.
- Both controls belong to the bundled memory core plugin, and other memory plugins may expose entirely different commands and deletion behaviour.
A tracked entry with any selected origin is removed whole, even when it also has unselected origins.
What a purge touches
A forget run deletes immediately unless you ask for a dry run, and there is no second confirmation prompt and no separate apply flag. The preview is computed from current state rather than saved as a plan, so the safe sequence is to preview, read the report, then repeat the identical command without the dry run flag. The cleanup reaches matching promoted entries, session corpus lines, memory index chunks together with their full text and vector rows, short term state, ingestion deduplication state, and dreaming rewrite preimages. A non-empty session selection also clears the whole embedding cache for that agent, including results from unfinished rebuilds that were never linked to published chunks, so unrelated published entries stay usable while later indexing may need to regenerate what was cached. Whole lines containing exact selected corpus snippets are removed from scanned memory files and dream diaries. Session identifiers are exact and case sensitive, and an abbreviation will not select a longer identifier. Direct agent edits and external writers do not share the plugin's mutation lock, so they are worth pausing during a sensitive cleanup and the preview is worth rerunning afterwards. If a run fails it can leave partial cleanup, and the right move is to fix the reported storage or filesystem error and run it again, rather than deleting the corpus and origin evidence the purge is holding on to.
After the purge
- Each selected session is recorded as forgotten in the agent's database before its artifacts are removed, and automatic ingestion, historical backfill and transcript indexing all check those records, with automatic ingestion logging the reason as forgotten.
- Indexing checks again before publishing chunks or cached embeddings, so a run prepared before the purge cannot restore forgotten data, and it reports that its source changed so you know to index current data.
- The exclusion is scoped to those session identifiers in that agent's store, so it does not cover future conversations with the same person or hook source, which is what an admission rule is for.
None of this makes much sense without the layer underneath it. What the agent remembers in the first place is covered in Built-in memory, and the origin classes that sit on every chunk, along with how recall is framed, belong to Memory architecture.
Why lineage, not search
The design starts from an awkward fact about merged prose, which is that once two sessions have been consolidated into one entry there is no reliable way to subtract one contributor from the sentence that survives. Rather than ask a model to try, OpenClaw removes any tracked entry carrying a selected origin whole, and reports those cases separately so you can see what went with them. Origins are maintained in code around the model call during Dreaming, including for agents that share a workspace, precisely so that the model is never the thing that owns them. The same conservatism explains why coverage is admitted to be partial, since handwritten notes, direct agent edits and entries staged before lineage tracking simply have no origin row to select. Admission policy is prospective for the same reason, and it is not a filesystem permission, so an excluded session can still edit a workspace file if its tools allow that. The honest summary in the documentation is that an empty preview means those selectors found nothing more, not that nothing remains, which is the right frame to carry into any deletion request you have to answer (Diali security).
On Diali
On Diali each customer runs their own assistant, and the state that Hosted OpenClaw on Diali keeps lives on a persistent volume, with daily snapshots and one-click restore available through the Backups add-on (included on Max). If you are weighing up a longer running deployment where retention matters, Diali pricing is a sensible place to start.
- Lineage is recorded at ingestion; what has no origin row cannot be selected.
- A dry run previews; the same command without it deletes straight away.
- An empty preview is not proof that nothing related remains.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
