AI & Tools

A Memory That Maintains Itself

Architecture diagram. Three sources on the left — a server session, a Windows box and an occasional third machine, each with its own context window — connect by dashed lines to a central node labelled THE STORE, holding more than 600 notes on a network drive. From there a line leads to a panel headed "Before every request", explaining that the lookup runs per request rather than once per session, extracts the load-bearing terms and shows the five best hits. Badges note a measured runtime of 0.7 seconds, read-only access, and quiet failure.
Each session forgets when its window closes; the shared folder is what persists across machines.

I work with several machines and several AI sessions at once. One on the server, one on the Windows box, occasionally a third somewhere in between. Each one knows exactly what is in its own window and forgets it the moment the window closes. Over months that has turned into an expensive pattern: the same question answered three times, the same trap walked into twice, and by the third time nobody left who remembers.

The fix is unglamorous and it is called shared memory. A folder of Markdown files on the network drive, reachable from every machine. It only gets interesting where that folder turns into something that maintains itself — and at the places where exactly that failed.

Before every request, not once per session

The first version was: look into the knowledge store once when a session starts. That sounds reasonable and is far too rare. A session runs for hours and changes subject five times along the way. What mattered at the start no longer matters two hours in, and what would matter now, nobody searched for at the start.

The lookup now runs before every request. A small script takes the text you typed, pulls out the load-bearing terms — preferring anything that looks technical, so paths, version numbers, identifiers containing digits — searches the store with them, and shows the five best hits with their path and one line of context. Over six hundred notes on a network drive, measured runtime 0.7 seconds. That is cheap enough to do it always.

Two properties mattered to me more than hit quality. First: the script only reads. Writing happens exclusively through the service built for it, never straight into the files, because a script with write access to six hundred notes is a time bomb. Second: it fails quietly. If anything goes wrong — network drive gone, file broken, timeout — it emits zero bytes and the request proceeds as normal. A memory that can block access gets switched off after the second outage.

The catch I found by looking

There had been such a mechanism before. A script that loads context at session start, properly registered, active for weeks. I ran it to see what it produced and got zero bytes.

Its own comment held the explanation: it only does anything when the working directory sits inside the knowledge store. Otherwise it exits silently. But I never work inside the store, I work in project directories — the store is the filing cabinet, not the desk. So the script had done nothing in practically every session, without ever saying so.

That is the nastiest class of failure there is: configured, registered, active, ineffective. It looks fine in every overview. You only find it by running the thing and looking at what comes out.

A cleanup service that knows what it may not do

Every five minutes a small service runs in the container that serves the knowledge store. It does two things, and the boundary between them is the actual design.

It repairs what can be repaired mechanically. The writing service had a quirk: on every save it multiplied a particular heading. One became three. Harmless in itself, but it is in twenty-one files, and it breaks the structure that both humans and search tools navigate by. Collapsing duplicate lines is unambiguous and lossless, so a machine may do it. Every change is read back and compared through a checksum; if it does not match, the change counts as not having happened.

And it moves nothing. The inbox has a decent backlog — over a hundred notes, all from the last two weeks. The temptation to file that automatically is strong, and I deliberately did not give in to it. Where a note belongs depends on its subject, on what it connects to, and sometimes on whether it ought to become two notes. A service deciding that from filenames produces more disorder in a week than it tidies in a month.

What it does instead: write its findings to a file. How many notes sit in the inbox, how many were repaired, which ones have no header fields. On its first run it found three notes without headers that nobody had noticed for weeks.

A watchdog that asks the right question

The service everything is written through was broken for three days once. Not crashed — it was running. The process manager reported it as active, memory use was normal, nothing odd in the log. It simply answered every request with an error code.

A watchdog that only asks “is the service running?” would have reported “all fine” for three days. So mine does not ask the manager, it asks the service: every two minutes it calls the endpoint and looks at the answer. If none comes, it restarts — and then calls again, because a successful start command is not proof of a working service. If it stays broken, it writes into its log that a human is needed now. Some failures no restart will fix, and a watchdog that cannot admit that hides them in an endless loop.

Handover between machines

The part that surprised me most is the simplest: a kanban board as a Markdown file. Columns are headings, cards are list items, details indented beneath. No plugin, because a session on another machine reaches the store as text and not as a rendered interface.

With that, one session can hand work to another that does not exist yet. A card carries the finding, the condition for “done”, and a marker for which machine it is meant for. Whoever takes it moves it and signs it — before the first minute of work, not after, otherwise two sessions grab the same card.

One detail there was taught to me the expensive way: the writing service cannot move cards. It only appends. Try anyway and you append text at the bottom while the card stays at the top — the board then looks as if the task were assigned twice. Moving works only as read, modify, write the whole file back, compare the checksum.

Correct rather than work around

The most important rule is not a technical one. When a note stops being true it is not deleted and not silently worked around; it gets a dated notice at the top pointing to the version that holds.

Why that is not a formality, I noticed this week. I was chasing the reason for an error about a network share that supposedly no longer existed. The knowledge store had three notes on it, all describing it as active and load-bearing, one even quoting the configuration line. All three predated a server migration and read like the present state. Had I believed them, I would have treated the dead entry as indispensable and never fixed the error.

What fixed it was a measurement on the running system: not a single configuration still referenced the path, the directory was empty, and the file server answered “does not exist” for exactly that export while every neighbouring one answered cleanly. Out of that came the rule I consider the most useful of the whole build:

On intentions, decisions and history, the document wins. On the current state of a machine, the measurement wins — and afterwards the document gets corrected.

Two panels side by side. Left, what the knowledge store said about a network share: three notes, all describing it as active and load-bearing, one even quoting the configuration line, all of them written before a server migration. Right, what the measurement on the running system said: not a single configuration still referenced the path, the directory was empty, the file server answered that this export does not exist, while every neighbouring one answered cleanly. A strip below states the rule: on intent and history the document wins, on the current state the measurement wins, and afterwards the document gets corrected.
The case behind the rule above: three agreeing documents against one measurement on the running system.

When the search lied without lying

One more story from the same week, because it shows how easily shared memory becomes the opposite of helpful. I was looking for a particular article in the website’s database. Query sent, not a row back. So I widened it, different table, nothing again. After the third empty answer I believed the result and wrote that the article did not exist.

It existed. Two things had gone wrong and both are on me. The tables of this installation carry no usual prefix but a random string assigned at setup. My queries were therefore running against tables that are not there. And I had routed the error channel to /dev/null, because the output is cluttered otherwise. So “this table does not exist” looked exactly like “no results” to me.

A suppressed error channel turns an error into a negative result. That is especially treacherous when you want to claim absence, because absence is the one statement that more searching cannot confirm — it only ever follows from nothing having come back. Since then: anyone about to write “does not exist” leaves the error channel open first and checks whether they were even looking in the right place.

Four cards, each holding one failure that looked like success. First: a session-start script, properly registered and active for weeks, which exits unless the working directory sits inside the store, so its output was zero bytes. Second: the writing service, broken for three days, reported as active by the process manager with normal memory use and a clean log, answering every request with an error code. Third: a kanban card that was appended instead of moved, so the copy lands at the bottom while the card stays at the top and the task looks assigned twice. Fourth: the error channel routed to /dev/null, where a missing table reads as no rows, and three empty answers were believed.
Four cases from this article, each silent in a different way — none announced itself.

What it changes day to day

The most noticeable difference is unspectacular. I ask a question, and before the answer arrives there are five lines above it with paths to notes, two of which I had forgotten. Sometimes none of them is useful. Two or three times a day one of them saves half an hour, because it already says why the obvious route does not work.

The second difference is the handover. I can leave a card on one machine in the evening and continue on the other the next morning without reconstructing the state from memory. For a single person that sounds like overhead. As soon as several sessions run in parallel — and for me they almost always do — it is the difference between collaboration and three people solving the same problem simultaneously.

The third is uncomfortable and therefore valuable. A memory that forgets nothing holds your own mistakes up to you. This week it contained three claims of mine that turned out to be wrong when measured. Without the store they would simply have vanished. With it they sit there, dated, with the correction underneath — and the correction is the more useful entry in the end.

What is still missing

The inbox still does not empty itself, and that is deliberate. The cleanup service reports the backlog, nothing more. Whether that holds up long term I do not know; a hundred notes is still manageable, three hundred would not be.

The search over the store comes in two flavours, and the better one was not set up at all on the machine I worked on this week. I only noticed when I failed to find an article I had written myself. That, too, is now a card on the board — which is roughly the point at which a system starts carrying itself.