A model with a context window has working memory. It does not have memory. Close the session and everything it learned about you, your project, and its own mistakes is gone. For a chatbot that's fine. For an agent you want to delegate real, ongoing work to, it's disqualifying — you cannot build a working relationship with something that reintroduces itself every morning.
When I built the memory system inside Froots, I deliberately avoided anything exotic. No bespoke database, no vector-store-as-a-product. It's markdown files on disk with strong conventions. The discipline is in the structure, not the technology.
Three files, three cognitive roles
The core insight is that "memory" isn't one thing. Lumping it together is why most attempts feel mushy. I split it by what the memory is for:
context.md— what I'm working on right now. The active project, current goals, open threads. This is the most volatile file; it gets pruned as focus shifts. It answers "where were we?"decisions.md— choices made, and the reasoning. When a direction is chosen, an entry goes here with the why, not just the what. Future-you doesn't need to know that you picked Cloudflare; it needs to know why, so it can tell when the reason no longer holds.learnings.md— mistakes and corrections. When the agent gets something wrong and gets corrected, when a non-obvious gotcha bites, it's recorded here. These are the entries that actually change future behavior.
Separating these isn't bureaucracy. Each answers a different question the agent asks at a different moment, and keeping them apart keeps each one dense and useful.
Append, never overwrite
The most important rule: memory is append-only. New knowledge gets a new dated heading; old entries stay. You never rewrite history to "clean it up."
This matters because the trail is the value. When an agent's behavior drifts, you want to read back the sequence of decisions and corrections that produced it. An overwritten file is a memory with the receipts shredded. A "## 2026-06-08 — switched to X because Y" heading appended below the last one keeps the whole reasoning chain inspectable — which is the same legibility principle behind agents you can watch work.
Two ways to recall
Writing is only half of it. On every turn, the system semantically searches the memory files for the handful of chunks most relevant to what you just said, and injects them into context automatically. The agent doesn't have to remember to remember.
For the cases where automatic recall isn't enough, there's explicit search — a natural-language query against the same store when the agent knows it's looking for something specific. Chunking by markdown heading means each retrieved piece is a coherent thought, not a window sliced mid-sentence.
Separate who-you-are from what-you-learned
One more split that earned its keep: persona is not memory. Identity, voice, and standing preferences live separately from working notes. Persona is injected every session because it's always relevant; memory is retrieved on demand because most of it isn't relevant most of the time. Mixing them means either drowning every prompt in stale notes or losing the stable traits that make the agent feel consistent.
Why simple won
I could have built something more impressive. But markdown files have properties a clever database doesn't: a human can open them, read them, edit them, and trust them. When your agent's memory is a file you can inspect, you can fix it. That auditability is worth more than any amount of architectural sophistication — and it pairs naturally with browser automation that always reads back its own actions.
This is the kind of unglamorous infrastructure that decides whether an agent is a toy or a partner. It's the foundation under everything in Froots.
Dylan Worrall is the founder of Froots and Soshi Labs. He writes about agent architecture and shipping dependable AI products.