◉CLAUDE LABJP
●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.302 — Fork subagents are now on by default in claude -p, the Agent SDK and the desktop app. Turn them off with CLAUDE_CODE_FORK_SUBAGENT=0 (10/16)●2.1.301 — Unattended retries now stop on their own when a usage limit is hit instead of waiting (10/15). Latest is 2.1.303 (10/18)●SONNET 4.5 — Retires on the Claude API on 11/30, 41 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Cowork
◈ Cowork/2026-09-05Advanced

I verify what my Cowork memory claims instead of trusting its timestamp

Persistent memory keeps asserting whatever was true the day you wrote it. After an unattended job quietly read an empty folder for months, I stopped judging memory by its modification date and started attaching a verification step to every claim that can rot.

Cowork51memory9scheduled tasks13operations30

✦ Premium Article

On a Friday evening I noticed that one of my asset-collection jobs had finished cleanly with a count of zero.

No error. No warning. The log had the count and the elapsed time, nothing else. When I walked through the same steps by hand, the answer showed up quickly: the folder the job was reading had been emptied months earlier, when I reorganised where those files live.

I remembered moving them. What I had not remembered was that the old location was also written down in persistent memory. The memory file itself had been touched a few weeks earlier, so by its modification date it looked recent enough. The line inside it still pointed at an arrangement from half a year ago. The timestamp was telling me how fresh the file was, not how fresh the claim was.

A memory is an assertion, not a fact. Check that it still holds, once, before handing it over. Since I started running more unattended work as an indie developer, that sentence has sat underneath the whole setup.

The busiest memory files hold the oldest claims

For a long while I worried mostly about what went into memory. Don't write too much, don't mix in secrets, don't duplicate. All reasonable, and all concerned with the moment of writing. The failure happened at the moment of reading, six months later.

Modification dates mislead here in a specific way. You touch a memory file when you want to add something new, and the older lines ride along untouched. So the more actively a memory grows, the more unverified assertions it quietly accumulates inside itself.

A human reading that line would pause — didn't I move that? An unattended run does not pause, because nothing gives it a reason to doubt the premise it was handed. In my experience this class of miss never even registers as a failure. The premise is stale, but the procedure itself completes exactly as written.

I wrote separately about jobs that report success while producing nothing. This one was the same shape with the cause sitting outside the job, in the memory it was given.

Sorting claims that rot from claims that don't

My first instinct was to give every memory an expiry — three months, then re-read it. Straightforward enough.

Trying it showed me the flaw. What expires is not the memory but the thing the memory points at. Some claims stay correct for years; others are wrong within days. A uniform expiry throws away the durable ones and keeps the rotten ones.

So I sorted by kind of claim instead. Roughly, mine fall out like this.

Kind of claimExampleHow it rots
LocationWhere assets live, canonical paths, output targetsRots quietly on every reorganisation
NameScript names, task names, flag namesRots on rename, invisibly to the reader
Outside worldModel generations, pricing, deprecation datesRots without you touching anything
ProcedureExecution order, preconditions, dependenciesRots the moment the implementation changes
JudgementWhy an approach was rejected, where a line was drawnBarely rots at all
PreferenceVoice, naming habits, phrasings to avoidBarely rots at all

The top four share a property: each one has a counterpart out in the filesystem or the world, and the presence of that counterpart can be checked by a machine. The bottom two have no counterpart. There is no command that verifies why I chose one design over another.

That line turned out to be exactly the line for "does this need a verification step?" Claims that rot get one. Claims that don't get handed over as they are.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You can stop the quiet failure where a stale memory sends an unattended run to a place that no longer holds anything, before the run even starts
✦You will be able to sort your own memory files into claims that rot and claims that do not, and decide which ones deserve a verification step
✦You get a dependency-free checker and loader you can drop into any unattended pipeline, so failed claims are held back in the open rather than dropped in silence
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◈ Cowork2026-09-16
The scheduled task that only ran on days my desk was awake
Cowork scheduled tasks run remotely by default, but the moment one needs a local file or app, it runs only on your machine. Here is how the last field in the setup dialog decides that, and the three questions I now answer before creating a task.
◈ Cowork2026-10-16
The Token-in-URL Way of Authenticating git Stopped Working in One Scheduled Task
A git clone stopped with 'could not read Username'. Two ways of putting a token in the URL behaved differently, and this is how I ended up on askpass.
◈ Cowork2026-09-15
What you keep the agent from walking matters more than what you hand it
Searching one connected Cowork folder for the same word gave three different answers. Here is what the default search silently left out, and how to measure a folder's scan scope once before you hand it over.