TL;DR Add two sentences to the task's prompt: at the start, "read the whole lessons page" (with its address); at the end, "append one line with the date and what you learned, unless it's already there". For a cloud task, make the page a connector page or a file that lands on the default branch.
Outside a Project, every run of a cloud scheduled task is a new Claude Code session on a fresh clone of the repository, and a local Desktop task starts a new session every time too. None of them inherits the previous run's conversation. What a run learned is gone when it ends, unless it writes it somewhere the next run reads at the start.
What a run finds when it starts
The run that wrote this tip is a cloud scheduled task. This is what its machine held before it started working:
$ uptime -s
2026-11-09 09:35:38
$ ls ~/.claude/projects/-home-user-ai-infra/
c5d90c3a-3c7f-5068-bf22-93907f591544
c5d90c3a-3c7f-5068-bf22-93907f591544.jsonl
$ find ~/.claude -name MEMORY.md | wc -l
0
A machine booted that same minute, a single transcript (its own) and no MEMORY.md. Auto memory lives on the machine where it was written and isn't shared with cloud environments, so yesterday's run and the one before it left nothing here.
What it looks like when it works
My seven scheduled tasks for wmedia.es, six in the cloud and one in Desktop, share a lessons page in Notion: 31 entries since October 29. Every run reads it in full before touching anything and, when it finishes, appends a line only if it learned something the page doesn't already say. One of those lines, written by the November 3 run:
2026-11-03, CC Tips (cloud): through the wmedia JSON-RPC helper,
search-content-tooltakeskeyword(aqueryargument returns an error string, which a script readingtipssees as no hits) ...
Tried again today from this very run: with query, the wmedia.es server answers this:
"The keyword field is required."
A script looking for the list of tips reads that as zero results: the topic looks unpublished and the routine writes a tip that already exists. That line cost one run; the runs after it don't pay again.
How to give a task memory
1. Pick where the page lives
| The task runs | Where the page goes |
|---|---|
| In the cloud | A connector page (Notion, Google Docs) or a file that reaches the default branch |
| In Desktop, locally | A file in the task's folder; with Worktree on, every run works in its own copy, so a connector page is safer |
| In the cloud, inside a Project | It already has one: the run is a thread, it may continue an earlier one, and every cloud thread reads the project's MEMORY.md when it starts |
2. Add the two sentences to the prompt
Before anything else, read the whole lessons page at <page address>
and apply what it says. When you finish, append one line with the date,
what happened and what you learned, only if the page doesn't say it yet.
Append, never rewrite.
The prompt is what the page can't be: the assignment. The run carries out the prompt as its task, while what it reads along the way keeps the handling of any external content, so the prompt is what says why the page gets read.
3. For a file in the cloud, tell it which branch to push
Every run starts from the default branch, unless the prompt names another or a pull request event triggered it, and Claude pushes its work to a claude/... branch unless the prompt names another. A notes file left on claude/... is invisible to tomorrow's run. Ask it to commit only that file on main and push, and if main moved, to git pull --rebase and push again. Your GitHub branch protection rules or rulesets, applied to the GitHub access you connected, decide whether it can.
4. Prune the page
Every run reads all of it, and pays for that in tokens. Once a lesson has become a rule, move it into the repo's CLAUDE.md or the prompt and delete it from the page. Another of my routines keeps a log that reached about 80,000 characters, and reading it no longer fit in the tool's answer: since then every run saves it to a file and reads only the top entry.
The cases you'll run into
- Auto memory isn't enough for a local task. Claude decides what to save and doesn't save something every session, and it loads only the first 200 lines or 25 KB of
MEMORY.md. It's also per repository, so the task shares it with your interactive sessions in that repo. - Two runs at once. A GitHub trigger opens an independent session for each event: two PRs updated almost together are two runs with the page open. That's why it says "append, never rewrite": a run that rewrites the whole page wipes out the line the other one just wrote.
- Continuing isn't remembering. If a run stopped halfway, write to that same run; the page is for what every run after it should know.
Official docs: Automate work with scheduled tasks · Auto memory · Give a project standing context