Skip to content

Autonomous Patterns

REACH in autonomous mode operates without a human in the loop for the routine work. Claude authors the orchestration logic, schedules it via Windows Task Scheduler, and the system wakes, reaches, records, signals, and sleeps — on its own cadence.

Human judgment isn't eliminated. It's reserved for the moments that warrant it.


The Core Autonomous Loop

Wake (Task Scheduler trigger)

Check state — what needs attention?

Reach into sources (Outlook, DB, git, web)

Act (send, record, launch, signal)

Write state — what did I do?

Log — structured, reconstructable

Sleep (process exits, scheduler owns the next wake)

Every autonomous reach follows this shape. The discipline is in the state and log layers — without them, unattended runs are a black box.


Scheduling — Windows Task Scheduler

No daemon. No always-on process. Task Scheduler wakes the reach, it runs, it exits. Energy efficient, no memory leak risk, no zombie processes.

powershell
$action = New-ScheduledTaskAction -Execute "dotnet" `
    -Argument "run C:\reach\outlook-check.cs" `
    -WorkingDirectory "C:\reach"

$trigger = New-ScheduledTaskTrigger -Daily -At "8:00AM"

Register-ScheduledTask -TaskName "REACH-OutlookCheck" `
    -Action $action -Trigger $trigger -RunLevel Highest

Available triggers:

  • Daily / weekly at fixed time
  • On system startup
  • On user login
  • On file system event (via wrapper)
  • On network availability
  • Chained — one task signals the next

State Management

Each reach starts fresh. Autonomous runs need explicit state or they repeat work, miss things, or lose track of where they left off.

csharp
var statePath = @"C:\reach\state\outlook-check.json";

var state = File.Exists(statePath)
    ? JsonSerializer.Deserialize<CheckState>(File.ReadAllText(statePath))
    : new CheckState { LastProcessedId = null, LastRunAt = DateTime.MinValue };

// ... do work using state.LastProcessedId to skip already-seen items ...

// Write updated state
File.WriteAllText(statePath, JsonSerializer.Serialize(new CheckState
{
    LastProcessedId = latestId,
    LastRunAt = DateTime.UtcNow
}));

State files are flat JSON. Human readable. Git trackable. The reach owns them — nothing else writes to them.


Signal Files — Inter-Reach Communication

Signal files coordinate independent reaches without a message broker. One reach writes a signal; another reads it and acts.

C:\reach\signals\
  urgent.signal          ← outlook-check wrote this
  build-failed.signal    ← ci-monitor wrote this
  file-arrived.signal    ← file-watcher wrote this

Writing a signal:

reach process.signal "urgent"
  payload   subject from "email"
  output    log

Reading and consuming a signal:

reach file.watch "C:\reach\signals"
  on new    signal "urgent"
  then      prompt.confirm
    title   "Urgent item flagged — review now?"
    on yes  reach outlook.inbox where flagged true

Failure Handling

Autonomous reaches fail silently by default — no one is watching. The log layer is the safety net.

Dead letter pattern — failed items written to a dead-letter folder for manual review:

C:\reach\dead-letter\
  2026-06-17-0847-timesheet-failed.json
  2026-06-16-1200-signal-unhandled.json

Retry pattern — state file tracks retry count:

csharp
if (state.RetryCount >= 3)
{
    // Write to dead-letter, skip this item
    File.WriteAllText($@"C:\reach\dead-letter\{itemId}.json",
        JsonSerializer.Serialize(new { item, error, state.RetryCount }));
}

Anomaly detection — OCTO Health Layer reads run history and surfaces patterns: arm failed 2+ consecutive runs, process didn't wake at scheduled time, empty result where data was expected. See Health Layer →.


Autonomous OCTO — Morning Brief

The morning brief is OCTO running autonomously at 8:45am. No human initiates it. The Task Scheduler wakes it, the arms reach, the surface appears on the screen, and it waits for the human.

# morning.octo

name    morning-brief
arms
  - outlook.inbox     since yesterday   analyze urgent
  - teams.planner     status overdue
  - teams.transcript  latest            summarize
  - git.commits       since yesterday   analyze cadence

surface
  title   "Good morning. Here's what needs you."
  show    urgent-items
  actions
    draft-reply   →  reach outlook.draft from selected
    send-summary  →  reach outlook.draft to team summarize all
    snooze        →  reach teams.planner snooze selected

close
  tone  warm
  joke  true

Scheduled via Task Scheduler. Runs daily at 8:45. Arms reach, surface appears, human decides, OCTO closes. Process exits until tomorrow.


Multi-Reach Coordination

Multiple autonomous reaches coordinating through signals and state:

8:00  outlook-check.reach    → reads inbox, writes urgent.signal if needed
8:45  morning.octo           → reads combined signal, surfaces brief
12:00 midday-check.reach     → reads schedule changes, cancellations
17:00 timesheet-draft.reach  → reconstructs day from git + calendar
17:00 daily-report.octo      → reads run history, surfaces daily report

Each reach is independent. They coordinate through the signals folder and shared state files. No message queue. No broker. No infrastructure.


Design Principles for Autonomous REACH

State is explicit — the reach owns its state file. Nothing else writes to it. If the state file is missing, start fresh — don't guess.

Log everything you do — autonomous runs have no observer. The log is the only way to reconstruct what happened.

Dead-letter failed items — never silently discard failures. Write them somewhere a human can find and review them.

Signals, not direct calls — reaches coordinate through signal files, not direct invocation. Loose coupling. A signal can be consumed by whichever reach picks it up next.

Bounded token consumption — each autonomous run consumes tokens for its task and exits. No continuous burn. The cost is per run, not per hour.

The human is still there — autonomous doesn't mean unattended forever. The morning brief surfaces every day. The daily report closes every evening. The human is in the loop at the cadence the practice is designed for — not at every step, but at the right moments.