Post ·
Sessions Forget: Designing Resume State for AI Agents
AI sessions lose everything that lives only in context. A resume page, a ruled-out list, and fixed close and boot rituals keep long-running AI work intact across days and machines.


An AI session has a context window, not a memory. Everything it knows about your work lives in that window, and the window ends: the session closes, the context gets compacted, you switch machines, you come back after two weeks. If the state of your work only exists in the conversation, it is gone.
Running an AI-maintained knowledge base for my architecture practice, I learned this the expensive way. The fix was not a smarter model or a memory plugin. It was a few plain files and two rituals that I run the same way every time.
Separate durable memory from working state
The knowledge base itself — entity pages, decisions, registers, the git history — is durable. It does not need rescuing. What gets lost is the working state: which threads are open, what the next action is, what is blocked and on whom, what I already tried and ruled out. That state needs its own home, and it needs to be small.
I split it three ways, one question per file:
- index.md answers "what exists?" The catalog of everything, organized by type.
- inbox.md answers "what is the full backlog?" Every open question and follow-up, split into active and later.
- NOW.md answers "what is in flight right now?" The resume page. The only page I open on a cold start.
What goes on the resume page
NOW.md is deliberately tight. It holds:
- At most five active threads. Each with a status, a next action, what it is blocked on, and an absolute due date. "Next week" becomes a real date before it is written down.
- Watches and tripwires. Things that should change what I do if they happen.
- Decisions pending ratification. So nothing gets treated as settled before I have settled it.
- A ruled-out list. One line per approach that failed or that I rejected: date, what, why, source. The model checks it before proposing anything. This single section ended the most frustrating failure mode of all — a fresh session confidently re-suggesting the thing we abandoned last Tuesday.
- A dated last-session line and a files-touched list. A short list of what changed and where it lives, so I never have to hunt for yesterday's work.
The close ritual
Before a session ends, state is flushed to disk. Never end with anything important living only in context.
- Run the pending scripts and the integrity checks.
- Update NOW.md — threads, next actions, the last-session line, the files touched.
- Append a dated entry to the log.
- Trim the active backlog. Promote, demote, mark done.
- Commit and push.
The boot ritual
On a cold start, the session reloads in a fixed order: the operating contract, then NOW.md, then the active backlog, then the last one or two log entries, then optionally the git log. The same order every time means a resume after two weeks rebuilds the same working state as a resume after two hours. The boot also opens with a short list of what changed since I was last here, so the first thing I see is where things are.
Anything that must happen at a set time gets a scheduled task. Continuity should be triggered, not remembered.
Budget the boot files
The resume files are read whole on every start, so every byte is paid on every session. Mine grew until boot alone ate a noticeable share of the context. Now a script enforces budgets on NOW.md and the active backlog, and trimming follows a fixed order, lowest value first: finished items move to an archive, older session notes move to the log verbatim, stale items move to the backlog, and long rows shrink to one line and a link. Nothing is deleted, and active threads and ruled-out lines are never trimmed to make budget.
Tell compaction what to keep
When a long session compacts its context, the summary decides what survives. Left alone, it keeps a narrative and drops the specifics. So I spelled out what the summary must carry exactly: the active thread IDs and their next actions, every file changed this session, any commit not yet pushed, canonical figures quoted in the session, any decision I ratified — verbatim — and the output conventions. Tool output and exploration get dropped; conclusions keep their evidence.
When several sessions share one memory
Sessions have no live channel to each other. They coordinate through the files. Two lessons:
- Hot files have one writer. The resume page, the index and the backlog are single-writer. With file sync in the path, two sessions writing the same file is a silent last-write-wins clobber. Default to one writing session at a time; the close ritual is the handoff.
- Shared logs get split. My single activity log was truncated by a cloud-sync client at around 189 KB. The monthly split truncated again. The fix was one log file per lane per month, so concurrent writers never touch the same file, plus a check that fails if an append-only file ever gets shorter.
Copy this: a NOW.md and the rituals
The resume page template:
# NOW - resume state
## Active threads (max 5)
| ID | Thread | Status | Next action | Blocked on | Due |
|----|--------|--------|-------------|------------|-----|
| T1 | ... | ... | ... | - | 2026-10-15 |
## Watches / tripwires
- If <event>, then <what changes>.
## Pending ratification
- <decision> - proposed <date>, awaiting <who>.
## Ruled out - don't repeat
- 2026-09-24 - <approach> - <why it failed> - <source>
## Last session (2026-09-26)
<two or three lines>
### Files touched
- wiki/<folder>/<page>.mdAnd the section that makes the AI actually use it:
## Session continuity
Session context is temporary. The files are the memory.
Close ritual - before a session ends:
1. Run pending checks and scripts.
2. Update NOW.md: threads, next actions, last-session line, files touched.
3. Append a dated entry to log/YYYY-MM.md.
4. Trim inbox.md: mark done, promote, demote.
5. Commit and push.
Boot ritual - on a cold start, read in this order:
CLAUDE.md -> NOW.md -> inbox.md (active) -> last 1-2 log entries.
Open with a short list of what changed since the last session.
Rules:
- Use absolute dates. Convert "next week" to YYYY-MM-DD.
- Check "Ruled out" before proposing any approach.
- A thread untouched for 10+ days is stale: re-confirm before acting.
- NOW.md, index.md and inbox.md have one writer at a time.
When compacting, the summary must keep exactly: active thread IDs and next
actions, every file changed this session, unpushed commits, figures quoted
this session, and any decision I ratified, verbatim.Start here
You do not need my setup. Tomorrow, with whatever assistant you use:
- Create a NOW.md with five threads, next actions, absolute dates, and a ruled-out list.
- End every session by updating it and committing.
- Start every session by reading it first.
That is most of the value. The rest is what I added after each thing broke.