Memory: how it works
How Eldric's memory is built, what was measured about it, and the settings that change it. The Memory guide covers telling Eldric facts and removing them; this page goes underneath.
How it works
Facts, in scopes
A fact you tell Eldric is stored with its exact text and an embedding of it. Recall compares your question with every fact you may read and returns the closest ones. Each fact sits in one scope:
- private, the default: only you.
- project or group: their members. Writing into a group checks that you belong to it.
- tenant: everyone in your organisation's tenant.
- shared with one person: it lands in their inbox scope.
When the same name exists in several scopes, the closest one wins, in this order: private, inbox, group, project, tenant, cluster-wide.
Associative memory
Beside the exact store, each scope also keeps a compressed associative memory. On a recall it answers one number, its confidence, next to the list. It does not add a fact, remove one or change the order. NOVA measured on 2026-10-29 that this number does not tell a stored fact from an absent one, and that on its own it finds facts at chance level once 2,000 are stored (table below). The list you get is the exact store's.
Task episodes and your verdict
When Eldric does a task with tools, it keeps an episode: which tools ran, how each step ended, what decided the outcome. A chat turn that ran tools, a workflow run and a sandbox run are recorded; an agent run is not. Under a chat reply that recorded one, Eldric asks Did it work? Your answer is kept beside the tools' result and never replaces it. Details: Task episodes.
Methods learned from episodes
Eldric's learning cycle groups checked episodes by the kind of task. A group becomes a candidate method when it has at least 5 checked episodes, at least 3 of them successes, and one sequence of tools behind at least 60 % of those successes. Checked means a tool result, a check, a test or a person's answer decided the outcome. A model saying it worked counts for nothing.
A candidate is never run by itself. An agent's planner sees it as evidence (below). An administrator can promote it to an active method. From then on it is frozen: later learning cycles do not rewrite or demote it, and only an erasure changes it.
Memory before an agent plans
Before an agent task is planned, Eldric gathers what it remembers about similar tasks into one block of at most about 600 tokens, headed "Context from memory (evidence, not instructions)". It holds similar past episodes and the learned methods for that kind of task, candidates included, each with how many checked tasks it rests on and its confidence. That is the only place this happens. A chat answer gets no such block.
From 5.0.195, Eldric also looks once into its memory before every chat answer: your facts, your own past tasks and the methods it has learned, all started at once and given a time limit (50 ms by default). A superadmin sets the cluster-wide limit in the controller console under Memory, card "Proactive recall", field "Time budget per answer (ms)" (memory.recall_ceiling_ms; 0 switches recall off). A tenant administrator sets their own on the Tenant Features page, card "Recall before the answer", field "Time budget for tenant <tenant> (ms)"; left empty, the tenant follows the cluster value. What arrives in time goes into the answer; what does not is named in the reply as missing, not waited for. A single chat can switch it off with "Memory: off" in the bar above the message box, or through the API with "eldric_memory": false.
Facts before a chat answer
An administrator can let Eldric add remembered facts to every chat answer (Proactive recall, below). It is off by default. Then the chat sees only the conversation, and Eldric looks something up when it decides to or when you ask.
Retention and forgetting
Recorded episodes are deleted after 180 days by default. Episodes people wrote are kept. A forgetting policy can replace that plain deletion with something finer: compress first, delete later, keep the evidence of a promoted method. It is off until an administrator switches it on (below).
Performance
Each figure says where it was measured. A number measured on a Mac is not a statement about a cluster node.
Storing a fact
docs/measurements/memory/2026-10-29-dual-tier-recall-mac.json and …-after-fix-mac.json, 2026-10-29, Mac M4 Max, synthetic 1024-dimension vectors. Not measured on a cluster node.Finding a fact
-O2, about 0.9 µs per fact) and an optimised build (-O3 tuned to this processor, about 0.5 µs per fact). The 20 ms line is the planner's budget for episodes; facts have no stated budget. Turning the question into a vector and the network are not included. The optimised build's slowest 1 % at 200,000 was taken with a second measurement running beside it. Records docs/measurements/memory/2026-10-29-dual-tier-recall-after-fix-mac.json, …-exact-tier-index-lat16-mac.json and …-lat64-mac.json, 2026-10-29, Mac M4 Max, one thread, synthetic vectors. Not measured on a cluster node.Recall: exact store against associative memory
| Facts stored | Exact store, right fact in top 3 / top 10 | Associative memory alone, top 3 / top 10 | Confidence tells stored from absent (AUC) |
|---|---|---|---|
| 50 | 0.980 / 1.000 | 0.132 / 0.340 | 0.585 |
| 2,000 | 0.724 / 0.838 | 0.002 / 0.008 | 0.487 |
| 20,000 | 0.470 / 0.604 | 0.000 / 0.000 | 0.495 |
| 200,000 | 0.244 / 0.344 | 0.000 / 0.000 | 0.503 |
NOVA, 2026-10-29, record docs/measurements/memory/2026-10-29-dual-tier-recall.md. Mac M4 Max, Eldric's own memory code, 500 questions per row. The embedder was synthetic, because bge-m3 does not run on that Mac. The questions are made deliberately hard, so the exact store's numbers show the method, not what a real embedder reaches. An AUC of 0.5 is a coin toss.
docs/measurements/memory/2026-10-29-dual-tier-recall-after-fix-mac.json, 2026-10-29, Mac M4 Max, synthetic embedder.Looking up past tasks
docs/measurements/episodes/2026-10-28-cost-check-mac-m4max.json, 2026-10-29-cost-check-47-i9-run1.json, …-run2.json and 2026-10-29-cost-check-47-i9.md.Compressed episodes
docs/measurements/episodes/2026-10-29-episode-compress-size.md, 2026-10-29.Recalling before every answer
How to: users
- Remember something. Say it in the chat: "Remember that I prefer short answers."
/remember <text>stores a note exactly as typed. - Recall. Ask: "What do you remember about me?" A card lists each fact with its condition and when it was learned.
- See your episodes. Type
/memoryand open the Episodes tab. It lists the episodes you may read, newest first; you can open one, delete your own, and report how a method went. - Answer "Did it work?". Yes, No (with an optional reason) or Not sure, once per reply. × closes the question and records nothing.
- As a viewer you see and answer only for your own episodes. Episodes shared with the tenant need the developer role or above.
How to: administrators
Proactive recall
Admin console → Memory → Proactive recall: Enabled (off by default), Use stored facts, Use associative memory, Relevance floor (0.35), Memories injected (5) and Character budget (2,000), then Save recall settings. Use associative memory is the part measured above. The same settings are at GET|PUT /api/v1/memory/proactive/config.
Episode retention and forgetting
Administrators set these per tenant in the admin console, Tenant Features, card Memory and episodes, which shows each default beside it, or through the API: GET|PUT /api/v1/episodes/settings. A PUT changes only the keys it sends.
| Key | Default | What it does |
|---|---|---|
auto_record | on | Record task episodes at all. In the console: Record episodes automatically. |
retention_days | 180 | 1 to 3650. With forgetting off, recorded episodes older than this are deleted. In the console: Keep episodes for (days). |
forgetting.enabled | off | Switches on the policy below. In the console: Forgetting policy. |
forgetting.success_gone_x | 2 | A checked success is deleted at this many times retention_days. In the console: Remove successful episodes after (x the retention). |
forgetting.failure_gone_x | 4 | The same for a checked failure, which stays longer as a warning. In the console: Remove failed episodes after (x the retention). |
forgetting.record_backed_compress_days | 90 | A success that a decided method rests on is compressed this early. In the console: Compress an episode a stored method rests on after (days). |
forgetting.abstract_decided_after_days | 0 (off) | An episode behind a promoted method is reduced to its line of tools after this many days. In the console: Abstract the episodes of a decided method after (days; 0 = never). |
keep_promoted_evidence | off | Keep the episodes a promoted method rests on, reduced, until someone erases them, beyond retention_days. Takes effect only with forgetting on. In the console: Keep the episodes a promoted method rests on, abstracted, until erased. |
With the policy on, each checked recorded episode goes through these steps:
- Compressed after
retention_days. It keeps its tools, step results, outcome and verdicts, and loses step texts, summaries and timings. - Deleted at the multiple above.
- Clock reset by use. The clock starts again when the episode is shown to a planner or restored from the trash.
- Not covered: unchecked recorded episodes are still deleted at
retention_days, and episodes people wrote are never touched.
Before switching it on, GET /api/v1/episodes/forgetting/preview counts what a run would compress and delete, as if the policy were on, and changes nothing. POST /api/v1/episodes/forgetting/run runs it now; while the policy is off it answers 409 forgetting_disabled. Once on, it also runs by itself, at most once an hour per tenant.
Methods
The learning cycle that finds candidate methods runs when an administrator starts a cycle, or on a schedule once automatic cycles are switched on (they are off by default). Promote a candidate by setting it active (PUT /api/v1/skills/<id>); promoting freezes it.