Why I built it
I have always liked personal productivity and organization. For years I used GTD (Getting Things Done) to run my personal and professional life. When I found the Second Brain idea together with PARA, it made complete sense to me, so I built it.
Giving an agent that kind of access has an obvious risk. Your passport, bank statements and contracts end up near your notes. So the system is built around one question: what can the AI see, what can it move, and what can I undo?
Three rules
- Sensitive documents never enter the vault, and no AI reads them.A local script that uses plain pattern matching, with no AI and no network, checks every file first.
- The system only moves things.It never deletes and never overwrites. Every move is logged and can be reversed with one command.
- I dump everything into one inbox, and a nightly job empties it.If it can’t decide, it asks me. It doesn’t guess.
What runs today, and what is still being built
| Part | Status |
|---|---|
| The vault (folders, rules, commands) | Running |
| The knowledge base (Corpus) | Running |
| Nightly pull from my phone’s cloud folder | Running |
| The sensitivity filter and the nightly router | Running (first versions) |
| Router v2: inbox zero, review queue, triage folders, folder limits | Built, reviewed and merged. Its first night only writes a report |
| Starred-email channel | Set up and tested on 20 real messages. The rest comes in slowly. The timer is off |
| Scheduled rituals (morning brief, weekly review) | Written for my old Mac setup, being ported to Linux |
I list this on purpose. Most pages like this show only the parts that work.
How the pieces fit
1. The vault
It uses the PARA method: Projects, Areas, Resources, Archives. Plus a folder for the system’s own files.
- Inbox: quick capture. Should be empty after the nightly run.
- Projects: one thin note folder per project. The code lives in its own repository, and the note folder points to it.
- Areas: ongoing responsibilities such as career, health, finance, home, learning.
- Resources: reference material, including the knowledge base and my design documents.
- Archives: finished projects and old reviews.
- System: templates, rules, scripts and infrastructure notes.
A thin CLAUDE.md at the root points the agent to three files: who I am and what I’m focused on, the folder rules, and the list of commands. It reads those instead of guessing.
The vault is built for an agent first. Status files and router notes are written so a program can parse them. A human-friendly view comes second.
Technical detail: the two-layer project model
Each project has two layers: a code repository (the technical truth) and a small folder in the vault (plans, decisions, status). A /project command scaffolds or audits that pairing so they don’t drift. The vault folder never duplicates what the code already says.
2. The knowledge base (Corpus)
Corpus is a second layer on top of the vault. It follows the “LLM wiki” pattern: raw sources go in, and an agent turns them into small linked pages.
- Raw sources are read-only. Articles, blog posts, newsletters, PDFs and video transcripts land in a
raw/area. The agent never edits them. It only stamps three fields saying “ingested, when, and which pages came from it”. - Pages come in five types: hub, entity, concept, synthesis and source.
- Every non-trivial claim cites a source. Short quotes are kept (25 words or fewer). Claims without a source are marked as such.
- Disagreements are kept, not resolved. If two sources disagree, a synthesis page records both. Old claims are never deleted. They become stubs that link forward to the claim that replaced them.
- Asking a question: the agent reads the index, picks pages, and answers only from the corpus. If coverage is thin, it queues a few web pages for later ingest and labels the answer “fresh, not yet in corpus”. It never presents its own memory as a corpus claim.
- Guardrails against drift: a new top-level domain needs three or more sources that fit nowhere else. An ingest that would touch 20 or more pages pauses and asks me.
I have not asked it a real question yet. I am still working out when the knowledge base is the right tool and when a normal web search is better. I will add an example here once I have one that earned its place.
3. The inbox: dump anything, wake up to zero
Anything I want kept goes into one place, from any device:
- From my phone: drop a file in a cloud folder. A nightly job pulls it into the vault inbox. The originals go to the cloud trash and stay recoverable for 30 days.
- From email: starring a message means “send this to my 2ndBrain”. The channel stores the message text and each attachment, then removes the star and archives the message. The message stays in All Mail, and a ledger records every change so I can undo it.
- From my desk: drag it into the inbox folder.
The goal is inbox zero, like an email inbox. Every item ends up in one of four places:
- Out of the vault, if it’s sensitive. Filed into my own documents folders by kind (identity, health, finances, home, cars, family, insurance), using only the file name, never the contents.
- A folder in my notes, if it belongs to an area of my life: a contract, a receipt, a note.
- The knowledge base, if it’s reading material: an article, a blog, a newsletter, a book.
- A review pile, if the router isn’t sure. A morning summary lists one question per item. The inbox itself stays empty.
An email about a new car-insurance policy goes to the insurance folder, not the knowledge base. The star only means “bring this in”. What the item is decides where it goes.
Technical detail: how the router stays small and safe
The router is a thin shell wrapper around a deterministic Python engine that uses only the standard library. The AI’s job is narrow: read extracted text, then propose a destination folder and a tier for each file.
- The wrapper does the PDF and OCR text extraction itself.
- The model runs headless with a Read tool and an Edit tool only. It has no shell, no network tool, and none of my usual settings or hooks.
- It can read only one per-run folder of extracted text. It can edit only one plan file.
- The engine re-checks every row the model proposes: allowed source, allowed destination, no overwrite, tier rules, a limit on how many files per run.
- A move happens automatically only if the model is highly confident, a tier is set, there’s no open question and the date comes from the document’s content. Everything else is proposed, not done.
- The wrapper always exits cleanly, so a timer never retries in a storm. A failure shows up in the next morning’s summary.
4. Trust: the three tiers
Every file gets one of three sensitivity tiers. If I’m unsure which, the stricter one wins.
T0
Identity documents, medical records, bank statements, property deeds, loan papers.
Never in the vault. My own documents folders only. Nobody reads them: they are classified by name, date and folder only.
T1
Contracts, insurance policies, company legal papers, payslips, invoices.
In the vault, but git-ignored (stays on my machine, no cloud copy of the git history). The AI may read them to classify and summarise.
T2
CV, certificates, articles, books, reading material.
In the vault, tracked in git. The AI may read them.
Why this shape:
- The vault syncs and its git history can’t be undone, so anything sensitive must never be written to it in the first place.
- A model that never sees T0 can’t leak T0. The strongest guarantee is that the data never reaches it.
- Every non-text file that enters the vault gets a short summary note next to it (what it is, key points, a hash). That way the agent searches the note and doesn’t open the file. Summaries never contain account or ID numbers.
The local filter
It’s the gate that makes this work. It’s a script of pattern matching in two languages: IBANs with the check digit verified, card numbers (Luhn), ID-document keywords, medical terms, secret-looking strings like keys and tokens. It has no network access and no AI. It prints the name of the pattern it matched, never the value.
It returns one of three results:
- T0: a pattern matched. The file leaves the vault.
- Review: it couldn’t read the file, or the file is too big. The file is held out of any AI.
- Clear: it read the text and found nothing. Only then can the AI see it.
The rule is default-deny: “clear” requires readable text. A scanned image with no text is not clear.
It’s deliberately strict. It would rather flag a harmless file than let a sensitive one through. That cost me something real, and I tell the story below.
5. Mistakes are cheap
I assume the system will make mistakes. The design aims to make each one easy to see and easy to undo.
- It never deletes or overwrites. A name collision is proposed with both files shown.
- Every move is logged. One command reverses all moves from a given day.
- A morning summary lists what moved, what was proposed and what failed. It’s git-ignored, because it names real files.
- Gmail changes are tiny and reversible. The code can only remove two labels. A test fails if any other Gmail call exists. The access token technically allows more, so the limit lives in code and tests, not in the permission scope.
- The assistant never sends email. It writes drafts and I send them.
- A hold list names folders the router may not file into until I lift the hold.
When I get an item wrong, or the filter does
Files the filter can’t clear go to a triage folder outside the vault. When I look in it now and then, I have three moves:
- Drag the file into the right documents folder myself.
- Rename it and drop it in a
to-filefolder. A script reads only the new name, maps keywords to a kind from a fixed list, and files it. No AI is involved. - Drop it in a
not-sensitivefolder. It goes back to the inbox with a marker so the filter doesn’t flag it again. The marker is tied to the file’s content, so an edited file gets judged again.
6. Keeping folders tidy
If an agent can create folders, it will, and you end up with dozens of near-duplicates. I allow it, with six limits:
- Rule of three. The first two items of a new topic go into the existing parent folder. The folder is created when a third item arrives, and the first two move into it.
- Similarity check. The router compares a proposed name with every folder in that area. If one is close, it must reuse it.
- Weekly cap. At most two new folders a week.
- A registry. One note lists every folder the router made, with the date and the reason.
- A monthly check. It lists folders with fewer than three files after 30 days, near-duplicate names, and areas that are growing fast.
- Hard limits. Three levels deep, never a new top-level folder, never in the system area, never a name that repeats its parent. The checks only report. I merge, and nothing is deleted.
I don’t have a view on the number three yet. It is a starting value, one number in a config file. I will tune it after the first few weeks of real use.
7. Backups and sync
- Encrypted nightly backup of my documents, work, code and the whole vault to cloud storage. It keeps 30 daily and 12 monthly copies. It’s the only copy of the git-ignored files, so it matters.
- A one-way mirror of my documents to a cloud drive, so I can read them on my phone. Changed and deleted files go to a dated recovery folder, pruned after 90 days. The triage folder is excluded.
- Obsidian Sync for phone and laptop editing, with selective exclusions for big folders.
- Git for the vault itself, in a private repository.
What broke, and what it taught me
The first version of the filter flagged a file as sensitive on single words like “bank” or “patient”. Overnight it flagged 26 reading PDFs and a spreadsheet and moved them to the triage folder. That folder sat inside the tree my phone mirror copies to the cloud. By morning the files had been uploaded.
Nothing private was in them. They were books and articles. But two things were wrong: the filter was too eager, and the folder meant to be safe sat in an unsafe place.
I fixed both. I restored the files, exempted the reading folders from the filter, excluded the triage folder from the mirror and purged the stray copies from the drive. I also added a report-only first night. A new rule now writes a report and moves nothing until I have read it.
A safety step is only as good as every folder it writes into.
What I would copy if I were you
- Decide your tiers before you automate anything. “What may an AI read?” is a design decision, not a setting.
- Run the sensitivity check as plain code, with no model in it. Pattern matching is boring and predictable. That’s what you want here.
- Make every automated change reversible, and write the undo before the feature.
- Keep the agent’s tools minimal. Mine can read one folder and edit one file.
- Let a nightly job run unattended only after a night of report-only output.
- Keep an “unsure” pile. An empty inbox you can’t trust is worse than a full one.
The stack
Obsidian for the vault. Claude Code for the agent, headless for the nightly router. Python (standard library only) for the engine. Bash for the wrappers. systemd timers for scheduling. rclone and restic for sync and backup. Git and GitHub for history. The Gmail API for the starred-email channel.