# Memory scopes

Three files, three lifetimes, one rule. This is the memory layer of an AI
workspace, reduced to something you can set up in ten minutes. The point is
not the files. The point is that a lesson lands in the scope that matches how
long it should live, and that the assistant reads the right scope before it
acts.

---

## The three scopes

| Scope | Lifetime | Holds | Loaded |
| --- | --- | --- | --- |
| **User** | Every workspace, forever | Preferences, writing style, recurring patterns, general lessons about how you work | First lines auto-loaded into every session |
| **Session** | This conversation only | The task plan, in-progress notes, scratch state | Read on demand during the task, discarded after |
| **Repository** | This workspace only | Verified build and test commands, project conventions, access patterns, API quirks, "this failed before, do X instead" notes | Read on demand when working in this repository |

The scopes are separate on purpose. A lesson about one repository's flaky
test runner does not belong in the file that loads everywhere. A preference
about how you sign emails does not belong in a project folder. Put each fact
where its lifetime is, and the context stays lean without losing anything.

---

## The rule

Add this to the assistant's always-on instructions, word for word or close:

> Consult memory before any non-trivial task. Read the user scope (already
> loaded) and the repository scope for the current workspace. If you make a
> mistake that memory already documents, that is a preventable failure, and
> the fix is to read memory earlier, not to apologize later.

And its companion, for writing:

> When a mistake looks like it could recur, write the lesson to the correct
> scope before moving on. One line. State the failure and the fix, not the
> story.

---

## Entry format

Memory entries are one-liners. User memory is auto-loaded, so every line in
it costs context on every task; brevity is what protects the budget. The
shape that works:

```
- <situation>: <what failed> -> <do this instead>
```

Examples, generic:

```
# USER.md (loaded everywhere)
- Writing: no em dashes, no exclamation points, lead with the answer.
- Reviews: reprint the whole revised draft, never a fragment.
- Status: never infer a status from a date; check the source.

# REPO.md (this workspace)
- Tests: `npm test` needs `npm install` first after a container restart.
- Publish: the sitemap regenerates wholesale; add pages to STATIC_PAGES, not by hand.
- API: the contents endpoint returns base64; decode before parsing.

# SESSION.md (this conversation)
- Plan: 1) fix the link check 2) rerun suite 3) open PR.
- Open question: does the owner want the old slug redirected? Ask before merge.
```

---

## Where does a lesson go

Run the lesson through this table. First row that matches wins.

| The lesson is about | Scope |
| --- | --- |
| How you like output to look, sound, or be structured, anywhere | User |
| A habit of the assistant's you keep correcting, in any project | User |
| A command, path, convention, or quirk true only in this repository | Repository |
| Something that failed here and the workaround that fixed it | Repository |
| What you are doing right now, and where you are in it | Session |
| An assumption you have not yet confirmed | Session, marked as open |

If a repository lesson keeps showing up across repositories, promote it to
user scope and delete the copies. If a session note turns out to be durable,
move it before the session ends, because the session scope is discarded.

---

## Housekeeping

- **Prune on read.** When the assistant consults a scope and finds a line that
  no longer applies, it removes the line. Stale memory is worse than none,
  because it is trusted.
- **Keep user scope under a screen.** If it grows past that, the first lines
  stop being the important ones. Move the long tail to a linked file that
  loads on demand.
- **Version the repository scope.** It lives in the repo, so it travels with
  the code and gets reviewed like code.
- **Never store secrets in any scope.** Memory is plain text that gets loaded
  into a model's context. Store the name of the secret and where it lives.

---

## Why three and not one

One file is what everyone starts with. It works until the file is long enough
that the assistant stops reading it, or general enough that half of it is
wrong for the project at hand. Splitting by lifetime fixes both: the always-on
file stays short because only the always-true facts live there, and the
project file can be as long as the project needs because it only loads when
you are in the project.

The system compounds. Every documented failure is a failure that does not
happen twice. The cost is one line, written at the moment you are most
annoyed and least inclined to write it.
