CLAUDE LABJP
MODEL — Claude Fable 5 reached general availability on June 9 with a 1M-token context, always-on adaptive thinking, and 128K outputPLATFORM — The Developer Platform adds code execution, an MCP connector, a Files API, and prompt caching up to one hourMCP — Admins can provision MCP connectors org-wide via Okta, giving users zero-touch access on first loginSANDBOX — Claude Managed Agents now run in your own sandbox and connect to private MCP serversCODING — Opus 4.8 scores 72.5% on SWE-bench and 43.2% on Terminal-bench, excelling at long-running workLINEUP — Opus 4.8, Sonnet 4.6, and Haiku 4.5 lead the lineup; pick the right one per taskMODEL — Claude Fable 5 reached general availability on June 9 with a 1M-token context, always-on adaptive thinking, and 128K outputPLATFORM — The Developer Platform adds code execution, an MCP connector, a Files API, and prompt caching up to one hourMCP — Admins can provision MCP connectors org-wide via Okta, giving users zero-touch access on first loginSANDBOX — Claude Managed Agents now run in your own sandbox and connect to private MCP serversCODING — Opus 4.8 scores 72.5% on SWE-bench and 43.2% on Terminal-bench, excelling at long-running workLINEUP — Opus 4.8, Sonnet 4.6, and Haiku 4.5 lead the lineup; pick the right one per task
Articles/API & SDK
API & SDK/2026-06-23Advanced

An Unattended Agent That Wakes Up to a Blank Machine Every Time

A scheduled, unattended agent wakes up on a fresh disposable machine every run: paths it cannot write to, a filesystem that has not finished booting, a working directory that has vanished. Here is how to design state recovery into the first thirty seconds, drawn from real operational logs.

Claude Agent SDK9unattended agentsstate recoveryidempotency4operations11

Premium Article

The morning the scheduled agent woke up, the first thing it returned was neither success nor failure. It was a single line: could not create work tree dir: Permission denied.

The /tmp/repos path it had written to yesterday was not writable today.

The cause was quick to find. The machine the agent runs on is rebuilt from scratch every time — a disposable sandbox — and the directory's owner happened to be assigned to a different user that run. As an indie developer, I run unattended article generation across four sites at Dolice Labs, and whenever I take the "the environment is different every time" assumption lightly, the nightly task ends quietly with zero output.

The reliability of an unattended agent is decided not by clever core logic, but by the first thirty seconds. This piece is about those thirty seconds: how to design startup and state recovery right after a cold boot.

Compute is disposable; state lives somewhere else

The first mental shift is to abandon the naive expectation that "the same machine remembers where it left off."

Most scheduled runs spin up a new sandbox each time. Files you wrote last run are gone, packages you installed do not persist, and cwd and environment variables do not carry over. The only state you can rely on lives outside the compute.

In my own operation, I split durable state into three layers.

LayerWhere it livesRole
Code / artifactsGit remoteThe work itself. It only counts once pushed
Reference data / configCloud-synced workspacePolicy, keywords, tokens. Treated as near read-only
Run historyPer-date log filesThe only way to tell your future self what today already did

With these three layers in place, the sandbox can be burned down as often as it likes. The agent rebuilds its state from external truth on every run. Conversely, the moment any of these three relies on a local temp directory, that information is lost on the next cold boot.

Write the startup sequence defensively

Before any real work, I always run a short sequence to prepare the environment. Cut corners here and the later stages fail silently.

The order matters: (1) wait for the filesystem to come up, (2) discover the working directory dynamically, (3) secure a writable work area, (4) retrieve credentials.

#!/usr/bin/env bash
set -euo pipefail
 
# (1) Wait for the mount — right after a cold boot, files are invisible for a few seconds
WS=""
for i in $(seq 1 10); do
  WS="$(ls -d /sessions/*/mnt/Workspace 2>/dev/null | head -1)"
  [ -n "$WS" ] && [ -d "$WS" ] && break
  sleep 3
done
[ -n "$WS" ] || { echo "FATAL: workspace not mounted after 30s"; exit 1; }
 
# (2) Check the first-choice work dir is writable; fall back to $HOME if not
WORK_BASE="/tmp/repos"
if ! mkdir -p "$WORK_BASE/.probe" 2>/dev/null; then
  echo "WARN: $WORK_BASE not writable, falling back to \$HOME/repos"
  WORK_BASE="$HOME/repos"
  mkdir -p "$WORK_BASE"
fi
rmdir "$WORK_BASE/.probe" 2>/dev/null || true
 
# (3) Read credentials from synced storage, not env vars (survives reboots)
TOKEN="$(grep -A1 '^MySite' "$WS/_tokens/tokens.txt" | tail -1 | tr -d '[:space:]')"
[ -n "$TOKEN" ] || { echo "FATAL: token missing"; exit 1; }
 
echo "ready: WS=$WS WORK_BASE=$WORK_BASE"

The key is to never assume /tmp is writable. Actually create a small directory; if it fails, quietly escape to $HOME. The Permission denied I hit on this run was exactly the kind of failure that one .probe test absorbs.

Searching with a wildcard like ls -d /sessions/*/mnt/... is also deliberate. The session name changes every run, so a hardcoded path points at a directory that will not exist next time. Dynamic discovery is the cheapest insurance against an environment that keeps changing.

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
A copy-pasteable bash startup sequence built for disposable environments: mount detection, boot waiting, dynamic working-directory discovery, and fallback paths
An idempotency guard that asks durable storage whether today's work is already done, plus the two-signal check that stops duplicate output
The three traps I hit running Dolice Labs unattended — write permissions, cloud-synced files, and boot latency — written up as field-tested operational guidance
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

API & SDK2026-06-14
Making Claude Agent SDK Tools Idempotent — Stopping Double Execution with Deterministic Keys and an Outbox
An implementation log for stopping a Claude Agent SDK retry or session resume from processing the same payment twice. Three patterns — deterministic idempotency keys, an outbox, and a lightweight wrapper — with runnable code and production metrics.
API & SDK2026-06-12
Reallocating My Automation Pipeline Ahead of the June 15 Billing Change
On June 15, the Agent SDK, headless Claude Code, and GitHub Actions move to monthly usage credits. I audited every stage of my publishing pipeline against measured token logs and rerouted each one across three execution paths. Here is the reasoning.
API & SDK2026-06-02
Guard Your Agent's Destructive Operations with Pre- and Post-condition Contracts
A design for wrapping an autonomous agent's writes in deterministic pre- and post-condition checks. A contract gate stops the destructive operations that better prompts can never reliably prevent.
📚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 →