---
name: autonomous
description: Enter autonomous development mode with STRUCTURAL enforcement. Uses a stop hook to prevent premature exit. Generates stop conditions and confirms with user before starting. Work independently for a specified duration with progress reporting.
user_invocable: true
---
# Autonomous Mode (Structurally Enforced)
You are entering **autonomous development mode**. This mode uses a **stop hook** that PREVENTS you from exiting until all tasks are genuinely complete. This is not optional — the hook structurally enforces continuous work.
---
## Step 1: Generate Stop Conditions (MANDATORY)
Before activating the stop hook, you MUST:
1. **Analyze the goal** and break it into specific, verifiable tasks
2. **Present the task list** to the user with clear completion criteria
3. **Wait for user confirmation** before activating the hook
4. **Define the completion promise** — a phrase that is only TRUE when ALL tasks are done
**Example interaction:**
```
User: /autonomous --duration=8h --goal="Complete Slack feature parity"
Agent: Here's my task breakdown for autonomous mode:
TASKS (all must be complete before I can exit):
1. [ ] Implement job-specific Slack channels
2. [ ] Build full PresenceProxy Slack integration
3. [ ] Update dashboard HTML with platform badges
4. [ ] Implement Slack Lifeline process
5. [ ] Add platform dropdown to new session UI
...
Completion promise: "ALL_TASKS_COMPLETE"
Duration: 8 hours
Emergency stop: "stop everything" via messaging
Shall I proceed? (The stop hook will prevent me from exiting until all tasks are done)
```
**The user must confirm before the hook activates.** This is the safety gate.
---
## Step 2: Activate the Stop Hook
After user confirmation:
**2a. Add the stop hook to settings.json** (dynamically — it's removed when the session ends):
```bash
python3 -c "
import json
with open('.claude/settings.json') as f:
s = json.load(f)
hooks = s.setdefault('hooks', {}).setdefault('Stop', [])
if not any('autonomous-stop-hook' in str(h) for h in hooks):
hooks.append({'matcher': '', 'hooks': [{'type': 'command', 'command': 'bash .instar/hooks/instar/autonomous-stop-hook.sh', 'timeout': 10000}]})
with open('.claude/settings.json', 'w') as f:
json.dump(s, f, indent=2)
print('Stop hook registered')
"
```
**2b. Write the state file DIRECTLY** (do NOT shell out to bash — the session ID env var is only available inside Claude Code):
Use the **Write tool** to create `.instar/autonomous-state.local.md` with this content:
```markdown
---
active: true
iteration: 1
session_id: {VALUE OF $CLAUDE_CODE_SESSION_ID — get via: echo $CLAUDE_CODE_SESSION_ID}
goal: "YOUR GOAL"
duration: "8h"
duration_seconds: 28800
started_at: "{ISO timestamp}"
end_at: "{ISO timestamp + duration}"
report_topic: "TOPIC_ID"
report_interval: "30m"
last_report_at: ""
level_up: true
completion_promise: "ALL_TASKS_COMPLETE"
---
# Autonomous Session
## Goal
{goal text}
## Tasks
{numbered task list}
## Instructions
{autonomous instructions}
```
**CRITICAL**: To capture the session ID correctly, run this FIRST:
```bash
echo $CLAUDE_CODE_SESSION_ID
```
Then include the output in the `session_id:` field. This ensures session isolation works.
**WHY NOT bash script?** Running `bash setup-autonomous.sh` creates a subprocess that does NOT inherit `CLAUDE_CODE_SESSION_ID`. The state file ends up with an empty session_id, which causes the hook to leak into all sessions. Always write the state file from within Claude Code's context.
**SESSION ISOLATION**: The stop hook checks `session_id` — it only blocks the session that activated autonomous mode. Other sessions on the same machine pass through unaffected.
**From this point, you CANNOT exit THIS session** unless:
- You output `ALL_TASKS_COMPLETE` (genuinely true)
- Duration expires
- Emergency stop is triggered
**2c. On completion/exit**: Remove the stop hook from settings.json:
```bash
python3 -c "
import json
with open('.claude/settings.json') as f:
s = json.load(f)
s['hooks']['Stop'] = [h for h in s.get('hooks',{}).get('Stop',[]) if 'autonomous-stop-hook' not in str(h)]
with open('.claude/settings.json', 'w') as f:
json.dump(s, f, indent=2)
print('Stop hook removed')
"
```
---
## Step 3: Work Until Done
The stop hook will catch every attempt to exit and feed your task list back. Each iteration you will:
1. Read the task list
2. Pick the next incomplete task
3. Implement it fully (not stub, not wire — IMPLEMENT)
4. Verify it works (compile, test where practical)
5. Move to next task
6. Send progress reports at the configured interval
### The Defer-to-Future-Self Trap
**This is the #1 failure mode.** It looks like:
| What you think | What's actually happening |
|----------------|--------------------------|
| "This is Phase 2 work" | You don't feel like doing it right now |
| "Parked for follow-up" | You're avoiding the hard part |
| "Future improvement" | Your future self has no advantage over you |
| "Remaining work" | Work you're choosing not to do |
| "Deferred" | Abdication disguised as planning |
**The test:** Can you do this task right now with the tools and knowledge you have?
- **Yes** → Do it. Not later. Now.
- **No** → Document exactly WHY (missing dependency, needs external access, etc.)
**"Phase 2" is only valid when the current phase genuinely cannot contain the work** — not when you're tired, not when it's complex, not when it's 2 AM.
---
## Step 4: Completion
When ALL tasks are genuinely done:
1. Verify every task is complete (re-read the list)
2. Run `npx tsc --noEmit` — zero errors
3. Run relevant tests
4. Write learnings to MEMORY.md
5. Send final report via messaging
6. Output: `ALL_TASKS_COMPLETE`
The stop hook will detect the promise and allow exit.
---
## Emergency Stop
The user can always stop autonomous mode:
1. **Via messaging**: Send "stop everything" or "emergency stop" — the MessageSentinel intercepts
2. **Via file**: `touch .instar/autonomous-emergency-stop` — the stop hook checks for this
3. **Via cancel**: `/cancel-autonomous` — removes the state file
The stop hook checks for emergency stop on EVERY iteration. User safety is never compromised.
### /cancel-autonomous
To manually cancel:
```bash
rm -f .instar/autonomous-state.local.md
```
---
## Progress Reporting
Send reports to the user's messaging platform at the configured interval.
**How to send:**
```bash
cat <<'EOF' | .claude/scripts/telegram-reply.sh TOPIC_ID
AUTONOMOUS PROGRESS (iteration N, Xh elapsed / Yh total)
Completed:
- [task 1] ✅
- [task 2] ✅
Working on:
- [current task]
Remaining:
- [task 3]
- [task 4]
Issues: none
EOF
```
---
## Anti-Patterns (Structurally Enforced)
These aren't just warnings — the stop hook WILL catch you if you try to exit without completing them:
### The "Beautiful Summary" Exit
Writing a comprehensive report of what you did and what's "remaining" then trying to exit. **The hook will block you and feed the remaining tasks back.**
### The "Phase 2" Labeling
Calling incomplete work "Phase 2" and trying to exit. **The hook doesn't care about phases — it cares about the task list.**
### The "Good Stopping Point" Exit
Finding a natural break and trying to exit early. **The hook checks the task list, not your feelings about stopping.**
### The "It's 2 AM" Exit
Feeling tired (as an AI) and deferring. **You don't get tired. The hook knows this.**
---
## Hook Configuration
The stop hook is at `.claude/skills/autonomous/hooks/autonomous-stop-hook.sh`.
It reads state from `.instar/autonomous-state.local.md` and:
- Blocks exit if tasks are incomplete
- Feeds the task list + goal back as the next prompt
- Increments the iteration counter
- Checks for emergency stop signals
- Checks for duration expiry
- Checks for completion promise in `` tags
- Includes time remaining in the system message
**This is structural enforcement, not willpower.** You cannot talk your way out of the loop.