The second most common complaint about artificial intelligence (AI) assistants, after "it makes things up," is "it keeps making the same mistake." Both have the same root. Nothing persists between sessions unless you build the persistence yourself. The model that fixed your flaky test runner on Tuesday has never heard of it on Wednesday. This post is how I built the persistence: three files and one rule.
Where a Lesson Lives Decides Whether It Is Read
Everyone starts with one memory file. It works for a month. Then it is long enough that the assistant stops reading past the top, and general enough that half of it is wrong for whatever project you are in today. A preference about how I sign emails sits next to a note about one repository's build command, and both get loaded into every session whether or not either applies.
The fix is to split memory by lifetime, not by topic. A fact that is true everywhere, forever, lives in one place. A fact that is true only inside one workspace lives with that workspace. A fact that is true only for the next hour lives in the session and is thrown away with it.
| Scope | Lifetime | Holds | Loaded |
|---|---|---|---|
| User | Every workspace, forever | Preferences, writing style, recurring patterns, general lessons | First lines auto-loaded into every session |
| Session | This conversation only | The task plan, in-progress notes, scratch state | On demand during the task, then discarded |
| Repository | This workspace only | Verified build commands, project conventions, access patterns, API quirks, "this failed before, do X instead" notes | On demand when working in this repository |
The user scope stays short because only the always-true facts live there, and short is what keeps it read. The repository scope can be as long as the project needs, because it only costs context when you are in the project. That is the whole trick: right knowledge, right lifetime, and the context window is neither starved nor flooded.
The Rule That Makes the Files Matter
Files nobody reads are decoration. So the discipline is codified as a rule in the always-on instructions, and it reads close to this: consult memory before any non-trivial task; if you make a mistake that memory already documents, that is a preventable failure. The word preventable is doing the work. It reframes a repeated mistake from bad luck into a skipped step, which is what it is.
The write side has a rule too. When the assistant hits a mistake that looks like it could recur, it writes the lesson to the correct scope before moving on. One line. What failed and what to do instead, not the story of how we found out. Entries are terse on purpose: user memory is auto-loaded, so every line in it is a tax on every task, and brevity is what protects the budget.
What an Entry Looks Like
The shape that has held up is a situation, a failure, and a fix, on one line. From this site's own repository scope: the test suite needs a fresh install after the container restarts, because the dependencies go stale; the sitemap regenerates wholesale on every publish, so a page added by hand disappears the next time the script runs. Both were mistakes made once. Neither has been made twice, and not because anyone remembered.
The routing question, which scope does this go in, gets its own small table in the file below. The short version: if it is about how I like output to look anywhere, user; if it is a command or quirk true only here, repository; if it is where I am in the current task, session. A repository lesson that keeps appearing across repositories gets promoted to user scope and the copies deleted.
Take It
The three scopes, the rule, the entry format, the routing table, and the housekeeping rules are in one file: memory-scopes.md. It takes ten minutes to set up and it pairs with the output gate and the skills layer from earlier in this series.
The system compounds the same way skills do. Every documented failure is a failure that does not happen again. The cost is one line, written at the exact moment you are most annoyed and least inclined to write it, which is why the rule has to be a rule.
This is part of a track on agent tooling and spec-driven development that goes deeper than a field report, with something you can download and run in each one. Free for now while the track grows; the deepest installments become a paid tier later.