The Goldfish Problem
A late-night rabbit hole, too much Path of Exile 2, and a growing frustration with being the database for every project led me to build an experiment: a second brain for my AI, my team, and hopefully my future self.
So this whole thing hit me in bed last night. I'd played way too much PoE 2, my brain was completely fucking fried, and instead of sleeping I was lying there scrolling about "second brain" setups. People wiring up their entire lives in Obsidian, knowledge graphs, the whole deal. And somewhere in that half-asleep haze, it clicked.
Because here's what my actual days look like. I spend an absurd amount of time being the memory for every damn thing around me. Explaining the same decision to a new dev, then again in a meeting to someone who missed the last one, then again to my AI coding assistant, which, as always, has the long-term memory of a goldfish. All the why lives in my head. Why we built it this way. Why we said no to that. Why that one cursed workaround exists in a file nobody wants to touch. None of it written down anywhere useful, just buried in Slack threads I'll never find again, meeting recordings nobody rewatches, and the gap between my ears.
So I'm lying there thinking: people build these second brains for themselves, so why the hell isn't my AI getting one for the projects I actually work on? Why am I the knowledge graph?
The thing is, you can't build anything in bed at 1am except a worse sleep schedule. So the idea just sat there overnight, rattling around. Then today I did the thing I always do when something annoys me enough. I built a system for it.
The actual problem
Here's the thing nobody tells you about AI coding tools. They're brilliant for about one conversation. Then you open a new chat and you're back to square one, re-explaining your entire project like you just met.
And honestly? Human onboarding isn't much better. A new person joins, and the only way they get context is by interrupting someone who already has it. Usually me.
So the problem was never "the AI isn't smart enough." The problem was that the context, the actual memory, was scattered everywhere and owned by no one. I wanted one place that both my tools and my team could read from. Same source of truth, whether you're a senior dev, a new hire, random suit-wearing individual, or a robot.
What I built
The shape of it is dumb-simple on purpose, and that's kind of the point. It's just a git repo per project, and everything flows one way:
sources ─► raw/ ─► brain/ ─► wiki/
(meetings, (the (curated (humanized
tasks, inbox, knowledge site people
decisions) evidence) graph) actually read)
Three layers, one rule each:
project-context/
├── raw/ # append-only inbox: evidence, never edited
│ ├── meetings/
│ ├── tasks/
│ └── decisions-inbox/
├── brain/ # curated graph: AI-maintained, PR-gated
│ ├── index.md
│ ├── overview.md
│ ├── decisions/ # ADR-style records
│ ├── requirements/
│ ├── domains/
│ └── _meta/processed.json
└── wiki/ # generated site: never hand-edited
raw/ is the inbox. Meeting notes, exported tasks, half-baked brain-dumps at 11pm. Stuff goes in and never gets touched again. It's the receipts.
brain/ is the cleaned-up part. An AI "librarian" reads the raw mess and turns it into something actually usable. One idea per page, all cross-linked, all pointing back at where it came from.
wiki/ is the pretty version. A searchable site that builds itself out of the brain. This is the bit the non-technical folks actually open, because nobody but me wants to read raw markdown.
Everything is a markdown file with rules
No fancy database, no special app. Every page in the brain is just markdown with a bit of frontmatter slapped on top. Greppable, diffable, and (important bit) it survives me getting hit by a bus:
---
title: Move checkout to a hosted payment flow
type: decision # decision | requirement | domain | meeting | learning
status: active # draft | active | superseded | archived
updated: 2026-06-08
sources:
- raw/meetings/2026-06-08-checkout-sync.md
related:
- "[[payments-domain]]"
- "[[ADR-0006-auth]]"
---
That sources: line is the whole trick, honestly. Everything in the brain has to trace back to a real file in raw/. No exceptions. The thing that builds it all follows one little rulebook, and these are the lines I actually care about:
1. Never edit anything under raw/. It's immutable evidence.
2. If you can't cite a source for it, you don't get to write it.
3. One concept per page. Update and link before you duplicate.
4. Keep index, overview, and the changelog in sync every run.
Rule 2 is the one doing the heavy lifting. No source, no claim. No vibes. The AI doesn't get to make shit up just because it sounds plausible.
Decisions get the full write-up so future-me knows not just what we did, but why, and what it cost us:
## Context
Checkout was a custom form; PCI scope and edge cases were eating us alive.
## Decision
Move to a hosted payment flow and stop touching card data ourselves.
## Status
active
## Consequences
- Smaller PCI footprint, less to maintain.
- Less control over the exact UI. Trade-off we accepted.
- Affects [[payments-domain]] and the mobile checkout screen.
And yes, I've planned to automate the raw data-gathering in due time. So basically it will get fed from various sources automatically.
How the tools actually read it
Okay, this is the bit I think is actually cool. My coding assistant doesn't get the whole brain shoved at it, that'd blow the context window in about two seconds. Instead there's a tiny little server (MCP, if you like acronyms) sitting in the middle, and the AI just asks it for what it needs:
server.tool("search_context", { query: z.string() }, async ({ query }) => ({
content: [{ type: "text", text: await ripgrepBrain(query) }],
}));
server.tool("get_decision", { slug: z.string() }, async ({ slug }) => ({
content: [{ type: "text", text: await readBrain(`decisions/${slug}.md`) }],
}));
So mid-task, instead of guessing, it just goes and asks, and gets a real answer back with a receipt attached:
> search_context("why hosted checkout")
ADR-0006 · Move checkout to a hosted payment flow (status: active)
↳ source: raw/meetings/2026-06-08-checkout-sync.md
↳ "PCI scope and edge cases were eating us alive."
And it's not dumb about it either. It hashes every source so it only ever chews on the new stuff, instead of re-reading the entire world every single run:
{
"a1b2c3…": {
"source": "raw/meetings/2026-06-08-checkout-sync.md",
"processed_at": "2026-06-08T14:00:00Z",
"pages": ["brain/decisions/ADR-0006-hosted-checkout.md"]
}
}
HIL: human in the loop
The AI drafts. A human merges. That's the whole deal.
And I cannot stress enough how much this one rule matters. The AI never just writes to the brain on its own. It opens a PR, like any teammate would, and I skim it and hit merge:
context: compile 2026-06-08 (3 sources)
brain/decisions/ADR-0006-hosted-checkout.md + new
brain/domains/payments-domain.md ~ updated
brain/overview.md ~ updated
3 sources processed · 2 pages added · 1 updated
So I get the robot doing all the boring synthesis grunt-work, but I never hand it the keys to the source of truth. It proposes, I approve. Trust, but verify, and all that.
And here's the bit that quietly closes the loop: when I'm heads-down in a coding session and the AI figures something out ("ohhh, that's why this keeps breaking"), it can toss that learning straight back into the inbox. So the thing gets a little smarter every time I use it, instead of dumping everything it learned the second I close the tab.
Does it actually work? No clue yet.
Real talk: I built this today, off an idea I had in bed last night. It's a concept, not a battle-tested system. I haven't dropped a single new dev into it, I haven't watched it survive a month of real meetings piling up, and I have no idea how it holds up once the brain gets big and messy. So take all of the above as "here's the shape of the idea," not "here's the proven thing."
What I'm hoping it does, if the concept holds up: a new dev, or a fresh AI chat, opens a repo and already has the history, the decisions, the sharp edges, because it's all reading from the same brain. The non-technical side gets a wiki they can actually search instead of pinging me. And I stop being the single point of failure for "why did we do it this way."
But that's the hypothesis. Here's the stuff I genuinely don't know yet:
- Does the AI librarian draft anything good enough to merge, or am I going to be rewriting half its PRs?
- Does it stay honest about that no-source-no-claim rule once the inputs get noisy and contradictory?
- Does the whole thing rot the second I stop feeding it, or is the staleness nagging enough to keep me in line?
- And the big one: is reviewing all these PRs actually less work than just... being the database myself?
No idea. That's the next chapter, and I'll probably write it once I've run this thing into the ground on a real project for a few weeks.
What I'm not unsure about is the itch. I'm so done being the memory for everything around me. The context shouldn't live in my head, or in a Slack thread from four months ago, or in a recording nobody will ever watch. It should live somewhere both my team and my tools can read. The whole point is to stop being the fucking database.
So the bet is simple: the fix for a goldfish brain isn't a smarter goldfish. It's writing things down where the goldfish can read them. Now I just have to find out if I'm actually right.