Skip to main content
Module 2: Multi-Agent 5 / 6
Intermediate Session 11 Autonomous Auto-claim

Autonomous Agents

Build agents with WORK/IDLE phases and auto-claim capabilities for independent operation.

March 20, 2026 18 min read

What You’ll Learn

Most AI interactions are conversational: the human types, the AI responds, repeat. Autonomous agents break this pattern. They operate in continuous loops — checking for work, claiming tasks, executing, reporting results, and checking again — all without human intervention.

By the end, you’ll understand:

  • What makes an agent autonomous vs. interactive
  • The WORK/IDLE phase cycle
  • Auto-claim: picking up tasks from shared queues
  • The heartbeat pattern for liveness monitoring
  • Safety constraints that keep autonomous agents under control

The Problem

Interactive agents have a bottleneck: the human. Every time the agent finishes, it waits for the next instruction.

SCENARIO 1: Test Watcher
  Developer changes code → tests need to run
  But developer is writing more code → tests sit unexecuted

SCENARIO 2: Code Review Pipeline
  3 PRs need review. Agent finishes PR #1, then stops.
  PRs #2 and #3 wait for human to say "now do the next one"

SCENARIO 3: Multi-Feature Sprint
  5 independent features. Sequential assignment wastes time:
    Assign #1 → wait → done → assign #2 → wait → done → ...
  Could be: define all 5 → agents work in parallel → all done

The core problem: manual task assignment creates artificial bottlenecks. If tasks are well-defined and independent, agents should pick them up automatically.

How It Works

Interactive vs. Autonomous

INTERACTIVE                          AUTONOMOUS
  Human: "Fix the login bug"           Agent: [check queue] → task found
  Agent: [works] → "Done."            Agent: [claim] → [work] → [report]
  Human: "Now add error messages"      Agent: [check queue] → task found
  Agent: [works] → "Done."            Agent: [claim] → [work] → [report]
  Human: "Run the tests"              Agent: [check queue] → empty
  Agent: [works] → "All passing."     Agent: [idle] → [wait] → [check]
  ↑ Stops after each task              ↑ Loops until queue is empty

The WORK/IDLE Phase Cycle

Every autonomous agent alternates between two phases:

              ┌──────────────────────────────────┐
              │                                  │
              ▼                                  │
        ┌───────────┐    no tasks available      │
        │   IDLE    │◀──────────────────┐        │
        └─────┬─────┘                   │        │
              │ check task queue        │        │
              ▼                         │        │
        ┌───────────┐   nothing found   │        │
        │   CHECK   │──────────────────▶│        │
        └─────┬─────┘                            │
              │ task found → claim it            │
              ▼                                  │
        ┌───────────┐                            │
        │   WORK    │  execute task               │
        └─────┬─────┘                            │
              │ complete → report result          │
              └──────────────────────────────────┘

In IDLE, the agent waits a configurable interval before re-checking. In WORK, the agent has full authority over its claimed task — reading files, writing code, running commands.

Auto-Claim: From Queue to Execution

Auto-claim is how an autonomous agent picks up unassigned tasks:

SHARED TASK QUEUE
┌─────────────────────────────────────────────┐
│  [task-1] status: done       assignee: A    │
│  [task-2] status: done       assignee: B    │
│  [task-3] status: ready      assignee: —    │ ◀── Agent C claims this
│  [task-4] status: ready      assignee: —    │
│  [task-5] status: blocked    assignee: —    │
└─────────────────────────────────────────────┘

RULES:
  1. Only claim tasks with status "ready" (skip "blocked")
  2. Claim ONE task at a time (prevents hoarding)
  3. Set assignee atomically (prevents double-claim)
  4. Respect priority order (higher priority first)

The Heartbeat Pattern

When an agent works autonomously, how do you know it is still alive?

Agent C (autonomous)                    Monitor
    │                                      │
    │  ♥ { agent: "C", task: "task-3",     │
    ├─────  status: "working" }           ──▶ recorded: alive
    │        ... 30 seconds ...            │
    │  ♥ { agent: "C", task: "task-3",     │
    ├─────  progress: "60%" }             ──▶ recorded: alive
    │        ... 30 seconds ...            │
    │  (no heartbeat)                      │
    │                                    ──▶ 60s without heartbeat
    │                                      │ → agent presumed dead
    │                                      │ → unassign task-3
    │                                      │ → task returns to queue

Heartbeats provide liveness detection (crashed agents get their tasks reclaimed) and progress tracking (the orchestrator can monitor completion).

Daemon Mode

Some autonomous agents run indefinitely, watching for events rather than draining a queue:

DAEMON AGENT: Test Watcher
  WATCH: file system changes
  TRIGGER: *.ts file modified
  ACTION: run related tests, report pass/fail
  LOOP: forever (until explicit stop or session end)
  EXIT: stop signal, session end, or 3 consecutive fatal errors

Safety Constraints

Autonomous agents need guardrails. Autonomy is granted in degrees, not all-or-nothing:

┌─────────────────────────────────────────────────┐
│  1. SCOPE LIMITS                                 │
│     allowed_paths: ["src/", "tests/"]            │
│     max_files_modified: 10                       │
│                                                  │
│  2. APPROVAL GATES                               │
│     auto_approve: read, test, lint               │
│     require_review: write, delete                │
│     blocked: deploy, publish                     │
│                                                  │
│  3. KILL SWITCHES                                │
│     max_runtime: 300s per task                   │
│     max_iterations: 50                           │
│     error_threshold: 3 consecutive failures      │
│                                                  │
│  4. RESOURCE BUDGETS                             │
│     max_tokens_per_task: 100,000                 │
│     max_tool_calls: 200                          │
└─────────────────────────────────────────────────┘

An agent can be fully autonomous for safe operations (reading, testing) while requiring approval for destructive ones (deleting files, deploying).

Key Insight

Autonomous agents are the building block for CI/CD-like workflows within Claude Code. They bridge the gap between interactive coding and automated pipelines.

The key shift is mental: interactive agents treat the human as the scheduler (“what should I do next?”). Autonomous agents treat the human as the architect (“here is the queue, here are the constraints, now execute independently”).

This means quality depends on task definitions. A well-defined task with clear inputs, expected outputs, and success criteria can run autonomously. A vague task like “improve the codebase” cannot. Invest in task decomposition (Session 7) and protocols (Session 10) before enabling autonomous agents.

Hands-On Example

A test-runner agent operating autonomously:

SETUP: Define the agent
──────────────────────────────────────
Agent: "test-runner"
Mode: autonomous
Constraints:
  allowed_actions: [read_file, run_tests, report_result]
  denied_actions:  [write_file, delete_file]
  max_runtime: 120s per task
  heartbeat_interval: 30s

CYCLE 1: Claim and execute
──────────────────────────────────────
[CHECK]  Query queue → status: "ready", type: "test"
[CLAIM]  task-17: "Run integration tests for auth module"
[WORK]   Read tests/auth/ → run pnpm test tests/auth/
[REPORT] { passed: 12, failed: 1,
           failure: "tests/auth/refresh.test.ts:45" }
[♥]      Heartbeat sent at 30s mark

CYCLE 2: Next task
──────────────────────────────────────
[CHECK]  Query queue → task-22 found
[CLAIM]  "Run unit tests for payment module"
[WORK]   Read tests/payment/ → run pnpm test tests/payment/
[REPORT] { passed: 8, failed: 0 }

CYCLE 3: Queue empty
──────────────────────────────────────
[CHECK]  No tasks available
[IDLE]   Wait 10s → check again → still empty → wait...

Good vs. Bad Autonomous Agent Design

GOOD:                                BAD:
  Single responsibility                Multiple responsibilities
  Clear success criteria               "Make it better"
  Bounded execution time               "Keep going until perfect"
  Structured results                   Unstructured text output

  Example: Lint checker                Example: "Code improver"
    Input:  file path                    Input:  entire codebase
    Action: run linter                   Action: ??? (too broad)
    Output: { errors, warnings }         Output: "I made some changes"

Connection to Team Protocols

Autonomous agents use the same protocol messages from Session 10. The only difference is who initiates:

INTERACTIVE:  Human → "Review this PR" → Agent works → responds
AUTONOMOUS:   Agent → [checks queue] → [claims] → [works] → responds
              Same message format. Same request_id. Different trigger.

What Changed

Interactive AgentAutonomous Agent
Human assigns each taskAgent claims from queue
Stops after every taskLoops continuously
Human monitors progressHeartbeat signals liveness
All actions allowedSafety constraints per operation
Bottleneck: human response timeBottleneck: task queue depth

Next Session

Session 12 covers Worktree Isolation — how git worktrees give each agent its own working directory on its own branch, enabling true parallel development without merge conflicts.