Projects / Hermes
An In-RAM Memory With a Jump Point to the Archive
The first piece in this series was about the decision. This one is about the machine. How does a memory that lives outside the prompt, that the agent tends itself, and that must be faster than a text file — actually get built?
The answer is deliberately unglamorous. No vector database cluster. No cloud. No orchestration layer. One small store, a local model, and a rule about where the deep content lives.
What follows is the working shape of that machine, the way an engineer would sketch it on a whiteboard — not the spec sheet. The schema, the exact mechanisms, and the benchmark runs live in the lab notes; they are thesis material, and they are ours. The architecture is for everyone.
One File, Loaded Whole
The store is a single SQLite file. One table. The schema is boring on purpose: an identity, the fact itself as one compact standalone sentence, its vector, its timestamps — and one optional field whose entire job is the subject of a later section.
No pending table. No review queue. No soft-delete column. A delete is a delete — the row is gone, and it is gone on purpose, by the owner. There is no “archive anything older than sixty days.” No expiry. No rotation.
The design assumption is monotonic growth. The memory is meant to grow, and it is meant to grow forever, within reason. So the identity column is append-only and never renumbered: every fact keeps its coordinate for its whole life.
And the whole store loads into RAM at boot. That is the move that makes the speed condition real. At this scale — thousands of facts, not billions — RAM residency is not a stunt; it is the obvious layout. The read path never touches disk: a read is a dictionary lookup in process memory, not a syscall, not a round trip. The file on disk is the persistence; RAM is the working memory. You never query the disk for a read. You query the thing that is already in your head.
The Local Lane
Semantic recall needs embeddings, and the design has one non-negotiable constraint that shapes the whole choice: no cloud. No data leaves the machine. No extraction API, no vector service, no endpoint that sends the agent’s memory out to a third party and back.
So the embedding model runs locally: a small 768-dimensional model, served over a localhost endpoint on the same machine. The memory sends the question; the model returns a vector; the vector is compared against the vectors already held in RAM.
The scan is the cheap part. A few thousand 768-dimensional comparisons in numpy run in single-digit milliseconds. The scan was never the bottleneck, and it never will be — not until the memory grows to tens of thousands of entries, which is a problem for a future version, not a present one. The cost is the query embedding itself: 50 to 200 milliseconds on a CPU — the honest wall named in the first piece. It is the price of “what do I vaguely remember about this?”, and it is paid in full, every time, on the local machine.
There is a degradation path for when the lane is down. If the local endpoint cannot be reached, recall falls back to lexical matching over the fact text — keyword search, weaker in quality, and loud about it. The fallback is logged and labelled, never silent. A memory that quietly switches to a worse mode and pretends nothing happened is a memory you cannot trust. A memory that says “the semantic lane is down, I am matching by keyword” is a memory that is still telling you the truth about what it just did.
The Jump Point
Here is the part of the architecture most worth understanding, because it solves a problem that is easy to miss until you have lived inside it.
A memory fact is a condensation. One compact sentence. But sometimes the fact is a summary of something much bigger — a whole conversation, a long event, a decision with a long history. The sentence in the memory is the map coordinate. The full, verbatim, unedited record is somewhere else.
That somewhere else is the archive — the kredenc, in this system’s own vocabulary: a vault of verbatim cards, every card held in fixed frames at byte-exact coordinates. Every card already knows where it lives: an offset and a length. The kredenc has its own story elsewhere on this site; what matters here is only what it is — the place where nothing is summarized.
The problem, before the seam was built, was that the address was a content hash. An excellent machine key; a terrible working handle. Getting from a fact to its verbatim meant two lookups where there should be one: find the shard, then rummage inside it. Two slow steps for a jump that should be one.
The fix was to make the jump a single verb. A fact may carry a pointer to its own card — the optional field from the schema — and one resolve call turns that pointer into the verbatim record with a single indexed seek. No hunting. No rummaging. One step, from the backpack to the archive.
Think of it as the difference between knowing “the thing is in the filing cabinet somewhere, probably the third drawer” and knowing “it is in the third drawer, second folder from the left.” The first is a search. The second is a jump.
The rule that governs this seam is worth quoting in full, because it is the whole philosophy in one line:
The matrix never duplicates kredenc content — small fact plus pointer in the backpack; verbatim depth in the archive. A map coordinate, not a photocopy of the farm.
The memory holds the coordinate. The archive holds the land. The memory never makes a photocopy of the farm and keeps it in its pocket. It keeps the address.
The Spare Tire
The last piece is the one that sounds least impressive and is the most important for trust.
A file can break. A disk can corrupt. A migration can go wrong. And a memory system that crashes when its store is unreadable is a memory system that takes the whole agent down with it. That is not a memory. That is a single point of failure with a personality.
So the design keeps a spare tire. The old memory files — the very files this whole project was built to replace — are not deleted. They are kept, in full, as a fallback corpus. In normal operation they sleep; the system never touches them. They wake in exactly one case: the store cannot be opened.
And the degraded mode has a contract. It announces itself, with the reason, everywhere the agent looks. Recall continues over the fallback corpus — lexically, labelled as degraded. And the write tools are refused, all of them, until the real store returns. A broken memory is never written around, because writing to a memory that is known to be broken is how the real data gets lost.
The outage is visible. In the prompt, in the log, in the behaviour. Never silent.
This is the engineering expression of the whole system’s one rule: a memory that hides what it is doing is not a memory. It can be faster than a file. It can hold a jump point to an archive. It can be self-tended, ungated, local, and RAM-resident. But the moment it starts concealing its own state — the moment it degrades quietly, or deletes silently, or writes around its own failure — it stops being a memory and starts being a liability with a heartbeat.
The spare tire is not a feature that was added. It is the same rule, applied to the failure case.
What This Adds Up To
One file. A local lane. A jump point. A spare tire.
None of it is novel. None of it is a research result. The novelty is in what was removed: the gate, the cloud, the rotation, the soft delete, the silent degradation. The architecture is interesting not because of what it does, but because of what it refuses to do.
And it all fits on one machine, in one directory, in a store that, on the day this was written, held thirty-two facts and nothing more.
Thirty-two facts. In RAM. Faster than the file they replaced. With a jump point to the verbatim, and a spare tire for the bad day.
That is not a memory system. That is a memory.
Next — part three, the conversation: The Memory Tends Itself — A Conversation.