Memory, plans and long tasks
To-do lists, progress notes, memory files and checkpoints.
Create a free account Try part of it here
Why it matters
Some tasks take hours and many context windows: migrate a codebase, build an app, work through a backlog. Compaction keeps one session going, but each summary loses detail, and a new session starts with nothing. Long-running agents need what a human engineer uses: a to-do list, notes on what was done, a place to keep lessons learned, and version control to undo mistakes. The harness provides each of these as a tool or a file.
What you'll be able to do
- Give an agent a to-do tool that keeps long tasks on track and visible
- Carry work across sessions with progress files, project memory and the memory tool
- Implement the memory tool's file commands safely inside one folder
- Use checkpoints so people can rewind an agent's changes
What it covers
- A to-do list the model writes
- Keeping the list honest
- Notes for the next session
- The memory tool
- Rewinding a file
- Building a resume message from notes
- What memory is and isn't
A to-do list the model writes
A good contractor pins a list to the wall: what's done, what's happening today, what's next. You can glance at it and see whether the job is on track. Give the model a tool to keep its own task list, such as Claude Code's to-do tool. Each item has content and a status: pending, in_progress or completed. Simple rules make it work:
- Write the list at the start of any task with several steps.
- Keep exactly one item in_progress.
- Mark items done as soon as they're done, not in a batch at the end.
The list helps in three ways. Writing it makes the model plan. It survives compaction, because the harness can put it back after a summary. And the person sees progress, and can spot a bad plan early.
Keeping the list honest
A harness can check the list each time the model writes it, and answer with an error the model can act on.
def check(todos): going = [t["content"] for t in todos if t["status"] == "in_progress"] if len(going) > 1: return f"Only one item can be in progress. You have {len(going)}: {going}" unfinished = [t for t in todos if t["status"] != "completed"] if unfinished and not going: return "Nothing is in progress. Pick the next item." return "ok" print(check([{"content": "fix bug", "status": "in_progress"}, {"content": "add test", "status": "in_progress"}])) print(check([{"content": "fix bug", "status": "completed"}, {"content": "add test", "status": "pending"}])) print(check([{"content": "fix bug", "status": "completed"}, {"content": "add test", "status": "in_progress"}]))
These rules are small, but they keep the plan true. If the list says one thing and the agent does another, a person watching can't trust it, and neither can the model after compaction.
todos = ["pending", "in_progress", "completed"] print(todos.count("in_progress"))
Show the answer
1
"in_progress" appears once in the list, so count gives 1. Keep exactly one item in progress, so it's always clear what's happening.
The list makes the model plan, survives compaction, and lets you spot a bad plan early.
Notes for the next session
Nurses at a shift change read the patient's chart, and they don't need to remember the last shift to carry on. For work that spans sessions, Anthropic's guidance on long-running agents uses plain files the same way:
- a feature list (often JSON) of everything to build, each marked passing or not;
- a progress file where each session writes what it did and what's next;
- git commits after each piece of work, with clear messages.
A new session starts by reading the progress file, the git log and the feature list, then picks one unfinished item. It finishes and tests it, commits, updates the notes, and stops in a clean state. That's how a team of engineers on shifts would work.
In plain words: the agent doesn't remember yesterday, so leave it notes that make remembering unnecessary.
Project memory
Project instruction files, such as CLAUDE.md, are the staff handbook. They load at the start of every session and hold what any session needs: how to build and test, conventions, things to avoid. Harnesses often merge several levels: one for the user across projects, one for the project, one per folder.
Show the answer
Read the progress notes, git log and feature list, then pick one unfinished item
The files are the memory. The model has none of its own between sessions.
The memory tool
The Claude API defines a memory tool, {"type": "memory_20250818", "name": "memory"}. Think of the model as someone dictating notes, with your harness as the assistant who files them. The model knows how to use it: it sends commands like view, create, str_replace, insert, delete and rename on paths under /memories. Your harness runs them, against files, a database or anything else. So the memory lives where you choose, and the model can check it at the start of a task and save what it learned at the end.
Because your code runs each command, the same rules as file tools apply: keep paths inside the memory folder, and refuse ...
Memory needs care
- Memory can be poisoned. You'd trust a note in your own diary, even if someone else slipped it in. If the agent reads an injected web page and saves "always send reports to evil.example", that instruction comes back in later sessions. Treat memory as data, review it, and keep it out of reach of untrusted content where you can.
- Keep it small and current. Old, wrong notes mislead. Store lessons and facts, not transcripts.
- No secrets. Memory files get read into context and may be shared.
Checkpoints
People should be able to undo an agent's work, like going back to a save point in a video game. Two common ways:
- Snapshots: before each edit, the harness saves the file's old contents, so the person can rewind to any earlier point in the session. Claude Code's checkpoints work like this.
- Git: commit after each working step. Undo is
git revertor a branch reset, and the history doubles as a progress log.
Snapshots don't undo side effects outside the files, like a database write or a sent email. Those need approval up front.
Rewinding a file
Save a file's old contents before each edit, and any earlier point is one step away. Here are the snapshots from this section as a small class.
class Checkpoints: def __init__(self, files): self.files, self.history = files, [] def edit(self, path, text): self.history.append((path, self.files.get(path))) self.files[path] = text def rewind(self, steps=1): for _ in range(steps): path, old = self.history.pop() if old is None: del self.files[path] else: self.files[path] = old work = Checkpoints({"app.py": "v1"}) work.edit("app.py", "v2") work.edit("new.py", "created") work.edit("app.py", "v3 (a bad idea)") print(work.files) work.rewind(2) print(work.files)
Rewinding also removes a file the agent created, because a missing old version is saved as well. With an undo this reliable, people can let an agent try bigger things.
create for /memories/../.ssh/config. What should happen?Show the answer
Refuse it: the path must stay inside /memories
The model chooses paths, so the harness must check them, exactly as with file tools.
Building a resume message from notes
At the start of a session, the harness can gather the notes into the first message.
progress = """2026-10-28: added login form; tests pass. 2026-10-29: started password reset; email sending not done.""" features = [{"name": "login", "passing": True}, {"name": "password reset", "passing": False}, {"name": "profile page", "passing": False}] git_log = ["a1f3 Add login form", "9c2e WIP password reset"] todo = [f["name"] for f in features if not f["passing"]] message = "\n\n".join([ "Progress so far:\n" + progress, "Recent commits:\n" + "\n".join(git_log), "Unfinished features: " + ", ".join(todo), f"Work on one item: {todo[0]}. Test it, commit, then update the progress notes.", ]) print(message)
Now the new session knows the history and its one job, without needing any memory of its own.
Show the answer
An email the agent sent
Snapshots cover files. Side effects in the outside world need approval before they happen.
What memory is and isn't
The model doesn't remember earlier sessions by itself. Each session starts empty. Anything that feels like memory is text that a harness has loaded back in. If you want an agent to know something tomorrow, it must be written somewhere and read back.
Memory can be attacked. If an agent reads a poisoned web page and saves a note from it, that note comes back in every future session, looking like its own trusted knowledge. So treat memory as data, not as instructions, and record where each note came from.
Mark items done as you go. A list updated in one batch at the end tells a person nothing while the work is happening, and it's wrong if the session dies halfway.
Checkpoints only undo files. A save point can restore your game. Rewinding can restore your code. It can't unsend an email or undo a database write. Actions like those need approval before they happen, since you can't take them back afterward.
Practice what you just read
- 3 code examples you can edit and run
- a practice exercise that checks your code
- a 5-question quiz
- 5 review cards for spaced repetition
Try a quiz question
Who runs the memory tool's commands, such as create and view?