# How we built Engrava: from cognitive-architecture research to a production library

> Source: <https://dev.to/sovantica/how-we-built-engrava-from-cognitive-architecture-research-to-a-production-library-4i7i>
> Published: 2026-07-14 20:23:39+00:00

Deterministic consolidation, a typed graph in SQLite, and an honest look at what agent-memory benchmarks can and can't measure.

You're building an agent. It answers questions across many sessions, and by session three it has forgotten what it learned in session one.

The reflex is to put a vector database in front of it - and now it remembers a blurry average of everything, ranked by cosine distance, contradicting itself and unable to tell a three-week-old preference from a stale throwaway. A graph database gives you structure, at the cost of a second persistence model with its own query language and deployment. A managed memory service starts you in a few lines, and moves the decision of what your agent remembers onto someone else's infrastructure.

Underneath all of them is one problem: if every plausible fact is written the moment it appears, memory turns into an accumulation layer instead of a judgement layer. Engrava is our answer to that - local, structured, and deliberate about what it keeps in reach. Here is how it is built, and why.

Before the storage design there was a long stretch of reading cognitive-architecture research, circling one question: what does a long-running agent actually need from memory if that memory has to stay inspectable? That framing is the reason Engrava is a typed graph and not a bag of embeddings, the reason consolidation is deterministic instead of an LLM rewrite pass, and the reason extraction stays above the database instead of hiding inside it.

Engrava is a typed knowledge graph with hybrid search, in a single SQLite file. Thoughts are nodes; typed edges carry the relationships a flat vector can't - that A caused B, that C specializes D. Retrieval fuses vector similarity, keyword match, recency, and priority rather than leaning on cosine distance alone. Turn on the journal and every thought and edge mutation is recorded in a tamper-evident SHA-256 chain. It is all in the free package.

Every thought has a priority, recomputed each time the consolidation cycle (the dreaming: block) runs - one deterministic pass over the store weighing five signals: recency, staleness, confirmation, confidence, frequency. They combine into a score, checked against gates before promotion:

```
dreaming:
  enabled: true
  signals: [recency, staleness, confirmation, confidence, frequency]
  promote_threshold: 0.75
  gates:
    min_confirmations: 2
    max_promoted_per_run: 20
```

The default is conservative on purpose: with min_confirmations: 2, a fact the agent has seen once is not promoted - it stays fully retrievable, just not lifted into the active set until the agent has re-confirmed it. That is the point of the cycle: keep memory a judgement layer, so a single noisy pass can't reshape what the agent treats as settled. No language-model call, no network call, no embedding recomputation - arithmetic over SQLite rows, same inputs and same outputs every run, and the policy is a YAML file you can review in a pull request.

Three findings shaped three choices. Diekelmann & Born (2010) describe memory stabilization during sleep as selective - the brain keeps a subset of traces, not all of them, which is what the priority score and the promotion gates do. Yassa & Stark (2011) describe how the hippocampus keeps similar experiences from collapsing into one average, so in Engrava thoughts stay distinct nodes and similarity doesn't auto-merge them. Rao & Ballard (1999), and Clark's synthesis (2013), frame the brain as stabilizing what repeated experience confirms, which is where the confirmation and confidence signals come from. We did not build a brain - we took the pressures biological memory evolved under and applied them to a file on disk.

We didn't tune Engrava to top a leaderboard. And dreaming - the consolidation cycle that gives Engrava its character - doesn't move our retrieval benchmark. We turned it on, we turned it off, and the accuracy barely shifts.

It isn't a bug we're hiding; it's a sign the benchmark is measuring something dreaming isn't for. These benchmarks are short-horizon question-answering over a fixed transcript. Dreaming is lifecycle management - over the weeks an agent stays alive, it decides what stays in reach and what settles out, so the store doesn't rot into an accumulation layer. Whether that discipline pays off over long horizons is genuinely hard to measure, and the benchmarks that exist can't see it.

Comparable evidence across consolidation systems is thin, too: implementations, datasets, reader models, and evaluation setups vary too much for clean comparisons, and the underlying sleep-consolidation research is itself contested. So we won't attach an improvement claim to dreaming that our own retrieval test doesn't support. Dreaming is deterministic, inspectable, and does a specific job; whether that job matters is yours to decide.

The wider point holds for the field: half of these benchmarks aren't measuring the same mechanism. Some run a language model inside the memory pipeline; some don't. And the reader model can move the headline number more than the memory architecture does - hold the memory fixed, swap in a stronger reader, and the same system posts a very different score. When we do publish a number, we publish the whole run - reader, judge, dataset, setup - so anyone can reproduce it.

SQLite runs inside the host process, writes to one file, ships as one library, and is one of the most-tested databases in existence. We wanted that posture. Engrava is a Python library - pip install engrava, and the store is a file on your disk. No server to run, no port to open, no separate auth; your agent imports it like any dependency, nothing leaves the host unless you wire up a remote embedding provider yourself, and it is MIT-licensed. It is not a multi-tenant fleet service - if your agent is a horizontally-scaled cluster needing shared memory across machines, embedded is the wrong shape. For a single agent, it is usually the simpler fit.

When we started, this was fairly open space. By the time we shipped it wasn't - several teams, Anthropic among them, had shipped consolidation under the same "dreaming" name, borrowing the same sleep metaphor, around the same time. The category converged fast. What separates these tools now isn't the vocabulary; it's whether the consolidation is something you can open up, configure, and run yourself, or something that happens elsewhere on your behalf.

Engrava is live on [PyPI](https://pypi.org/project/engrava/) - the graph, deterministic consolidation, hybrid search, the audit journal, and MindQL are all in the free package.

If you're building an agent, try it:

```
pip install engrava
```

The repo is on [GitHub](https://github.com/sovantica/engrava); issues and discussions are open.
