I use five AI tools, and each of them keeps its own memory.
Claude in the browser has one. Claude on my phone has another. Claude Desktop has its projects. Codex and Claude Code know whatever sits in the repository they were started in. n8n knows nothing at all unless a workflow hands it something. Five memories, and no two of them agree on what I know.
Before all of this I kept notes in Obsidian, and it went the way these things go.
Every second brain dies the same way. Notes go into the inbox faster than anybody sorts them, the inbox grows, and one day you stop believing that what you are looking for is in there. Writing things down was never the hard part. Sorting is, and sorting is the first thing that gets skipped in a busy week.
So I stopped being the one who sorts. Every night one model reads my inbox and proposes where each note should go. A second, independent model approves or rejects each proposal. Then a script that cannot think writes only what was approved. I was supposed to be the one approving. I never did, so I took myself out of the loop.
One place, every client
All of it lives in a self-hosted Outline. Not most of it - all of it. It is the single source of truth for everything I want an AI to know.
The reason is MCP. Outline sits behind an MCP connector, so the same knowledge base shows up in Claude chat, on my phone, in Claude Desktop, in the CLI agents and in n8n workflows. Five clients, one memory. What I write down in one of them, the other four can read.
I considered the obvious engineer’s version first: notes in a git repository as the source, mirrored into Outline for reading. I dropped it. Outline keeps a revision history of every page, and that history does the job I wanted git diff for. A mirror would only have given me a second place to be out of date.
There is a git repository in the picture, but it holds the configuration of my agents, not knowledge. Instructions, permissions, settings. A fact about the world goes to Outline. A rule about how an agent should behave goes to the repo.
One honest note before going further. A single source of truth is also a single point of failure. Outline is now a critical service and the only copy of the data, so backups that work and are monitored are a precondition for the whole thing, not a nice extra. If I could not restore it, I would not trust it. If I did not trust it, I would be back to five memories.
A structure an agent can find its way through
The knowledge base has six collections. The real names are Slovak; here they are in English:
- 00 Start - INDEX, About me, KB rules, Log
- 10 Inbox - everything new
- 20 Projects - things that end
- 30 Areas - things that do not end
- 40 Knowledge - verified, evergreen technical knowledge
- 90 Archive
The entry point is INDEX: one line of TL;DR for every document that matters. An agent that starts there knows which page to open without reading all of them.
The rule for pages is one page, one topic. Every document opens with the same header:
Type: knowledge | source | record | project | area
Status: active
Updated: 2026-10-26
Related: [links]
TL;DR: One to three sentences, enough to decide whether to open the page.
The header is written for the agents as much as for me. The TL;DR is what ends up in INDEX, Updated says how stale a page might be, and Related keeps a page from becoming an island.
Two things pushed me towards this shape.
The first was Andrej Karpathy’s LLM Wiki, an idea file he published in April 2026. It keeps raw sources, which the model reads but never changes, apart from the wiki the model writes and maintains. It has an index listing every page with a one-line summary, an append-only log of what happened and when, and a periodic lint pass in which the model checks the wiki for problems. My Inbox, INDEX and Log map onto that almost one to one. Lint is the part I have not built yet.
The second was a LlamaIndex experiment, Did Filesystem Tools Kill Vector Search? They set an agent that explores files with filesystem tools against a classic RAG pipeline on five research papers, with an LLM grading the answers from 0 to 10. The agent won on correctness (8.4 against 6.4) and on relevance (9.6 against 8.0). The authors are clear about the catch: their files were 22 to 52 pages long, and the advantage would probably disappear with bigger ones.
That catch is the design rule I took from it. An agent that navigates pages beats retrieval as long as each page fits comfortably into what it can read. So: small pages, and an index good enough that the agent knows which one to open.
Permissions are the architecture
If I were building this again, this is the part I would set up first.
Every client connects as its own technical user, never as an admin. There are three of them:
| Collection | kb-reader chat, desktop | kb-agent CLI agents, n8n | kb-curator night shift |
|---|---|---|---|
| 00 Start | read | read | read, writes Log and INDEX |
| 10 Inbox | write | write | write |
| 20 Projects | write | no access | write |
| 30 Areas | read | no access | write |
| 40 Knowledge | read | read | write |
| 90 Archive | read | no access | write |
Everything new goes to the Inbox. Every client can write there. Only the curator writes to 40 Knowledge, the collection every agent trusts. When an agent in the middle of some task decides it has learned something important, it does not get to put it next to the verified knowledge. It puts it in the Inbox, and the night shift decides.
AI does not delete anything. Not as a sentence in a prompt - the curator’s API key has no scope for deleting. A prompt can be talked out of a rule. A missing permission cannot.
The agents do not see my life. kb-agent cannot see 20 Projects, 30 Areas or 90 Archive at all. The CLI agents and n8n get the technical knowledge and nothing else.
Every connector has to pass a short acceptance test before I use it:
- Reading works.
- Editing a page in 40 Knowledge fails.
- Writing to the Inbox works.
- The agent cannot see the personal areas.
Points two and four are the ones that matter. A connector that can read everything is easy to set up. The test is there to prove it cannot do what it should not.
The night shift
At 03:30 a systemd timer on a VPS starts Claude Code headless - claude -p - as the user
kb-curator. What happens next is split into three roles, and the split is the whole point.
1. The curator proposes. A model reads the Inbox and, for every document, proposes what to do with it: which collection and which parent page it belongs under, whether it should be merged into a document that already exists, which header fields to fill in, and whether it contains sensitive or client data that needs a flag. The result is a plan. The model has no tools and no keys, so a plan is all it can produce.
2. The reviewer approves. A second, independent agent reads the plan and approves or rejects each item. It did not write the proposal, so it has no reason to defend it.
3. The script writes. A deterministic script carries out only what was approved, and only operations on its allowlist: move a document, merge two, fill in a header, append to the Log, rebuild INDEX. Anything outside that list does not run, however good the reasoning behind it sounded.
Duplicates get merged and the original goes to the Archive. Nothing is deleted - the same rule as in the permissions, enforced a second time.
Every change ends up as one line in the Log. That is how I read the night shift’s work: not by opening documents, but by scanning a list of what moved where. I only come into it when an entry says “Needs owner”. A rejected proposal is not lost: the document stays in the Inbox and gets another try the next night. After three rejections the curator stops proposing it and writes “Needs owner” into the Log instead. That is my cue.
Why Claude Code in a terminal and not an n8n workflow with an API key? Because Claude Code runs within my subscription. And because the reviewer is Claude as well, the personal documents in my Inbox do not travel to one more vendor.
The reason for the three-way split is simple. A model is good at judgement and bad at being trusted with write access. A script is the opposite. So the model gets judgement and no access, a second model checks the judgement, and the script gets access and no judgement. None of the three can do damage on its own.
I fired myself
On paper, the first version had me in the loop.
Once a week the curator would produce a triage document with a checkbox next to every proposal. I would open it on my phone, spend five minutes ticking what I approved, and the curator would carry out only the ticked items. The rule was going to be firm: nothing goes into 40 Knowledge without a human.
I never started it. For nineteen days the Inbox sat there with nine documents in it, waiting for a review I was not going to do. That is exactly how every second brain dies, except this time I had designed the step I was skipping.
So I admitted what I actually wanted: a memory that works without my work. The approvals went to the reviewer agent, and the run went from weekly to daily.
What stayed are the safeguards that never depended on me:
- proposing, approving and writing are still three separate steps;
- the script still runs only what is on its allowlist;
- at most ten operations per run;
- nothing gets deleted;
- every change is still a line in the Log;
- client data never goes into 40 Knowledge.
On paper the human was one safeguard out of seven. In practice it was the only one that never ran. Taking out one of seven is a very different decision from taking out the only one.
What does not work yet
Lint is still missing. Karpathy’s idea has a regular health check and I do not have one. Orphaned pages, pages nobody has touched in six months or more, duplicates the curator did not catch - nothing looks for them automatically yet.
Outline glues the header together. If the header lines are not separated by blank lines, Outline renders them as one paragraph, and five tidy fields turn into one long sentence. Every agent that writes a document has to know this, which is why the instructions for my agents spell it out.
Build a light version
You do not need my exact setup. The order matters more than the parts:
- A self-hosted Outline.
- An MCP connector, so every AI client reads the same thing.
- Technical users with the smallest permissions that work - one per kind of client, never an admin.
- An Inbox where everything new lands, and a header on every page.
- Claude Code headless on a systemd timer.
- Proposing, reviewing and writing as three separate steps.
- A Log line for every change.
Stop after step four and you still have the part that matters most: one memory, and agents that cannot overwrite what you trust.
The point
A second brain does not die because you stop writing things down. It dies because nobody sorts what you wrote. Mine gets sorted while I sleep, by two models that check each other and a script that cannot improvise.
If you want the next post when it comes out, the form is right below.