DEV Community

Build Loops
Build Loops

Posted on

I Built a Session Log That Survived My Migration. Here's the Three-File System.

A few weeks ago I spent a couple of hours on a small side project with my agent. It went fine. I closed the session, and the session got logged.

That log is the reason the project still works today. When we came back to it, the agent tried to change code that was already working — and the MEMORY.md entry stopped it. Not the prompt. Not a warning. A three-line note written at the end of the last session. If that entry hadn't been there, it would have repeated the exact same mistake.

That's the whole system, really. Three files in the project root, plus one instruction in AGENTS.md that forces the agent to read them. This is how I stopped re-explaining, stopped repeating mistakes, and stopped paying for both. The short version: memory isn't something you install — it's something you declare, and log.


The system in one line

Three files in the project root, plus one AGENTS.md instruction that makes the agent read them in the right way:

File Role Read every session?
AGENTS.md Rules, role, guardrails — how to do things properly and what not to do Yes (it is the config)
MEMORY.md Active session log — 3-5 line entries per session Yes — forced, via a top-of-AGENTS.md instruction
ARCHIVE.md Filing cabinet — stale-but-valuable entries moved out of MEMORY.md No — only surfaced when relevant

The whole trick is the last column. One file is loaded always. One is loaded always and forced. One is never loaded by default. Getting that column right is what keeps the system alive for months instead of rotting in week two.


The write side: what a session entry captures

At the end of a session the agent writes a short entry to MEMORY.md — three to five lines. Core info, the key decisions made, the plans still open, and what was actually done. Short on purpose: long enough to reconstruct where things left off, short enough that the file stays cheap to load next session.

A real entry looks like this:

## 2026-07-22 — pricing-page refactor
- Finished the Stripe checkout flow; working state committed on main.
- DECISION: keep the legacy free tier, don't grandfather price changes.
- OPEN: update the pricing copy, then archive the old discount logic.
Enter fullscreen mode Exit fullscreen mode

Four lines. Reconstructable tomorrow, cheap to load forever. That's the whole write-side discipline: if an entry needs more than five lines, it's two entries, or it belongs in a doc the entry points to.


The read side: the one line that makes it a memory

Here's the part every "create a memory file" guide misses: the file alone does nothing.

A memory file only works if the agent actually reads it, at the start of the session, before it does anything else. So the first instruction in my AGENTS.md is:

Read `MEMORY.md` at the start of every session before proceeding with anything.
Enter fullscreen mode Exit fullscreen mode

That line is the difference between a file that exists and a memory that loads. It's also why this is a re-declaration story, not a setup story: I didn't install anything. I declared a rule in AGENTS.md that makes the agent treat the file as memory. Same file, same instruction, works in any tool that reads AGENTS.md — I carried this exact setup across Claude Code to OpenCode, and it came with me.


The division of labor: AGENTS.md vs MEMORY.md

Two files, two jobs.

AGENTS.md is the constitution: rules, role, guardrails — how to do things properly, and what not to do. MEMORY.md is the diary: what actually happened, what was decided, what's planned, session by session.

Rules that shouldn't be forgotten live in one. Context that shouldn't be re-discovered lives in the other. When both are maintained, the agent rarely needs you to re-say something you already told it once — and here's the part that pays for the whole setup: the specific thing you forgot to say in a prompt is often already in the files. AGENTS.md for how to work, MEMORY.md for what happened last time. The system catches the mistakes you didn't think to warn it about.


The part no one else covers: ARCHIVE.md, the cold tier

Every memory guide stops at MEMORY.md. None of them answer what happens when it grows.

And it will grow. MEMORY.md is read at the start of every session — so every line in it costs tokens on every session, forever. A file that starts at five lines becomes five hundred, and every session is paying for all of them.

The fix is a third file: ARCHIVE.md, the filing cabinet. Everything that's not relevant to the current project or the current season of work — but too valuable to delete — moves there. Long-memory hygiene, token-budget hygiene, same action.

Let me be concrete about why this is money, not just tidiness. Paid plans meter usage in a five-hour session window plus a weekly cap — when you hit it, you're paused until reset, and on some setups overage means a bigger bill for the same mistakes. API-based setups bill per token with no weekly quota at all. Either way, an always-loaded memory file is charged on every session.

Anthropic's own numbers put typical usage at roughly $13 per developer per active day, with 90% of developers under $30 a day — so the file sitting in your context isn't pennies, it's a line item. Shrink the always-loaded set and you shrink every session's cost. That's the cold tier's whole job.

A before/after shows it. Before, this sat in MEMORY.md and cost tokens every session:

- 2026-02 — researched auth libraries; decided on auth.js over clerk. Details in research/auth.md.
Enter fullscreen mode Exit fullscreen mode

After the move, MEMORY.md says just this — and the archive holds the detail:

- 2026-02 — auth decision: auth.js (not clerk). Rationale archived → ARCHIVE.md.
Enter fullscreen mode Exit fullscreen mode

The always-loaded set shrank by one line. Multiply that across the forty entries you're not touching this month, and the difference is real — not because tokens are expensive per line, but because the whole file is re-read at the start of every single session.


The archiving rule: surface on demand, never by default

Two rules keep the archive from becoming the new memory problem.

First: archiving is human-decided. The agent can suggest what's cold, but you're the one who owns the line between "still relevant" and "archive." It's your project — the agent has no idea what you're about to resurrect.

Second — the one everyone misses: tell the agent to only surface ARCHIVE.md when relevant, and never load it by default. If you forget that instruction, the agent reads the whole archive every session, and the token savings you built the file for quietly disappear. The cold tier only works if it stays cold until you reach for it.


The honest counterweight: this rots if you ignore it

The hard part isn't the setup — it's that the setup is hard to correct later.

Most people write AGENTS.md and MEMORY.md once, then never touch them again. The file grows, the rules drift, entries stop being written, and slowly the token bill climbs past what you planned. On paid plans with usage limits, that's real money spent re-doing the exact same mistakes.

The system only keeps working if you treat maintenance as part of the system — not as a one-time fix. Two habits keep it alive: archive on a schedule, and re-read the file yourself now and then. If the agent is the only one reading MEMORY.md, it stops being your memory.


Do I still need this if my agent has auto-memory?

Claude Code ships auto-memory — it saves what it thinks is worth keeping, consolidates it, and caps the index, with a "saved N memories" summary. OpenCode has no native cross-session memory at all (the feature request is still open). So the honest answer depends on your tool.

Let me be fair to auto-memory first: it's genuinely convenient, and it catches things you'd never think to log. It's not nothing. But it's a black box — you don't get to see what it kept, what it quietly dropped, or what it'll do with it next week. An explicit session log is the opposite: greppable, reviewable, version-controlled, and portable to whatever tool you use next. Native memory is convenience; the log is a system.

Use both if it helps. Just don't confuse "the tool remembers something" with "I have a memory system."


Don't do these (the checklist)

  • Write MEMORY.md once and never touch it again. It rots, and you pay for the rot on every session.
  • Let the file grow unbounded. Every line is charged on every session — the cold tier exists for a reason.
  • Forget to tell the agent to surface ARCHIVE.md only when relevant. It'll read the whole archive every session and eat the savings.
  • Treat auto-memory as a substitute for a reviewable log. Convenience isn't a system.
  • Re-say in prompts what the files already say. If the agent broke code you already told it about, the files didn't load — fix that, don't repeat yourself.

The verdict

A three-line note written at the end of a session stopped my agent from breaking working code. That's the incident that earned this system — and it's the reason I'll keep logging, keep archiving, and keep the always-loaded file small.

Memory is something you declare and log, not something you install or inherit. The smaller the always-loaded set, the cheaper every session. The colder the archive, the longer the system lives. It survived a migration because it lives in files, not a tool — and files follow you anywhere.


If you've been fighting the same battle — an agent that forgets, a memory file that grows without bound — the fix starts with the file that tells the agent how to work: Why Your Coding Agent Keeps Making the Same Mistakes — AGENTS.md Fixes It.

What's in your MEMORY.md that you'd never want the agent to forget? And what's the one entry you wish you'd archived before it cost you tokens?

This is the session-log rebuild, expanded from the migration diary (what broke when I switched from Claude Code to OpenCode). Next up: why loaded rules aren't obeyed rules.

Top comments (1)

Collapse
 
buildloops profile image
Build Loops

What's in your MEMORY.md you'd never want the agent to forget? And what's the one entry you wish you'd archived before it cost you tokens?