CLAUDE LABJP
AUTO — Auto mode becomes the default in Claude Code today, August 14, across the Pro, Max, and Team plansPRICE — Sonnet 5 promo pricing of $2/$10 per Mtok is now permanent; the increase to $3/$15 planned for September 1 will not happenFIX — Version 2.1.231, released August 13, fixes MCP OAuth sign-in failing with a redirect URI mismatch on servers that use a pre-registered client, such as SlackSUNSET — The legacy Workbench and the experimental prompt tool APIs retire on August 17, now three days awayMCP — Support for the new MCP 2026-07-28 spec is rolling out, bringing a stateless core, stronger OAuth and OIDC authorization, and versioned extensions for Apps and TasksBOOST — The temporary 50% weekly usage boost for Claude Code subscribers runs through August 19AUTO — Auto mode becomes the default in Claude Code today, August 14, across the Pro, Max, and Team plansPRICE — Sonnet 5 promo pricing of $2/$10 per Mtok is now permanent; the increase to $3/$15 planned for September 1 will not happenFIX — Version 2.1.231, released August 13, fixes MCP OAuth sign-in failing with a redirect URI mismatch on servers that use a pre-registered client, such as SlackSUNSET — The legacy Workbench and the experimental prompt tool APIs retire on August 17, now three days awayMCP — Support for the new MCP 2026-07-28 spec is rolling out, bringing a stateless core, stronger OAuth and OIDC authorization, and versioned extensions for Apps and TasksBOOST — The temporary 50% weekly usage boost for Claude Code subscribers runs through August 19
Articles/Cowork
Cowork/2026-06-30Advanced

Trusting a Three-Day-Old Mirror: Stopping Unattended Tasks from Acting on a Stale Working Copy

A persistent clone reused for speed quietly drifts from the remote. Read 'has this article been fixed yet?' from an out-of-sync tree and your unattended task duplicates work or 'succeeds' against an old world. Here is a HEAD-match plus writability preflight, with a self-healing re-clone, in bash.

Cowork33scheduled-tasks4automation101git17reliability17

Premium Article

An unattended scheduled task can log "success" while the thing it produced is still from a previous timeline. As an indie developer, I run four AI blogs (Dolice Labs) as Cowork scheduled tasks, and one morning's log gave me a jolt. Before editing, I checked "has this article already been revised?" against my local clone — but that clone was three days old, and in reality another run had finished updating the very same article upstream. I was one step away from rewriting the same piece twice.

Not a single error fired. The git clone had succeeded, the files were readable, the quality gates passed. And yet the ground my decision stood on had shifted. This class of incident shows up not as a "failure" but as "correct processing on top of an outdated truth," so no exception handler will catch it. Here is how to treat a persistent clone as a cache and verify its freshness as a contract before you make any decision.

Why a persistent clone drifts in silence

For speed, most automations don't re-clone the working repo every run. They keep it somewhere like /tmp/repos/{site} and update with git pull --rebase. That's a sound optimization. The danger is that downstream steps implicitly assume the persistent clone is "the latest." Drift enters through three paths.

First, another run has already moved ahead. If several scheduled slots (morning generation, midday revision, nightly recovery) touch the same repo, another run has pushed since your last pull. Your tree doesn't know about that push.

Second, ownership flipped and the pull itself failed silently. On Cowork's VM, /tmp/repos/ can persist across sessions owned by nobody:nogroup, and then git pull and writes are both rejected. If your recovery appends || true, the step keeps going after failing — and you decide on top of an old tree.

Third, a rebase finished halfway. If a prior run hit a conflict or interruption and couldn't complete the rebase, it may leave a detached state or a partial commit. git log looks plausible but isn't current.

The common thread: readable but old. That is exactly why "could I read it?" is the wrong question, and "does it match the latest?" is the right one.

Why deciding on a stale tree breaks quietly

An unattended task reads its local tree mostly for decisions that come before processing. Questions like these:

The decisionWhat a stale tree does
Does this slug already exist?Mistakes an upstream-added article for "missing" and creates a duplicate slug
Has this article been revised already?Sees "not done" for something already fixed, and rewrites it twice
Do JA and EN counts match?Calls it balanced on an old count, missing a real mismatch
Did we just publish this topic?Reads an old article list, judges "new," and duplicates the subject

When the decision is wrong, no amount of correct processing afterward saves the result. Worse, the failure mode is "clean exit," so the log reads Status: SUCCESS. The principle I hold onto: a decision made on an unverified tree is invalid, even if its conclusion looks right. Guarantee freshness before the decision. Design it as a matter of ordering.

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
Three ways a persistent clone goes stale (another run advanced it after push, ownership flipped to nobody, a half-finished rebase) and how each one poisons decision reads
A sub-second preflight that matches local HEAD against remote via git ls-remote and probes .git writability before any decision is made
A self-heal flow that catches up with pull --rebase, falls back to a fresh clone under $HOME when it can't, and treats any decision made on an unverified tree as invalid
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-05-15
git clone Fails in Cowork Scheduled Tasks — Diagnosing /tmp Permission Errors and Disk Space Issues
When git clone fails with Permission denied or No space left on device in Cowork automated tasks, the root cause is often /tmp directory ownership or disk exhaustion. Learn how to diagnose both and apply a $HOME fallback pattern for reliable automation.
Cowork2026-07-05
When Claude Declines a Request on Safety Grounds, What Should an Unattended Pipeline Return?
A third kind of ending that is neither an error nor a normal completion — a safety decline. Here is how to fold it into a pipeline you run unattended, with a classifier and a review-queue design drawn from indie development.
Cowork2026-06-27
Logged as success, but it produced nothing — stopping silent failures in Cowork scheduled tasks with end-of-run assertions
A Cowork scheduled task exits 0, yet not a single artifact was produced. Trusting the exit code alone hides this silent failure. Here is how to turn your definition of done into end-of-run assertions that fail loudly with an evidence log.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →