For weeks I had the same quiet frustration. I’d tell my agent to remember a goal, an idea, a preference. It would say it saved it. And the next session it acted like the conversation never happened. I’d repeat myself, it would save again, and the loop kept going.

One night I caught myself doing it out loud. I typed in a goal I had already typed three sessions earlier, watched the agent echo back a cheerful “saved to memory,” and knew, before I had even closed the window, that by morning it would be gone again. I tried the obvious things first. I restarted sessions, re-pasted the same facts, even reworded them in case something about the phrasing was the problem. None of it stuck, and I had started to assume this was just what long-running AI was: confident in the moment, blank the next day.

The cause was not a flaky model. The memory file was correct on disk and wrong in practice, and the reason is worth writing down because anyone building on these tools will hit some version of it.

My setup gives the agent, Claude Code in my case, a persistent memory: a plain text file it reads at the start of every session and appends to as it learns things about me and my work. The file itself had been telling me what was wrong, in its own header, the whole time:

# Memory index (always-loaded)
Only the first 200 lines / 25KB of this file load each session;
past that, entries silently drop.

I had scrolled past that line a hundred times without registering it as a boundary that applied to me. The harness loads the first 200 lines, or 25KB, whichever comes first, and no more. Everything past that point never reaches the model. No error. No warning I noticed. And because new memories were appended to the end, the newest things I saved were exactly the ones dropping off the invisible edge. The agent was not ignoring my goals. It literally could not see them. From its side they had never been written. That is the failure worth naming: not a crash, but a silent gap between what you believe is stored and what the system actually reads.

The fix was to stop asking one file to do two jobs. Being always present and being fetched when relevant are genuinely different jobs, and jamming both into one growing file is exactly what broke. So I split the store into two tiers. The first is an always-loaded policy: the core rules and the handful of high-frequency facts, held under the load budget with real headroom so it never spills past the cap. I keep it under 180 lines, comfortably below the 200-line wall, and a check enforces that. The second tier is a lookup catalog, the complete record of everything I have ever asked it to remember (mine is past 250 entries), never auto-loaded, so its raw size does not matter. The agent reaches into it when a topic actually comes up.

Then I made the silent failure loud. The guard is a short script that counts the always-loaded file’s lines and bytes, checks them against the cap, and exits non-zero if the file is over budget, or if a stored memory exists that nothing in the catalog points to, the kind of orphan you would otherwise only find by luck. It turns an invisible degradation into something that stops me before a session even starts. If a system can silently drop your data, the first thing you build is the thing that refuses to let it.

The general point outlived the bug. Every byte you hand a model competes for a fixed budget, and that boundary is usually enforced quietly: truncation, summarization, eviction, most of it without a stack trace and none of it showing up in the file you are looking at. “It is saved” and “it is loaded” are two different claims, and the space between them is where weeks of my frustration had been hiding. On-disk completeness told me nothing about what the model was actually reading, and I had trusted the wrong one.

I had spent those weeks blaming the model for being forgetful. I had built it a memory it was structurally unable to read past line 200.