What belongs in Memory
These are reasonable Memory entries.- “Regenerate the checked-in client after the public HTTP contract changes.”
- “This project requires Python 3.11 or later.”
- “OpenClaw project mode still isolates data by agent.”
- “Run contract tests next and inspect generated-code drift.”
Memory is not an overwritable text row
A Memory entry looks like one conclusion, but it has three identity layers.Artifact Revision
An effective change to the Memory lifecycle creates another immutable Artifact Revision. The Revision stores the manifest and change set at that point.Logical entry
entry_id identifies one piece of long-term knowledge. A revision of its content remains the same logical entry.
Entry version
entry_version_id identifies the exact content version. A revision creates a new entry version and retains its previous_version_id, evidence, and creating Memory Revision.
An entry_id alone is not an exact citation. Maintenance operations also need the relevant Memory Revision and entry-version ID.
The manifest defines current state
The manifest in a Memory Revision is the authoritative directory for that Revision. Each item records a stableentry_id, an exact entry_version_id, the content hash, and an active or inactive state.
retire changes an entry to inactive so default recall stops selecting it. The content and historical Revisions remain available.
Revision is not in-place replacement either. It creates the next entry version, and the next Memory Revision points its manifest at that version.
Two write paths
Once identity and the manifest are clear, look at how content gets in.Explicit write
When you know what should be retained, callremember_memory directly.
expected_revision for concurrency control. If the content actually changes, it returns a Memory ref and an exact entry Citation. If the canonical form matches an existing entry, the write is no-op and may return the current Memory ref with entry=null.
Extraction from Source
The automatic path captures Source first, then lets the scheduler orflush_memory process a Source window.
Explicit writes and Source extraction can both produce Memory, but their lineage differs. To prove that an entry came from a particular Source, inspect its exact
source_refs rather than relying on text similarity.Revise and retire
An entry that already exists can still change, or it can be retired first. A revision targets the current exact Citation. New content creates another entry version, while the old version remains readable. Retirement also needs an exact target.include_inactive supports audit. Old Artifact Revisions and entry versions still exist.
If another worker advanced the Memory head, an older Citation conflicts. Read the current state and inspect the difference before deciding what to do. Do not guess the next Revision.
How search works
After a write, the next request has to find the entry again. Memory search does more than rank every text by one similarity score. It selects the current Memory head, then chooses a mode from the request and available capabilities.
If query embedding is temporarily unavailable or times out,
auto may fall back to FTS when FTS is available. An explicit vector or hybrid request must not silently change modes. The caller receives a capability error.
Fusion and reranking
Hybrid search combines FTS and vector ranks with reciprocal rank fusion. The current RRF constant is 60. Vector admission converts unit-normalized L2 distance to cosine similarity and applies a minimum similarity threshold. Results keepmatched_by, showing whether FTS, vector, or both contributed.
Optional reranking runs after retrieval. It may change final order, but it does not modify Memory or the search index. Once reranking begins, it uses the selected Revision snapshot instead of silently switching when another write advances the head.
PreparedContext is not a copied search response
A search hit does not mean this request will inject the whole entry.prepare_context retrieves coarse candidates, then a builder selects final content under one shared UTF-8 byte budget.
The current builder uses several explicit limits. It takes up to 16 coarse Memory candidates and up to 8 Experience candidates. The final set has at most 8 items, and at most 2 of those may be Experience. Each item is capped at 2000 bytes.
These are current implementation details and may change. The stable contract is that final content fits max_bytes, includes exact Citations, and is labeled untrusted_history.
Two result states are normal.
Walk through the OpenAPI example
Write Memory explicitly.memory_ref should identify the current exact Revision. The result should include entry_id and entry_version_id. matched_by should match the requested mode. The Citation from prepare_context should point to the same entry version.
Then revise the content.
Easy misdiagnoses
auto returned FTS instead of hybrid
Check the embedding model, profile ID, dimension, backend vector capability, and whether current Memory heads have complete vector projections.
Flush processed Sources but created no Revision
The model may have returned no-op, or canonicalization may have found duplicate content. Inspect Source lineage and the change set.Search returned a hit, but PreparedContext is empty
PreparedContext also applies relevance, deduplication, and byte-budget constraints. A search hit is not guaranteed final selection.The Memory head changed during reranking
The current search keeps the Revision snapshot selected at the start. A later search reads the new head.How you know the layers are separate
- Artifact Revision, entry ID, and entry-version ID are three separate identities.
- Retire means deactivate, not delete.
- An explicit write needs no model and no Source first.
- An extraction candidate must pass evidence and domain validation.
automay fall back, but an explicit vector or hybrid request must not silently change modes.- PreparedContext is still temporary, untrusted, and bounded.
Next
See who continues the work
Memory answers what the project should remember later. Handoff answers who continues and where they begin.
Write the first Memory
Start a local Server, write a Memory, find it, then get a cited PreparedContext.

