Consolidation, episodes and procedures
How consolidation turns a run's memories into episodes, facts and procedures, resolves contradictions, and learns from repeated success.
Consolidation turns a task's (run's) memories into durable, organized knowledge: the task itself becomes an episode, memories are distilled into facts, contradictions are resolved, and successful repetitions become procedures.
When it runs
| Trigger | How |
|---|---|
| At the end of a task | MCP consolidate(runId, goal?) or POST /v1/memory/consolidate |
| If you forget | If the maintenance service is running, runs that receive no new memories for 30 minutes (checked every 5 minutes by default) are consolidated automatically. The maintenance service runs in the background host started with Runtime:Mode=service, or in the API if MemoryMaintenance:Host=api is set. In a local install that starts only the API, it does not run by default. |
| From the console | Can be started manually from the project's maintenance page; the job runs in the background and its status can be tracked. |
curl -s -X POST $API/v1/memory/consolidate -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"workspaceId\":\"$WS\",\"runId\":\"billing-refactor-12\",\"goal\":\"Restructure invoice numbering\"}"
# {"status":"consolidated"}Required permission: curate. The request runs synchronously.
Steps
-
Episode. An episode is opened for the run; every memory in the run is an episode event.
-
Facts. Promotable memories become facts:
decision,correction,violation,approved_pattern,artifact_ref,preferenceare promoted as is;rawtext is parsed into facts. If an LLM is available, each fact is extracted as a single, self-contained, actionable statement; preferences get thepreferencetype. Without an LLM, the text is split into clauses.
Facts are linked to their source episode and their source kind is marked
derived. -
Entity linking. Names of people, organizations, places and concepts in facts are extracted and linked to memories; the entity leg in search uses them.
-
Contradiction check (below).
-
Episode score and procedures (below).
-
Abstractions. Generalized knowledge is produced from same-type facts in recent successful episodes; it is linked to the source facts with
DERIVED_FROM. -
Tenant rule candidates. If the same decision or approved pattern exists in at least two different projects, it becomes a tenant-wide rule candidate; it has no effect until an admin approves it.
-
The run layer is cleared and a
categorizewebhook event is emitted.
MCP add_memory already writes memories durably; when consolidation writes them again, the duplicate check merges them into the existing memory instead of duplicating them.
Steering extraction
There are two ways:
- Per call:
extractionInstructionsin thePOST /v1/memory/consolidatebody (e.g. "Extract only reporting and communication preferences."). The MCPconsolidatetool does not take this parameter. - Per workspace: categories. Each category defines which types get promoted and an optional extraction instruction. Default categories:
decisions,corrections,violations,approved_patterns,preferences,conversation(raw).
curl -s "$API/v1/categories/$WS" -H "Authorization: Bearer $KEY"
curl -s -X POST "$API/v1/categories/$WS" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"name":"conversation","description":"Conversation lines","promotableTypes":["raw"],
"extractionPrompt":"Extract personal preferences and exact dates; skip greetings.","isEnabled":true}'A per-call instruction takes precedence over the category instruction. Instructions only take effect if an LLM is configured. There is no single tenant-wide extraction instruction. Categories can also be managed from the console's Settings → Categories / Extraction pages.
Contradictions
Consolidation compares each new fact with similar memories:
| Situation | Result |
|---|---|
| New decision vs. a very similar old decision | The old decision is superseded. |
| Two corrections on the same topic | The newer one supersedes the older if it is at least 24 hours newer; if they are closer in time, it is flagged as an open contradiction. |
| Correction ↔ decision | The correction wins; the decision's confidence drops and it is superseded. |
| Violation ↔ approved pattern | The pattern's confidence drops. |
| Workspace memory ↔ tenant-wide rule | The workspace memory's confidence drops; an objection note is added to the tenant rule's history. |
Open contradictions appear in explain_memory output and raise the risk component of the memory's trust score. Resolve them with supersede_memory. Direct writes (add_memory / append) do not go through the contradiction check; it runs only during consolidation.
Episodes
Each episode carries a goal (goal), summary, success score, start/end time, and a link to the previous episode.
curl -s "$API/v1/episodes/$WS?limit=10" -H "Authorization: Bearer $KEY"
curl -s -X POST $API/v1/episodes/search -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"workspaceId\":\"$WS\",\"query\":\"invoice numbering\",\"topK\":5}"MCP: search_episodes(query, topK). Searches also automatically return similar episodes in the relevantEpisodes section.
The success score is first estimated from the run's content (low if there are violations, high if there are approved patterns); it is recomputed when the actual outcome is reported with report_outcome.
Procedures
A procedure carries a name, trigger, goal, steps, things to avoid (anti-patterns), validation counts and confidence.
- Formation: every approved pattern in a successful episode becomes a procedure (steps come from the episode events); in addition, high-confidence decisions/patterns reinforced by at least three pieces of evidence are promoted to procedures.
- Strengthening/weakening: if a similar procedure is applied again and succeeds, it is validated; failed runs increase the failure count and add things to avoid.
- Use: every search returns the most relevant procedures in the
proceduressection.
curl -s "$API/v1/procedures/$WS?query=invoice&limit=10" -H "Authorization: Bearer $KEY"
curl -s -X POST $API/v1/procedures/validate -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"workspaceId\":\"$WS\",\"procedureId\":\"<id>\",\"success\":true}"MCP: list_procedures(query?, limit).
Limits
- Extraction, contradiction checks and entity linking are not done at write time; they happen in consolidation.
- Fact parsing and abstraction quality depend on the LLM configuration; a default self-hosted install runs rule-based.
- At most 500 memories per run and at most 20 facts per memory are processed (configurable).
- A workspace-level "durable after approval" candidate stage is optional (
promotion.workspaceCandidates.enabled); when enabled, consolidation facts are hidden until an admin approves them.
Related pages
Updating, superseding and deleting
Choose between updating a memory in place, superseding it with a newer one, or deleting it, and understand what each does.
Blocks and user profiles
Pin information the agent should see in every task with memory blocks, and keep per-end-user profiles that join the context when a userId is given.