Background Agents & Autonomous Loops

Work that runs while you're away: /goal, /loop, agent view, routines

Advanced 15 minBuilder
What you'll be able to do
  • Use agent view (`claude agents`) to dispatch, supervise, and manage many background sessions grouped by Needs input / Working / Completed
  • Choose between session-scoped autonomy (`/goal`, `/loop`) and durable cloud autonomy (routines via `/schedule`), and between local and cloud surfaces
  • Write a `/goal` condition that is provable from Claude's own transcript, since a fast evaluator model can only read the transcript
  • Configure `/loop` with self-pacing or a 5-field cron expression, and reach for the Monitor tool instead of a polling loop for event-driven reactions
  • Explain the worktree isolation and supervisor-daemon lifecycle that keep background sessions safe and alive
At a glance

This lesson covers the surfaces that let Claude Code keep working while you're away — and how to supervise it. Agent view (`claude agents`) is the dashboard for background sessions; `/goal` pursues a condition across turns; `/loop` schedules session-scoped work (self-paced or 5-field cron); durable cloud routines (`/schedule`) survive your laptop closing and fire on schedule, API, or GitHub triggers; the Monitor tool reacts to a process's output without polling; and underneath it all, git worktrees isolate edits while a per-user supervisor daemon keeps sessions alive. The organizing axes are session-scoped vs durable and local vs cloud. Most of these are research preview or experimental — defer to /help and the live docs for your version.

  1. 1The mental model: unattended work, and the screen that supervises it
  2. 2Agent view — the supervision screen for background sessions
  3. 3Underneath: worktree isolation and the supervisor daemon
  4. 4/goal — goal-driven autonomy across turns
  5. 5/loop — session-scoped scheduling, self-paced or cron
  6. 6Routines (durable cloud) plus event-driven reactions

The mental model: unattended work, and the screen that supervises it

The single-subagent lesson was about delegating inside one session to keep your context clean. This lesson is the opposite frame: work that runs while you're not watching, possibly for hours, possibly in the cloud, and the surfaces that let you supervise it rather than babysit it.

Two axes organize everything here:

  • Session-scoped vs durable. Session-scoped work (/goal, /loop, background Bash, Monitor) lives and dies with a Claude Code session — close the laptop and it's gone (or restored only under narrow --resume rules). Durable work (cloud routines) runs on Anthropic infrastructure and survives your machine being off entirely.
  • Local vs cloud. Agent view, /loop, and /goal are local — they run on your machine under a per-user supervisor. Routines are cloud. The Monitor and PushNotification tools are local helpers; PushNotification can reach your phone via Remote Control.

The one screen that ties the local side together is agent view (claude agents): a dashboard that lists every background session grouped by state, so you can see what needs you at a glance instead of scrolling transcripts.

text
                 unattended work in Claude Code
   ┌───────────────────────────┬───────────────────────────┐
   │        SESSION-SCOPED      │          DURABLE          │
   │  (dies with the session)   │   (survives laptop off)   │
   ├───────────────────────────┼───────────────────────────┤
   │ /goal   condition-chasing  │                           │
   │ /loop   cron / self-paced  │   routines (/schedule)    │
   │ background Bash + Monitor  │   schedule / API / GitHub │
   │ supervised in: agent view  │   managed at: claude.ai   │
   └───────────────────────────┴───────────────────────────┘
         LOCAL (your machine, a daemon)        CLOUD

Most of these surfaces are brand-new and research preview or experimental. Treat exact flags as moving targets and confirm against /help and the live docs for your installed version.

Watch out

Research preview — verify against your version

Agent view, /goal, and routines are research preview; the Monitor tool is recent (v2.1.98+). Commands, flags, and caps change week to week. Everything below reflects Claude Code v2.1.x in 2026 — always run /help and read the official docs for the version you actually have installed.

Agent view — the supervision screen for background sessions

Open it with claude agents (research preview, v2.1.139+). It takes over the terminal and lists every background session — across all your projects — grouped into three buckets: Needs input, Working, and Completed, with pinned sessions and the ones that need you floated to the top. Narrow to one project with --cwd <path> (v2.1.141+); other launch flags include --model, --permission-mode, and --agent.

Navigation is keyboard-driven:

KeyAction
/ Move between rows (peek at adjacent sessions)
SpacePeek at the selected session without attaching
Enter / Attach — the session takes over the terminal as a full interactive Claude Code conversation
Ctrl+TPin the selected session (floats it to the top and keeps its process alive while idle)
Ctrl+XDelete the selected session
Ctrl+SSwitch grouping between state and directory

You dispatch new work two ways. From the dispatch input at the bottom of agent view, type a prompt and press Enter (each prompt starts its own new session — it's not a follow-up). Or from your shell:

bash
# dispatch a background Claude session
claude --bg "investigate the flaky SettingsChangeDetector test"

# name it, or run a specific subagent as the session's main agent
claude --bg --name "flaky-test-fix" "..."
claude --agent code-reviewer --bg "address review comments on PR 1234"

To run a shell command as a background PTY job instead of a Claude session, type ! <command> in the agent-view input, or from the shell use claude --bg --exec '<command>':

bash
claude --bg --exec 'pytest -x'

Manage sessions from your shell with: claude attach <id> (open in this terminal), claude logs <id> (read output), claude stop <id>, claude respawn <id> (--all), and claude rm <id>. Session IDs live under ~/.claude/jobs/. One gotcha: you can't open agent view while in-flight background tasks exist in your current session — check /tasks first.

Tip

Pin the sessions you care about

Unpinned idle sessions are stopped by the supervisor after about an hour. Press Ctrl+T to pin the long-runner you don't want reaped, and it floats to the top of agent view and stays alive. Captured output from a --exec shell job stays in memory only and is cleaned up about five minutes after the command exits — attach or claude logs it before then.

Underneath: worktree isolation and the supervisor daemon

Two pieces of machinery make background work safe and durable on your machine.

Worktree isolation. A background session starts in your working directory, but before its first file edit Claude moves it into an isolated git worktree under .claude/worktrees/. Parallel sessions can all read the same checkout, but each writes to its own worktree — so two background agents never clobber each other's edits. The move is skipped if you're not in a git repo, if you're already in a worktree, or if the write lands outside the cwd. Disable it entirely with worktree.bgIsolation: 'none' (v2.1.143+). Note: claude rm keeps a worktree that has uncommitted changes (and deleting from agent view removes the worktree including uncommitted changes — commit or push first).

The supervisor (daemon). Background sessions don't live in your terminal — a per-user supervisor process hosts them, separate from any terminal window. That's why a session keeps running after you close the tab. Key lifecycle facts:

  • Unpinned idle sessions stop after ~1 hour (pin with Ctrl+T to keep them).
  • On a binary update, the supervisor restarts pinned sessions automatically.
  • Session state persists on disk through auto-updates, supervisor restarts, and machine sleep.

When things stall, two commands diagnose and recover:

bash
claude daemon status                          # diagnose the supervisor
claude daemon stop --any --keep-workers       # restart the daemon, preserve sessions

--keep-workers is the important flag: it bounces the supervisor without killing the sessions it's hosting, which is how you clear a stuck daemon without losing in-progress work.

Key insight

Isolation is why you can fan out safely

The same git-worktree mechanism that /batch uses for parallel subagents protects background sessions too: edits are confined to a per-session worktree under .claude/worktrees/. That's what makes it reasonable to have several background agents editing the same repo at once — they read one checkout, write separate worktrees, and you merge deliberately.

/goal — goal-driven autonomy across turns

/goal <condition> (v2.1.139+) tells Claude to keep working across turns until a condition is met, instead of stopping when work merely looks done. For example:

text
/goal all tests in test/auth pass and lint is clean
/goal the build is green, or stop after 20 turns

It supports turn or time bounds ("…or stop after 20 turns"). /goal with no argument shows the current goal; /goal clear removes it. A goal is not session-scoped in the /loop sense — it's context-driven and resumes on --resume if still active.

The crucial detail is how the condition is evaluated. After each turn, a small fast model (typically Haiku) checks whether the goal is satisfied — but it evaluates from the transcript only. It cannot run shell commands or read files independently. So the condition must be provable from Claude's own output.

That reframes how you write goals. "All tests pass" is only checkable if Claude actually ran the tests and the passing output is in the transcript. A goal like "the code is correct" or "no bugs remain" is unverifiable — the evaluator has no way to confirm it from text. Make the success signal something Claude prints.

Example

Provable vs unprovable conditions

Provable: /goal the output of "npm test" shows 0 failures — Claude runs the command, the result is in the transcript, the evaluator reads it. Unprovable: /goal the refactor is clean and idiomatic — there's no transcript signal a fast model can verify, so the loop never reliably terminates. Always anchor a goal to a concrete artifact Claude emits (test output, a lint summary, a successful build line).

/loop — session-scoped scheduling, self-paced or cron

/loop [interval] [prompt] runs a prompt or slash command on a recurring schedule within the current session (alias /proactive). Both arguments are optional, and that's where the flexibility lives:

  • Interval can be a bare token (30m, 5s, 2h, 7d) or a phrase ("every 2 hours"); seconds are rounded to the nearest minute. Omit the interval and the loop is self-paced — Claude picks delays between 1 minute and 1 hour, and can delegate to the Monitor tool for event-driven reactions instead of fixed polling.
  • Omit the prompt and /loop runs a built-in maintenance prompt, or your custom .claude/loop.md (project, takes precedence) / ~/.claude/loop.md (user) — plain Markdown, 25KB max, edits apply on the next iteration.
text
/loop 5m /babysit-prs          # run a slash command every 5 minutes
/loop every 2 hours check CI and summarize failures
/loop                          # self-paced; uses built-in or .claude/loop.md

Scope and limits: session-scoped; recurring tasks have a 7-day expiry; max 50 concurrent scheduled tasks per session; press Esc to stop while it's waiting. Loops are restored on --resume/--continue only if a recurring task is under 7 days old (or a one-shot's time hasn't passed) — background Bash and Monitor tasks are never restored.

Under the hood /loop uses the scheduler tools CronCreate(cron_expression, prompt, recurring), CronList(), and CronDelete(task_id). The cron expression is a standard 5-field form (minute, hour, day-of-month, month, day-of-week) supporting *, ranges (1-5), steps (*/15), and lists (1,15,30). There is no extended syntaxL, W, ?, and MON/JAN aliases are not supported. When both day-of-month and day-of-week are constrained, either matches (vixie-cron semantics). A jitter offset means recurring tasks can fire up to 30 minutes late (or half the interval if under 1h) and one-shots up to 90s early — use non-round minutes to dodge it. Disable the scheduler entirely with CLAUDE_CODE_DISABLE_CRON=1.

Watch out

/loop dies with the session; jitter is real

/loop is session-scoped — it stops when you exit Claude Code (and Monitor/background-Bash tasks never come back on resume). If you need a schedule that survives your laptop closing, that's a cloud routine, not a loop. Also: don't rely on exact firing times. Jitter can push a recurring task up to 30 minutes late; a cron of 0 * * * * may not fire exactly on the hour.

Routines (durable cloud) plus event-driven reactions

When the work must outlive your session, use routines — created with /schedule [description] (alias /routines; subcommands list | update | run). A conversational setup captures the prompt, repos, environment, triggers, connectors, and permissions, and the routine runs on Anthropic's cloud. Edit them on the web at claude.ai/code/routines.

Routines have a minimum interval of 1 hour and support three trigger types:

TriggerHow it fires
ScheduleRecurring (hourly or longer) or a one-off at a timestamp
APIPOST https://api.anthropic.com/v1/claude_code/routines/{routine_id}/fire with Authorization: Bearer {token} and beta header experimental-cc-routine-2026-04-01 (optional text body for context; returns a new session ID + URL)
GitHubReact to PR / Release events, with filters (author, title, labels, draft, etc.)

Routines run autonomously — no permission prompts. Their reach is bounded by the configured repos, branch-push settings (branches are prefixed claude/ by default), environment network access, and connectors. There's a daily run cap per account; one-off runs are exempt from the cap but still consume usage. On Bedrock/Vertex/Foundry, /schedule is unavailable, and bare /loop with no prompt falls back to a fixed 10-minute schedule with no self-pacing.

For event-driven reactions you don't need a polling loop at all. The Monitor tool (v2.1.98+) streams a background process's output line-by-line into the conversation so Claude reacts the instant something appears — tail a log, watch CI, observe a directory. It uses Bash permissions (and respects Bash deny rules) but is not available on Bedrock/Vertex/Foundry, nor with telemetry disabled. The PushNotification tool sends a desktop/phone alert at a milestone (phone via Remote Control). List and stop background Bash + Monitor streams with /tasks (alias /bashes).

Tip

Three flavors of 'scheduled' — don't conflate them

/loop = session-scoped, dies with the session, supports sub-hour cron. Routines (/schedule) = durable cloud, min 1-hour interval, three triggers, no prompts. Desktop scheduled tasks are a separate Claude Desktop feature again. If someone says "schedule a task," pin down whether they mean local-and-temporary or cloud-and-durable before you reach for a command.

Try it: Run work while you're away — and supervise it

Practice the unattended-work surfaces in a throwaway git repo. (Several are research preview — if a command differs on your version, check /help and adapt.)

  1. Dispatch and supervise. From your shell, run claude --bg "map every TODO comment in this repo and summarize them", then open claude agents. Find the session under Working, press Space to peek, then Enter to attach and read its result. Press Ctrl+T to pin a session and note that it floats to the top.
  2. Run a shell job in the background. In the agent-view input type ! npm test (or use claude --bg --exec 'npm test'). Attach or claude logs <id> to read its output before it auto-cleans (~5 min after exit).
  3. Inspect isolation. After a background session makes an edit, look for a new directory under .claude/worktrees/. Confirm the edit landed there, not in your main checkout.
  4. Write a provable goal. Introduce a failing test, then set /goal the output of "npm test" shows 0 failures, or stop after 15 turns. Watch Claude work toward it. Then contrast with an unprovable goal like /goal the code is clean and explain (in a sentence) why the transcript-only evaluator can't reliably satisfy it. Clear with /goal clear.
  5. Schedule session-scoped work. Run /loop 7m /tasks (or a self-paced bare /loop) and observe it fire. Stop it with Esc. Note in one line why this wouldn't survive closing Claude Code.
  6. (Optional) Durability vs session-scope. If you have routines available, sketch (don't necessarily create) a /schedule routine with a GitHub PR trigger, and state which trigger type (Schedule / API / GitHub) you'd use to fire it from a CI job — and the endpoint shape (POST .../routines/{id}/fire).

Deliverable: a short note that (a) classifies each task above as session-scoped vs durable and local vs cloud, and (b) gives one example of a /goal condition that is provable from the transcript and one that is not, with the reason.

Key takeaways

  1. 1Two axes organize unattended work: session-scoped (/goal, /loop, Monitor — die with the session) vs durable (cloud routines), and local (agent view, a per-user supervisor) vs cloud.
  2. 2Agent view (`claude agents`, research preview) groups background sessions into Needs input / Working / Completed; ↑/↓ navigate, Space peek, Enter attach, Ctrl+T pin, Ctrl+X delete; dispatch with `claude --bg "prompt"` or a PTY job via `claude --bg --exec` / `! cmd`; manage with claude attach/logs/stop/respawn/rm.
  3. 3Background sessions move into a git worktree under `.claude/worktrees/` before the first edit (disable with `worktree.bgIsolation:'none'`), and a per-user supervisor hosts them — unpinned idle sessions stop after ~1h; `claude daemon stop --any --keep-workers` recovers a stall without losing sessions.
  4. 4/goal <condition> pursues a goal across turns, but a fast model (Haiku) evaluates from the TRANSCRIPT only — it can't run shell or read files, so the condition must be provable from Claude's own output (anchor it to test/lint/build output Claude prints).
  5. 5/loop [interval] [prompt] is session-scoped (7-day expiry, max 50, Esc to stop): omit the interval for self-pacing, omit the prompt for built-in maintenance or .claude/loop.md; uses 5-field cron (no L/W/?/aliases) with jitter, via CronCreate/List/Delete.
  6. 6Durable cloud routines (/schedule, min 1h) fire on Schedule, API (POST /routines/{id}/fire with Bearer + beta header), or GitHub triggers and run with no prompts; for event-driven reactions the Monitor tool streams a process's output so Claude reacts without a polling loop.

Quiz

Lock in what you learned

Check your understanding

0 / 4 answered

1.You set `/goal all unit tests pass` and Claude loops indefinitely, never declaring success even after the suite is green. What's the most likely cause?

2.A teammate wants a task that keeps running on a schedule even after they close their laptop overnight, reacting to new GitHub PRs. Which surface fits — and why not the alternative?

3.In agent view, you dispatch several `claude --bg` sessions that edit the same repository in parallel. Why don't their edits collide?

4.You want Claude to react the instant a line matching 'FAILED' appears in a long-running test process, without burning turns on repeated polling. Which tool is designed for this?

Go deeper

Hand-picked sources to keep learning