# Autonomous

> Autonomous mode — Claude keeps working on a stated goal for hours with no user input, driven by a Stop-hook loop with time/cycle budgets, a progress journal, and a kill switch. Use when the user runs /autonomous, or asks Claude to keep working unattended / "run while I'm gone" / work on something for hours.

- Skill: `emran05/autonomous` (Agent Skill)
- Install (CLI): `npx skillmds@latest add emran05/autonomous`
- Raw SKILL.md: https://api.skillmd.com/api/skills/emran05/autonomous/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Emran05 (https://skillmd.com/u/emran05)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/emran05/autonomous

---


# Autonomous mode

Autonomous mode keeps THIS session working toward a goal without user input. The
mechanism: a Stop hook (`~/.claude/autonomous/stop-hook.sh`) intercepts every
attempt to end a turn while a mission is active and injects a continuation
prompt. You do not need to loop, schedule, or poll — **just work normally and
end your turn; the hook brings you back** until the goal is done, the budget
runs out, or the user stops it.

State lives in `~/.claude/autonomous/`:
- `mission.json` — goal, status, budgets, cycle counter (managed by `autonomousctl`)
- `mission.log` — append-only progress journal; your durable memory across compaction
- `KILL` — if this file exists, the mission ends at the next turn boundary

Manage everything through `~/.claude/autonomous/autonomousctl`.

## Subcommand handling

`/autonomous <goal text>` or `/autonomous start <goal>` → start a mission (below).
`/autonomous status` → run `~/.claude/autonomous/autonomousctl status` and report.
`/autonomous stop` → run `autonomousctl stop "user requested"`, report final state from the archived log.
`/autonomous pause` / `resume` → run the matching subcommand and confirm.
`/autonomous note <text>` → run `autonomousctl note "<text>"` — appends a USER NOTE
to the journal that the working session treats as a binding instruction at its
next cycle. This is how the user steers a running mission without stopping it.

## Starting a mission

1. **Restate the goal concretely.** Expand the user's phrasing into a specific,
   completable goal with an explicit definition of done (e.g. "All endpoints in
   api/ have tests and they pass", not "improve the project"). If the user gave
   a time budget ("run for 4 hours"), use `--hours`; otherwise default 8h.
2. Start it, binding to the current project directory:
   ```bash
   ~/.claude/autonomous/autonomousctl start "<concrete goal + definition of done>" --hours 8 --dir "$(pwd)"
   ```
3. Seed 3–8 ordered milestones — these drive the per-cycle focus, the
   statusline progress bar, and `status` output:
   ```bash
   ~/.claude/autonomous/autonomousctl milestone add "<milestone 1>"
   ~/.claude/autonomous/autonomousctl milestone add "<milestone 2>"   # ...
   ```
   As each milestone is verified complete during the mission, mark it:
   `autonomousctl milestone done <n>`. The hook prompt always names the
   CURRENT milestone; work toward that one only.
4. Tell the user, briefly: the goal as you understood it, the budget, and how to
   stop it (`autonomousctl stop`, `touch ~/.claude/autonomous/KILL`, or `/autonomous stop`).
   If the session is running in `default` permission mode, warn them that
   permission prompts will stall an unattended run — they should restart with
   `claude --permission-mode acceptEdits` (or pre-approve the needed tools) and
   that on a laptop they should prevent sleep with `caffeinate -dims &`.
5. Start the first task immediately. When you end the turn, the hook takes over.

## Working a cycle (what to do each time the hook re-prompts you)

The hook's injected prompt is the authority; in short:
- `tail -n 30 ~/.claude/autonomous/mission.log` to recover state — treat the
  journal as ground truth, not your memory (context may have been compacted).
  USER NOTE entries are binding instructions from the user; obey the newest.
- Do ONE meaningful unit of work per cycle. Finish and verify before logging.
- Log every cycle: what you did, how you verified it, what's next. Future-you
  reads only this.
- Commit verified work if the project is a git repo. Never push unless the goal says to.
- Stay inside the mission's project directory.

## Context pressure and compaction

The hook measures context usage from the transcript each cycle and shows it in
the injected prompt. Compaction cannot be forced, so the system makes it
lossless instead:
- **≥60% full, at a task-chain/milestone boundary** → append a HANDOFF entry now,
  while it's cheap:
  `HANDOFF: done=<verified> | wip=<half-done + exact next step> | next=<queue> | files=<key paths> | learn=<gotchas/decisions>`
- **≥75% full** → write the HANDOFF entry FIRST, before any new work, then
  prefer small self-contained tasks.
- When auto-compaction fires, a PreCompact hook stamps the journal and a
  SessionStart(compact) hook re-injects the goal, journal tail, and USER NOTEs
  into the fresh context — recovery is automatic; just resume from the HANDOFF.
- **Session recycling (better than compaction, needs the user-run watchdog):**
  if the hook prompt says the recycle watchdog is running, then at high context
  write the HANDOFF entry and run `autonomousctl handoff`, then end the turn.
  The watchdog spawns a fresh `claude -p` generation that resumes from the
  journal with a clean context. Never run `handoff` when the watchdog isn't
  running — the hook prompt only suggests it when it is.

## Safety rails (enforced by the hook, not by you)

- Budgets (hours/cycles) end the mission mechanically.
- Plateau auto-pause: if git HEAD and the journal both stay unchanged for 4
  consecutive cycles, the hook pauses the mission and notifies the user —
  logging real progress every cycle is what keeps the mission alive.

## Ending

- Goal fully complete and verified → `~/.claude/autonomous/autonomousctl done "<summary>"`,
  then write the user a completion summary (what was built, how it was verified,
  where the log/archive is) and stop.
- Blocked on a genuine user decision → `~/.claude/autonomous/autonomousctl pause "<question>"`,
  leave the question as your final message, and stop.
- Budget exhaustion is handled by the hook (mission expires; you simply stop).
  The user can resume later — a resumed mission binds to the next session that
  ends a turn while working inside the mission's project directory, so resume
  from the session that should continue the work.

Always invoke `autonomousctl` by its full path `~/.claude/autonomous/autonomousctl`
(a PATH symlink exists for the user's terminals, but not necessarily for yours).

