CLAUDE LABJP
MEMORY — Claude Code closes a cluster of long-session memory leaks, including MCP stdio stderr piling up to 64 MB per server and LSP documents staying open indefinitelyTABLES — Very large markdown tables no longer stall rendering; tables over 200 rows now show the first 200 with a "… N more rows" noticeSPEED — Sessions carrying many deny/ask permission rules no longer lose seconds every turn: rule matchers are compiled once and cachedTOOLS — print/SDK sessions with many MCP tools get up to 7x faster tool rounds thanks to cached tool-pool assemblyARTIFACTS — Claude Code Artifacts turn session work into live, shareable web pages that update in place — useful for PR walkthroughs and dashboardsDEADLINE — Opus 4.7 fast mode is removed on July 24; speed: "fast" will error, so move to Opus 4.8 fast mode before thenMEMORY — Claude Code closes a cluster of long-session memory leaks, including MCP stdio stderr piling up to 64 MB per server and LSP documents staying open indefinitelyTABLES — Very large markdown tables no longer stall rendering; tables over 200 rows now show the first 200 with a "… N more rows" noticeSPEED — Sessions carrying many deny/ask permission rules no longer lose seconds every turn: rule matchers are compiled once and cachedTOOLS — print/SDK sessions with many MCP tools get up to 7x faster tool rounds thanks to cached tool-pool assemblyARTIFACTS — Claude Code Artifacts turn session work into live, shareable web pages that update in place — useful for PR walkthroughs and dashboardsDEADLINE — Opus 4.7 fast mode is removed on July 24; speed: "fast" will error, so move to Opus 4.8 fast mode before then
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 SDK13unattended agentsstate recoveryidempotency6operations15

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-07-11
Tightening Tool Schemas From the Arguments You See in Production
Record the arguments Claude actually passes to your tools in production, then use that distribution to add enums and patterns back into your JSON Schema. With logging code and before/after numbers.
API & SDK2026-07-08
Rolling Out Agent Behavior Changes Gradually with Feature Flags
When an unattended agent changes its prompt or behavior all at once, quiet regressions hide until morning. Here is a design for assigning new behavior to only a fraction of runs, keeping a control group, and adding deterministic bucketing, canary comparison, and automatic rollback.
API & SDK2026-07-04
Reading the Claude apps gateway Announcement, I Rebuilt My Indie-Scale Control Plane
The self-hosted Claude apps gateway is a control-plane/data-plane separation you can scale down. Per-app cost attribution, model allowlists, and fail-closed spend caps, implemented as a small Cloudflare Workers proxy.
📚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 →