Why I separated memory from execution
At some point the amount of information I work with became too large.
Projects, technical decisions, tasks, diagrams, notes, interim conclusions.
While a project is active, it feels as if all its logic is in your head. But switch to other work and come back a few weeks later, and part of the context has to be rebuilt from scratch.
I needed a system that stores not just notes, but the state of a project.
One of the first approaches was Apple Freeform. The idea of a canvas suited me right away: laying information out in space, seeing connections, assembling a project as more than linear text.
But it soon became clear that one canvas wasn’t enough.
I needed ordinary files, Markdown, a clear folder structure, Canvas, an API, and the ability to build my own rules on top of all of it.
That’s how Obsidian became the main memory.
But another problem appeared almost immediately.
Obsidian is a good place to keep project architecture, technical decisions, documentation, reasons for changes, plans and history.
But day-to-day task execution is better kept separately.
For that I kept Todoist.
At first the natural idea seemed to be to link the two systems as tightly as possible: changes in Obsidian show up in Todoist, changes in Todoist come back.
In practice that symmetry quickly creates new problems.
Which one wins if the data diverges?
What counts as the current state of the project?
Should a task change be written back into the documentation?
In the end I arrived at a simpler architecture.
Obsidian stores memory.
Todoist manages execution.
The detailed state of a project lives in files. For example, the current plan is in implementation_plan.md, and the history of important decisions is kept in decisions_log.md.
Todoist doesn’t try to become a second copy of that memory. It shows what needs to be done now.
Out of this, one of the main rules of my whole system gradually emerged.
One fact = one owner.
If it’s a project decision, it belongs to project memory.
If it’s an action to be carried out, it belongs to the execution layer.
The link between them remains, but they no longer try to be mirrors of each other.
And here the next question appeared.
If the real project memory is in Obsidian, how do you give a language model access to exactly that, instead of moving documents into the chat by hand every time?
The first working answer to that question was my Obsidian MCP server.
In the next post I’ll go through how the LLM got access to my Obsidian through it.
