TLDR; The Claude memory debate conflates two problems: per-project working context, which Claude Code’s own memory already handles, and cross-project transferable knowledge, which it doesn’t. I built a lightweight markdown vault plus a Stop-hook nudge for the second problem, not another cathedral-scale tool.
In early April, AI Twitter spent a fortnight arguing about how to give Claude a proper memory. Three tools, all interesting, all solving the same underlying problem in different ways. Most of the conversation missed part of the problem, and the picture has shifted in the months since.
The tools are good. In specific situations I’d reach for each of them without hesitation. But the debate was conflating two different problems, and once you separate them you end up building something much smaller than the cathedrals on offer. For me, that ended up being a private Claude Code plugin: categorised markdown files in a cloud-synced folder, plus a Stop hook that nudges me to capture things worth keeping.
The week memory systems got a bandwagon
On April 3, Andrej Karpathy posted on X about what he called LLM Knowledge Bases; a day later he published an architectural sketch, the LLM Wiki. Instead of dumping everything into a vector database and calling it RAG, have an LLM agent compile your raw research, code, and notes into an evolving markdown wiki. Summaries. Backlinks. Encyclopedia-style articles. Human-readable. Every answer traceable to a specific file. VentureBeat covered it and the idea caught fire almost immediately.
The same week, Safi Shamsi shipped Graphify, a Claude Code skill in the same spirit. The current project is broader than that launch version: it parses code locally with tree-sitter across roughly forty languages, can add semantic passes over documents and media, and produces a queryable knowledge graph with an interactive HTML view. Its current benchmark table reports LOCOMO recall and QA results plus LongMemEval QA accuracy; the earlier nineteen-language and 71.5x-token claims are no longer present in the live source, so I am not carrying them forward as current facts.
Around the same time, actress Milla Jovovich and engineer Ben Sigman released MemPalace, yes, that Milla Jovovich. It is now a local-first memory system with pluggable storage backends and an MCP interface. People and projects become Wings, topics become Rooms, and original content lives in Drawers. Its current reproducible table reports 96.6% raw retrieval recall at five on 500 LongMemEval questions, with no LLM required for that retrieval benchmark. The repository now documents 47 MCP tools (as of October 2026). The earlier 170-token context claim and Halls-based description are no longer supported by the live source. Decrypt has the launch story.
The two problems everyone is conflating
Claude Code now has default per-project auto-memory, but it does not preserve the full conversation between sessions. “Persistent memory” still splits into two problems that want different solutions.
Per-project working context. Conventions, decisions, corrections, the weird edge case you worked around last week. Project-local. Shouldn’t leak into other projects.
Cross-project transferable knowledge. The lessons. GRDB’s DatabasePool gives you concurrent reads out of the box. SwiftUI alert bindings can’t use .constant(). DataForSEO’s on-page tools return cleaner HTML metadata than WebFetch does. You don’t want this trapped inside a single project. The whole point is that it travels.
Claude Code already handles the first problem reasonably well via CLAUDE.md instruction files loaded at the start of every session, plus the auto memory it writes for itself, a per-project folder of markdown notes whose index loads each session. It’s not fancy. It works. You probably don’t need to replace it. I’ve mapped out how the memory hierarchy fits together in more detail elsewhere.
The three tools everyone was posting about that week are, if you look carefully, about the second problem. Karpathy’s wiki is pitched at research papers and notes accumulated over months. Graphify is designed to eat an entire folder, code, docs, diagrams, images, and hand you back a navigable map, the sort of thing you’d point at a research corpus, not one day’s project context. MemPalace’s Wings explicitly partition memory by person or project so knowledge can cross boundaries without bleeding into each other.
The cathedrals are cross-project tools. The debate was framed as “how to give Claude memory” when it was “how to give Claude cross-project memory.”
Once you see it that way, the question becomes: how much machinery do you need for that layer?
What I built for it
I ended up with a Claude Code plugin called memory-vault. It’s private for now while I keep refining it, but the design is straightforward enough to describe completely.
The vault lives in a folder at ~/.claude/knowledge-vault/. On my machine that’s symlinked into iCloud Drive, so the same vault is on every Mac I work from. It could just as easily be Dropbox, Google Drive, OneDrive, or anything else with a desktop client and automatic sync. The medium doesn’t matter. What matters is that changes propagate without me thinking about it. No daemon, no vector DB, nothing to keep in sync with anything else. Search is a keyword index built from the files themselves, and if it’s ever wrong I delete it and it rebuilds. (It has since grown an MCP surface, which I didn’t have on day one and which I cover further down. The vector-DB-shaped hole in the middle is still a hole, deliberately.)
Inside the folder, knowledge is sorted into five categories: technical, solutions, decisions, domains, and tooling. Every entry is a single markdown file with frontmatter and a structured body. A real one, trimmed for space:
---
title: GRDB WAL Mode for Concurrent SQLite Access
category: technical
tags: [swift, grdb, sqlite, concurrency, wal]
created: 2026-03-09
updated: 2026-03-09
source_project: <redacted>
confidence: high
---
## Summary
GRDB's `DatabasePool` uses WAL mode by default, enabling
concurrent reads while a single writer operates. This is
essential for apps that read from SwiftUI views while background
tasks write.
## Key Findings
- `DatabasePool` (not `DatabaseQueue`) is required for concurrent access
- WAL mode allows multiple simultaneous readers with one writer
- GRDB record structs are value types, use `var` for mutation, not `let`
## Gotchas
- `dbPool.read {}` is synchronous and blocks the calling thread ,
always wrap in `Task.detached` when calling from MainActor views
- Use `.task {}` not `.onAppear` for async database loads
(auto-cancels on view removal)
## Related
- [[swiftdata-vs-grdb-trade-offs]], architecture decision on when to use each
Four body sections: Summary, Key Findings, Gotchas, Related, with [[wikilink]] backlinks to other entries. The categories are deliberately coarse. I’d rather have good tags on entries than a deep taxonomy I spend time maintaining.
After about a month of use, the vault had 48 entries. (Six months on it has 672, which changed some things and left others exactly as they were; that’s the section after next.) A representative sample from those first weeks:
- GRDB WAL Mode for Concurrent SQLite Access
- SwiftData vs GRDB, When to Use Each
- Use DataForSEO On-Page Tools for HTML Metadata, Not WebFetch
- SwiftUI Alert .constant() Binding Pitfall
- SEO Content Audit Methodology, Cannibalization, Link Equity & Consolidation
Every one is something I figured out on a client project and expect to need again on an unrelated one.
The rule I apply to every candidate entry is the one I wrote into my own command docs: would this help in a different project? If the answer is no, it belongs in the per-project memory, not the vault.
The ritual that makes it get filled in
The hardest part of this isn’t the storage. It’s the capture.
The failure mode of every memory system I’ve used is the same: the folder exists, but nothing gets written to it. You finish a conversation, close the terminal, and the thing you just figured out quietly disappears. The storage isn’t the problem. The moment of reflection is.
So the plugin ships with a Stop hook, a short Python script that runs each time Claude finishes responding. It reads the stop event from stdin, scans the transcript for words that suggest research or debugging happened, and if it finds more than one of them, returns a systemMessage nudging me:
This session involved research or debugging. Consider using
/remember <topic>to save key learnings to the knowledge vault for future sessions.
It never blocks. It never forces anything. It surfaces the question do you want to keep this? at the exact moment I’d otherwise forget to ask. Most sessions produce nothing. The ones that do produce a single entry, often just a paragraph, that I’m glad I have the next time I hit the same class of problem.
The keywords I scan for are things like turns out, figured out, root cause, the trick is, workaround, gotcha. That list is specific to how I work. I debug out loud. I use turns out when I’ve found a root cause. If you build something similar, pick your own triggers. The keywords aren’t the point, the nudge is.
When I accept the nudge, I run /remember <topic>. The command searches the vault for similar entries first to avoid duplicates, asks me to confirm the category if it isn’t obvious, writes the file, and updates the index. The whole thing takes under a minute.
What six months did to it
I said at the bottom of this post that I’d know in about six months. It’s been six, so this is the verdict, checked in October 2026. The vault went from 48 knowledge entries to 672 in that time, and a 14x is enough to show you which parts of a design were load-bearing and which were just decoration.
The substrate held. It is still flat markdown files in a synced folder. Search is still a keyword index built from the files themselves. There is still no vector database, no embedding step, no compile stage, and after 672 entries I’ve never once wanted one, which is the part of the original argument I was least sure about and am now most confident in. The links are still sparse and hand-written: 1,594 wikilinks across 672 entries, about 2.4 per entry. Nothing recompiles. Nothing gets stale in a cache I have to think about.
What grew was maintenance, not machinery. The cathedrals I was arguing against aren’t complex for maintenance reasons; they’re complex because they compile and embed and re-index. None of what I added does that.
Here’s what I got wrong, in rough order of how wrong I was.
“No MCP server, no daemon” is now false. Since 2026-07-05 there’s vault-mcp, a small Swift MCP server, so any MCP client can read and write the same entries. The reason wasn’t the vault outgrowing the folder; it was that I stopped working only in Claude Code. Codex and Gemini couldn’t see any of it, and knowledge that only one agent can reach isn’t cross-anything. That’s the same argument as the original post, applied one level up: the point of the vault is that it travels.
Except it mostly hasn’t. Writes through that MCP surface are logged with an actor, and when I checked in July that log held exactly one entry: the migration that created it. Python /remember doesn’t go through that path, and it was still what wrote every entry. So the cross-agent write path was provably untouched: a capability I built rather than a habit I have. I’d be overselling it to call it part of my workflow.
The five categories became six, and the sixth was a mistake. I added sessions. By July it held two entries, both from May. (Since September my task tooling writes its own session records into that folder; those aren’t knowledge entries, and I don’t count them here.) It turns out “what happened in this session” is per-project working context wearing a trenchcoat, which is exactly the thing this post argues doesn’t belong in the vault. I violated my own rule about six weeks after writing it down.
Coarse categories plus rich tags was the right call, and it has a real bill. I wrote that I’d rather have good tags than a deep taxonomy I spend time maintaining. Six months later: 1,819 distinct tags, of which 1,205 appear exactly once. Some of that is healthy long-tail. A lot of it was anti-pattern and anti-patterns, postgresql and postgres, the same idea splitting in two because nothing was stopping it; the curation pass has since merged those two pairs, and monetisation and monetization are still both there. The taxonomy I didn’t want to maintain up front turned into a taxonomy I now maintain in arrears, via a curation pass that clusters the variants and proposes merges. I still think this beats designing the hierarchy on day one, when I’d have guessed wrong about every branch. But “tags are free” was never true. They’re just billed later.
And the thing that’s meant to send the bill stopped running without telling me. I wired up a weekly job to do the curation pass automatically. Going back through the logs to write this section, I found it had been failing since May, twice over. First a renamed command, which sat in a log I never read. Then, after I fixed that, something quieter: macOS treats iCloud Drive as a protected location, so a scheduled background process gets Operation not permitted on every read of the vault, while the same command from a terminal works perfectly. If you copy this setup and put your vault in a cloud-synced folder, know that any launchd or cron job you point at it will hit the same wall. By July, both curation reports in that folder were ones I kicked off by hand.
This post argues that the hard part of a memory system isn’t storage, it’s the moment of reflection, so I built a nudge to protect it. Then I automated the maintenance of the nudge, stopped looking, and the automation quietly died for two months without one line of output ever reaching my eyes. The Stop hook works because it interrupts me. The curator failed because it didn’t.
So the fix, as of this update, wasn’t to harden the scheduler. I deleted it. Curation is now a second nudge in the same Stop hook: if the newest curation report is more than a week old, the next Stop hook tells me so, and I run the pass myself in a terminal that can see the files. The whole system now runs on interruption rather than schedule, which is where it was always heading. Silent automation is how this thing dies; loud nudges are how it stays alive. Even loud ones can be ignored, though: since the nudge went in I’ve run the pass three times, on 2 August and on 4 and 7 September, and not in the six weeks since.
The capture curve says something similar, and I’ll resist over-reading it: 129 entries in April, 221 in May, 63 in June, 35 in July, 45 in August, 106 in September and 28 so far in October. Some of that is less novel work: fewer new stacks, more grinding on things I already have entries for. But I don’t think that’s all of it, and “the ritual decays” is the more honest reading of a curve that shape.
What’s changed in the wider tooling since I posted this
Worth a check-in, because the picture has moved.
Anthropic’s Memory Tool API is a client-side primitive: Claude calls a tool that reads and writes files in a /memories directory you host yourself. Anthropic provides the interface, you provide the storage. (A correction from an earlier version of this section: I originally dated that API to late April as a beta. It actually shipped in beta back in September 2025 and dropped its beta header in February, before this post existed.) What is new from this window is Claude Managed Agents: Anthropic rolled out persistent memory there in public beta on April 23, storing memories as files manageable through the API or Console. Both are first-party acknowledgements that cross-session memory is a real problem worth solving, and the architecture (flat files, client-hosted for the Memory Tool) lands close to where MemPalace, the LLM Wiki, and my own vault already sit. They don’t replace third-party tools that add vector search, compression, temporal reasoning, or cross-project scoping, but they make the primitive available to anyone building one.
The original three tools have all moved. MemPalace now exposes 47 MCP tools (as of October 2026), several storage backends, and a temporal entity-relationship graph. Graphify has become a multi-assistant CLI and skill with local AST parsing across roughly forty languages, a current benchmark suite, and optional document and media extraction. Karpathy’s gist hasn’t been updated by Karpathy, but a community of follow-up gists and reference implementations has filled the gap.
A new entrant, claude-memory-compiler (explicitly inspired by Karpathy’s wiki, uses the Agent SDK to compile cross-referenced articles from your sessions), joins the older claude-mem (session capture, AI compression, injection).
None of it has pulled me off the folder, for the reasons in the section above: the storage was never the part I needed help with. But if you’re starting fresh today, you have more options than I did when I built this, including Anthropic’s own primitives for the file layer I had to hand-roll.
When the cathedrals earn their complexity
None of this is an argument that the fancier tools are wasted effort. They’re solving adjacent problems I don’t happen to have.
For a research corpus of hundreds of papers and PDFs, the case Karpathy originally described, an LLM Wiki is the right shape. The compilation step is the whole point. You want the agent to read everything and synthesise a map you couldn’t have built by hand. My vault is for lessons, not libraries.
For an unfamiliar monorepo where the interesting information lives in the relationships between files rather than the files themselves, Graphify’s knowledge graph earns its complexity. My vault has relationships, but they’re sparse, hand-curated [[wikilinks]]. I explicitly don’t want a graph I need to re-compile every time something changes.
For a team memory system where multiple people query a shared, growing corpus with semantic search, MemPalace’s hierarchy and MCP surface scale in ways a flat folder doesn’t. My vault is a solo practitioner’s notebook. A team would outgrow it quickly.
Real problems, good tools for them. The question is whether they’re your problems, or whether you’re reaching for the most impressive tool in the room when a folder and a hook would do.
I said I’d know in about six months. Six months in, the answer: the folder is still enough, and the folder was never the question. The thing that needed watching was whether I’d keep filling it and tending it: filling it less than in May, and tending it only when nagged.
I wrote about how I use Claude Code in six client projects if you want the broader workflow picture, and about keeping token usage sane if efficiency is the angle you care about most. If you’re thinking through how to set this kind of workflow up for a team and want to talk through the trade-offs, that’s what I help with on my Applied AI page.
Sources
- Andrej Karpathy, LLM Wiki gist, Original architectural sketch of the markdown wiki approach. Primary Source
- VentureBeat, Karpathy shares ‘LLM Knowledge Base’ architecture, Reporting on the April 3 announcement and the RAG-alternative framing. News Article
- Graphify on GitHub, Current source repository, approximately forty-language AST support, architecture, and current benchmark table. Primary source
- MemPalace on GitHub, Current source repository, 96.6% raw R@5 LongMemEval result, 47-tool MCP interface (as of October 2026), and Wings/Rooms/Drawers structure. Primary source
- Decrypt, Fifth Element Star Milla Jovovich Reveals AI Memory Tool MemPalace, Launch coverage and confirmation of Jovovich and Sigman as co-authors. News Article
- Anthropic, Memory Tool API documentation, First-party memory primitive (no beta header since February 2026). Company Documentation
- Claude Code, Hooks reference, Official documentation for the Stop hook and other Claude Code lifecycle hooks. Company Website
Common questions
What problem do AI memory systems actually solve?
Two different ones that get conflated: remembering within a project, and carrying knowledge across projects. Within-project memory is largely handled by instruction files; the harder, more valuable problem is cross-project recall, and that is the one worth building for.
Do you need a complex memory system for Claude?
Usually not. A simple markdown vault with a recall habit covers most of the cross-project need without the machinery of a full memory framework. The system only works if it actually gets filled in, so the ritual around it matters more than its sophistication.
How do you make an AI memory vault that gets used?
Attach it to a habit. A vault only earns its keep if capturing and recalling are part of the workflow, so I tie saving findings and checking the vault to the start and end of real work rather than treating it as a separate system to maintain.