Since March, a growing part of my business has run out of a folder of text files. My content, my ideas, my weekly review: markdown in a git repo, operated by Claude Code.
It works well enough that the rest is moving in: clients, decisions, goals, deadlines, the numbers. Before I move it, I wrote the architecture down, because a system you run your working life on deserves the same rigor as one you'd ship to a client.
Here's the design, and the one rule that holds it together.
Five layers, one direction
- 1The vaultMarkdown files, the single source of truth. One canonical home for every thing: a client, a decision, a goal, a day. Every entity gets a stable ID that is never reused.
- 2The contractOne schema that says what a client or a decision looks like. A change starts there, and everything downstream follows.
- 3The pipelineA stateless script that compiles the vault into one JSON read-model. I call it the spine.
- 4The skillsThe operations the AI runs: a morning brief, a weekly review, logging a decision, turning a debrief into next steps. Each one names the files it reads.
- 5The viewsA desktop app first, then the phone. They read the spine. They own nothing.
Each skill declares what it reads and what it may write. The morning brief writes nothing at all; it only reads. A skill that writes outside its declared outputs is a bug, however helpful the edit looked.
Markdown always wins. The spine is disposable; regenerate it, never patch it.
The data-flow rule in the system's contract
Why markdown
- I can read it without the app. If every tool I build disappeared tomorrow, the truth would still be there, in files any editor opens.
- Git gives me history for free. Every change has a date, a diff and a message. "When did this decision change?" is one
git logaway. - The AI reads it natively. No connector, no export, no sync job. Claude Code opens the file, quotes it and names the path.
- It's mine. No vendor decides the format, the pricing or the API.
Every file carries the same few fields at the top (an ID, a type, dates, links) and fixed headings in the body, so a script parses it as reliably as a model reads it. And facts are referenced, never duplicated: a fact gets one home, and everything that needs it points there. Copy a fact into two places and you've built yourself a future argument about which one is true.
The spine is disposable
The views need speed and structure, so a script compiles the vault into one JSON file. It's tempting to start treating that file as the database. It isn't, and the whole design depends on never letting it become one.
Before
If the read-model is the truth
- A screen writes a quick fix straight into the JSON
- The markdown and the JSON quietly drift apart
- Nobody knows which one is right anymore
After
If markdown always wins
- Every change lands in a markdown file first
- The spine is rebuilt from scratch, every time
- On a conflict, the markdown wins and the drift gets flagged
If you build mobile apps, you already know this discipline from offline-first work. One source of truth, a local cache derived from it, and a cache you can delete at any moment without losing anything. Same idea, applied to a business.
The contract the AI follows
The agents that work on the vault follow one contract, and every skill repeats it. It's the part I'd copy first into any repo where an agent works:
- 1Read first. Before any answer, open the files the question touches. Never answer from memory or generic best practice.
- 2Assert only what's written. When a fact carries weight, cite the file it came from, and quote the number.
- 3Missing means say so. If the vault doesn't hold it, say that and ask. No plausible guesses.
- 4History is append-only. The journal and the log are never rewritten. A correction is a new dated entry.
- 5Label inference. Keep "the file says" apart from "this implies".
The views own nothing
- 1Markdown vault
- 2Spine (JSON)
- 3Cloud database
- 4Desktop and phone
The plan is a desktop app for deep work and a phone app for the quick look. Both read the same compiled state, and neither holds data of its own. If a view and the vault disagree, the view is wrong, by definition.
And when the phone needs to change something, that change has to land in a markdown file before it counts. No quiet edits to a copy. A phone that writes to its own copy is how two versions of the truth start, and anyone who has built offline sync knows how expensive those are to untangle later.
One more decision, written down so I don't drift: this is personal. It's not a product, and it doesn't need to scale to anyone but me. That keeps it honest and small.
Tools will change. Models will change faster. A folder of plain text with a clear contract is the part of this I expect to still be using in ten years.
Weekly-ishEngineering OS, in your inboxJoin Engineering OS


