openclaw memory CLI Reference: Index, Search, Forget, Promote

Reference for the openclaw memory command, covering semantic memory indexing, search, promotion to MEMORY.md, and deletion by provenance. For users managing agent memory via the memory-core plugin.

Read this when

  • You want to index or search semantic memory
  • You're debugging memory availability or indexing
  • You want to promote recalled short-term memory into `MEMORY.md`
  • You need to delete provenance-tracked memories derived from specific sessions or participants

openclaw memory

Semantic memory indexing, search, promotion into MEMORY.md, and deletion based on provenance are all handled here. This functionality comes from the bundled memory-core plugin, which is active when plugins.slots.memory picks memory-core as its selection, the default choice. Other memory plugins expose their own CLI namespaces.

See also: Memory concept, Dreaming, Memory config reference, Memory Wiki, wiki, and Plugins.

memory status

openclaw memory status [--agent <id>] [--deep] [--index] [--fix] [--json] [--verbose]

When --agent is omitted, the operation targets every agent in agents.entries; if no agent list is specified, it defaults to the default agent.

FlagEffect
--deepCheck vector-store, embedding-provider, and semantic-search readiness, which triggers extra provider calls. Plain memory status skips this and stays quick; a fully persisted index appears as indexed (unprobed), while unknown vector or semantic state signals that probing never happened.
--indexRebuild the index when the store is dirty. This also implies --deep.
--fixFix stale recall locks and tidy up promotion metadata.
--jsonOutput as JSON.
--verboseShow detailed logs for each phase.

If the Dreaming line remains off even with dreaming.enabled: true set, or scheduled sweeps appear not to execute, the managed dreaming cron relies on the default agent's heartbeat firing to start reconciliation. Scheduling details live in Dreaming.

Status also reports any extra search paths coming from memory.search.extraPaths. For providers that resolve their default model during initialization, plain status postpones model identity checks until that model is known. Run --deep to initialize the provider and confirm the model and provider settings against the existing index.

memory index

openclaw memory index [--agent <id>] [--force] [--verbose]

Per-agent scoping matches status. --force performs a full reindex rather than an incremental pass. --verbose displays per-agent provider, model, sources, and extra-path details before indexing progress appears. The completion message gives the indexed file count. An empty corpus counts as a successful no-op: the command shows the resolved workspace path and notes that nothing was indexed, leaving the missing memory/ directory for the first memory write to create. Internal dreaming-narrative, cron, and heartbeat session transcripts are left out of indexing, including retained compressed narrative archives whose original sessions are no longer active. Sessions previously selected by memory forget stay excluded as well. --force removes stale index records for both groups without reindexing their retained transcripts. Ordinary retained, reset, and deleted user-session archives remain eligible until explicitly targeted.

openclaw memory search [query] [--query <text>] [--agent <id>] [--max-results <n>] [--min-score <n>] [--json]
  • Query: positional [query] or --query <text>. When both are present, --query takes precedence. If neither is set, the command fails.
  • --agent <id>: falls back to the default agent, not the full agent list.
  • --max-results <n>: limits result count, requiring a positive integer.
  • --min-score <n>: drops matches scoring below this threshold.

Routine indexing can proceed after search returns without triggering a warning. If automatic indexing failed, or the index identity mismatches, human output warns that matches might be incomplete. With --json, the response adds stale: true, plus warning and action fields. Treat an empty results array as authoritative only when stale is missing.

memory forget

Identifiable memory artifacts tied to selected sessions get removed, and those sessions are marked as forgotten in one agent's store. The connection between lineage, admission policy, and deletion coverage is explained in Memory provenance and deletion.

Warning

Deletion happens immediately unless --dry-run is set. No confirmation prompt or --apply flag exists. Source session transcripts are kept.

Begin with a preview:

openclaw memory forget --agent <agent-id> --session <id-or-key> --dry-run --json
openclaw memory forget --agent <agent-id> --hook-source gmail --dry-run --json
openclaw memory forget --agent <agent-id> --participant <actor-id> --dry-run --json

After reviewing the report, rerun the intended command without --dry-run.

FlagEffect
--agent <id>Picks a single agent. Falls back to the default agent, never all agents.
--session <id-or-key>Chooses by session ID or key; can be used more than once.
--hook-source <source>Chooses live sessions that recorded this external-content hook source; can be used more than once.
--participant <actor-id>Chooses live sessions that recorded this participant actor ID; can be used more than once.
--since <date>Includes sessions created on or after the given date. Use an ISO timestamp with a timezone for an exact cutoff.
--dry-runProduces a report without touching memory files, indexes, plugin state, or forgotten-session records.
--jsonOutputs the complete report in JSON format.

Session selection

You must supply at least one selector. When you repeat values or mix selector kinds, they join with OR: any session that matches one selector gets picked, as long as --since allows it. Selectors look at recorded identifiers, not names or message text. A participant selector pulls in the entire session, including contributions from everyone else.

--participant deliberately matches raw actor IDs across identity namespaces; it does not restrict itself to profiles. In the report, participantMatches lists the typed identities that correspond to each requested ID, even when several match. Before you delete anything, check those identities and the full sessions shown in --dry-run --json. A profile merge will not quietly change what a raw selector means.

Explicit IDs and keys are checked against live sessions and kept archives in the configured session.store, including custom and shared stores. Matching stays within the chosen agent. Each result in the report gets labeled live, archived, or unresolved. If an explicit value cannot be resolved, it is recorded as a literal session ID so it can be excluded later; that does not confirm the session was actually found. IDs must match exactly and case-sensitively, which also applies to retained archive names. A shorter form will not match a longer session ID.

Hook-source and participant selectors depend on live metadata; archived-only records do not keep that information. For those archives, use the full ID or key. Hook-source matching is exact: IMAP uses email, Gmail hooks use gmail, and generic webhooks use webhook. Older retained records that only have a coarse webhook classification cannot tell IMAP apart from a generic webhook once the original exact source is gone; pick those sessions by full ID instead. --since relies on the live session's creation time or the archive's creation time, not timestamps on individual messages. Unresolved explicit IDs have no timestamp and stay selected.

Read the report

FieldMeaning
agentId, dryRunRecords whether something was selected and if this was a preview.
sessionIds, sessionResolutionsLists selected IDs and how each one resolved; a resolution can also include sessionKey.
entryKeysEntry keys that have at least one origin in the selected sessions.
mixedLineageEntryKeysSelected entries that also have unselected origins; these get removed in full.
untargetableEntryKeysPromotion markers found without origin rows in this agent's store. This does not list unmarked prose.
curatedWritesFiles needing review, with relativePath and observedAt (Unix milliseconds). Includes supported recorded write attempts, which may not have succeeded.
artifactsCounts of matching files, entries, lines, and store rows described below.
refusalsHistorical consolidation highlights that need manual review. An empty list does not guarantee complete deletion coverage.

Preview and apply share the same matching logic, but each one reads the current state; a preview is not a fixed plan and does not lock later writes. Apply coordinates with the memory plugin's staging and file mutations. Indexing discards stale results instead of bringing back purged chunks or cached embeddings; rerun an index command that reports a source change. Direct agent edits and external writers do not honor that lock, so pause them during a sensitive cleanup. Run the preview again afterward. An empty selection or zero counts do not prove that no related data remains.

If deletion fails

Deletion is not a single transaction across files and stores. Index and plugin-state cleanup, including rewrite backups, happens before memory-file edits; corpus and origin evidence is removed last so a retry can spot remaining artifacts. If a purge fails, fix the reported storage or filesystem error and rerun the same command with the same selectors. Do not remove its corpus or origin records by hand. After it succeeds, run the command again with --dry-run to see what is left.

Artifacts removed

The purge removes matching promotion-marker entries and session-reference sections from scanned memory files, selected session-corpus lines, and selected-session transcript index chunks. It clears associated full-text and vector rows, cached embeddings, matching short-term state, ingestion seen-hash scopes, and origin rows. Matching content is scrubbed from dreaming rewrite backups, rather than deleting every backup.

Consolidation preserves origins for replaced promotion markers while retained rewrite preimages reference them. Those origins are pruned only after live entries, retained preimages, diary excerpts, and indexed snapshots stop referencing the keys. New consolidation-history excerpts carry the replacement entry's lineage and are removed with it. Their origins remain while the excerpts remain, even after backup rotation; diary history has no automatic expiry. In a shared workspace, a later purge for another agent also checks its indexed snapshots, even when the first purge already removed the shared file content.

It also clears stale index records for internal dreaming-narrative, cron, or heartbeat sessions when the selection is nonempty. Index cleanup can therefore include more than the selected sessions, and all chunks from a changed memory file may be invalidated for later reindexing.

The artifacts counters are:

  • memoryFiles, memoryEntries, memoryLines: changed memory files, removed marked entries or session-reference sections, and extra whole lines containing exact selected corpus snippets.
  • sessionCorpusFiles, sessionCorpusLines: changed corpus files and removed corpus lines.
  • indexChunks, indexSources, ftsRows, vectorRows, embeddingCacheRows: removed index and cache records.
  • shortTermEntries, seenHashScopes, backups, originRows: removed short-term entries and deduplication scopes, rewritten backup records, and deleted source-origin rows.

Entries with mixed lineage are deleted whole; the command does not rewrite them to preserve only unselected contributions. Surviving sources may support new entries later, but regeneration is not guaranteed.

Readmission and retained data

A real purge records the selected session IDs as forgotten in the agent's SQLite database before removing artifacts. Automatic dreaming ingestion, memory session-backfill, and transcript indexing, including memory index --force, check those records. Automatic ingestion records the reason forgotten. Repeating the purge does not remove the exclusion, and removing an admission-policy rule does not undo it. Future sessions with new IDs are not excluded by a previous purge.

New session-backfill diary facts and reflections carry entry markers and source origins, including REM previews and diary blocks left by a failed apply. Forgetting removes each matching line, including transformed or combined claims; unrelated lines remain. Historical unmarked backfill text has no reconstructed lineage. Exact corpus quotations in dream diaries such as DREAMS.md and memory/dreaming/**/*.md can be removed as whole lines. Untracked paraphrases cannot be reliably attributed and remain.

A curatedWrites entry by itself does not erase a file or its freeform modifications.
The most recent file-level write-observer record, along with supported write, edit,
and apply_patch calls in kept transcripts, points to files that need examination.
This does not serve as a full audit of shell writes or external editors. A listed
file can still be altered by the separate marker, session-reference, or
exact-quotation cleanup.

Warning

Entries placed before source-session tracking might lack origin rows and stay
after a purge; inspect them separately. Backfill for the current session keeps
origins, but it does not rebuild missing historical lineage.
Rewrite backups whose origin rows were already gone also need separate
inspection; earlier incomplete purges are not automatically fixed.
untargetableEntryKeys does not list every untracked candidate or memory.

Source transcripts, kept archives, other agents' indexes, exports, and
external backups each require separate inspection. In particular,
session deletion usually keeps a
deleted-transcript archive; it does not erase every copy of a conversation.

memory promote

Rank short-term candidates from memory/YYYY-MM-DD.md and, if desired, append
top entries to MEMORY.md.

openclaw memory promote [--agent <id>] [--limit <n>] [--min-score <n>] \
  [--min-recall-count <n>] [--min-unique-queries <n>] [--apply] [--include-promoted] [--json]
FlagDefaultEffect
--limit <n>Max candidates to return/apply.
--min-score <n>0.75Minimum weighted promotion score.
--min-recall-count <n>3Minimum recall count required.
--min-unique-queries <n>3Minimum distinct query count required.
--applypreview onlyAppend selected candidates to MEMORY.md and mark them promoted.
--include-promotedInclude candidates already promoted in previous cycles.
--jsonPrint JSON.

The CLI and the scheduled dreaming sweep both use the deep-phase defaults below.
Explicit CLI flags override them for a single manual run.

Ranking signals: recall frequency, retrieval relevance, query diversity,
temporal recency, cross-day consolidation, and derived concept richness, drawn
from both memory recalls and daily-ingestion passes, plus a light/REM phase
reinforcement boost for repeated dreaming revisits. Before writing, promotion
re-reads the live daily note, so edits or deletions to short-term snippets
since ranking are respected instead of promoting from a stale snapshot.

memory promote-explain

Explain one promotion candidate's score breakdown.

openclaw memory promote-explain <selector> [--agent <id>] [--include-promoted] [--json]

<selector> matches a candidate's key (exact or substring), path, or snippet
text.

memory rem-harness

Preview REM reflections, candidate truths, and deep-phase promotion output
without writing anything.

openclaw memory rem-harness [--agent <id>] [--path <file-or-dir>] [--grounded] [--include-promoted] [--json]
  • --path <file-or-dir>: seed the harness from historical YYYY-MM-DD.md
    daily files instead of the live workspace.
  • --grounded: also render a grounded What Happened / Reflections /
    Possible Lasting Updates preview from the historical notes.

memory rem-backfill

Write grounded historical REM summaries into DREAMS.md for UI review.
Reversible.

openclaw memory rem-backfill --path <file-or-dir> [--agent <id>] [--stage-short-term] [--json]
openclaw memory rem-backfill --rollback [--rollback-short-term] [--json]
  • --path <file-or-dir>: required unless --rollback/--rollback-short-term
    is set. Historical daily memory file(s) or directory to backfill from.
  • --stage-short-term: also seed grounded durable candidates into the live
    short-term promotion store so the normal deep phase can rank them.
  • --rollback: remove previously written grounded diary entries from
    DREAMS.md.
  • --rollback-short-term: remove previously staged grounded short-term
    candidates.

memory session-backfill

Distill retained session history into grounded short-term candidates. It shares
transcript trust classification, admission policy, and corpus storage with
dreaming. Staged candidates retain every contributing session's origin so
memory forget can select them later. Configured exclusions apply in preview,
REM, and apply modes; forgotten sessions remain excluded in every mode.
The default is a read-only preview, ordered
from the oldest unprocessed day to the newest.

openclaw memory session-backfill --agent <id> [--from YYYY-MM-DD] [--to YYYY-MM-DD] \
  [--limit-days <n>] [--archive-files <path...>] [--rem | --apply] [--json]
openclaw memory session-backfill --agent <id> --rollback [--json]
FlagDefaultEffect
--from YYYY-MM-DDInclude messages on or after this day in the dreaming timezone.
--to YYYY-MM-DDInclude messages on or before this day in the dreaming timezone.
--limit-days <n>92Process at most this many hash-untracked days, oldest first.
--archive-files <path...>Also inspect foreign transcript files as untrusted input; embedded owner metadata is not accepted.
--remWrite deterministic grounded per-day previews to DREAMS.md and retain their source-origin records.
--applypreview onlyDrain all bounded batches, stage trusted candidates, and write reversible DREAMS.md diary blocks.
--rollbackRemove all grounded backfill candidates and shared backfill diary blocks, including rem-backfill artifacts.
--jsonPrint machine-readable per-day counts and top candidates.

The command reads the selected agent's canonical session store, including
retained SQLite transcript identities from session rotation. It uses the same
tracked message hashes and per-run caps as live session ingestion, so repeated
--apply runs skip already ingested messages. Owner and agent lines from the
canonical store are eligible; tool output, web or non-owner input, and turns
without trustworthy owner provenance are excluded. Foreign archive files have
no authenticated owner-provenance contract, so their embedded ownership fields
remain untrusted and cannot be staged. Sessions previously purged with
memory forget remain durably excluded, including
when their original transcripts still exist or their tracked hashes were
cleared.

--apply empties the chosen history fully within a single call, yet every bounded batch still gets its own transaction. Both human-readable and JSON output show per-batch advancement along with the aggregate batch count, candidate total, and staged entries. When a successful apply is followed immediately by a preview, the preview then shows zero fresh candidates. Only the session corpus under memory/.dreams/, transient staging state, and reversible diary entries in DREAMS.md are written by this operation. It never touches MEMORY.md or USER.md; durable promotion remains a separate memory promote or dreaming decision. --rem and --apply cannot be used together.

Before any text is published, both writing modes record diary origins, so a failed apply later on never leaves diary quotations that cannot be traced. REM holds onto only the diary plus its origin bookkeeping: no session corpus is kept, no stage candidates are retained, ingestion cursors are not advanced, and no model is invoked.

Rollback for backfill is intentionally the same as memory rem-backfill: the identical grounded-only staging class and diary markers are used by both commands. Execute session-backfill --rollback only when your intention is to wipe both commands' grounded backfill artifacts from that workspace. Tracked hashes added by session backfill are also removed by rollback, and the affected transcript cursors are rewound, which lets surviving eligible candidates be previewed and applied once more. Forgotten-session records are left alone by rollback, and purged sessions are not readmitted.

Dreaming

Dreaming handles background memory consolidation through three phases that cooperate and execute in sequence on a single schedule: light (sort and stage short-term material), REM (reflect and surface themes), deep (promote durable facts into MEMORY.md). Only deep writes to MEMORY.md.

  • Turn it on with plugins.entries.memory-core.config.dreaming.enabled: true (default true); the sweep cron job is managed automatically by memory-core, so no manual openclaw cron add is needed.
  • Switch it from chat with /dreaming on|off; check it with /dreaming status (or /dreaming//dreaming help). Channel owner status or gateway operator.admin is required for on/off; status and help remain available to anyone who can run the command.
  • Phase output meant for humans goes to DREAMS.md (or an existing dreams.md). By default (dreaming.storage.mode: "separate") each phase also writes a standalone report to memory/dreaming/<phase>/YYYY-MM-DD.md; set mode: "inline" to merge reports into the daily memory file instead, or "both" to get both.
  • Both scheduled and manual memory promote runs rely on the same deep-phase ranking signals and default thresholds; explicit CLI flags override only for that single run.
  • Scheduled runs spread out across every configured agent's memory workspace.

Defaults for scheduling (plugins.entries.memory-core.config.dreaming):

KeyDefault
frequency0 3 * * *
phases.deep.minScore0.75
phases.deep.minRecallCount3
phases.deep.minUniqueQueries3
phases.deep.recencyHalfLifeDays14
phases.deep.maxAgeDays30
phases.deep.maxPromotedSnippetTokens160
{
  "plugins": {
    "entries": {
      "memory-core": {
        "config": {
          "dreaming": {
            "enabled": true
          }
        }
      }
    }
  }
}

For the complete key list and phase details: Dreaming, Memory config reference.

SecretRef gateway dependency

When active memory remote API key fields are set up as SecretRefs, memory commands pull their values from the active gateway snapshot; if that gateway is not reachable, the command stops right away. A gateway supporting the secrets.resolve method is required here; older gateways respond with an unknown-method error.

3,342 words · updated Sep 1, 2026